news 2026/10/27 23:42:47

美赛C题Wordle预测:时间序列特征工程与可解释建模避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
美赛C题Wordle预测:时间序列特征工程与可解释建模避坑指南

简介:这份资源汇集了2023年美国大学生数学建模竞赛C题的完整备赛材料,面向准备参加美赛或各类数学建模竞赛的学生与指导教师。包内包含赛题分析、数据处理、模型构建与论文写作等多维度的参考内容,尤其适合需要快速了解C题建模思路、学习数据清洗与回归聚类方法,以及规范论文排版的读者。资源共208个文件,涵盖pdf论文与参考文献、xlsx数据表、docx建模笔记、png图表、txt代码说明、sav与csv统计文件等,压缩包总大小约59.42MB,类型丰富,便于按需查阅与二次学习。目前已有176人在线学习,具有一定的参考价值。透过这些资料,可系统梳理从数据预处理(如滑动窗口平滑、单词难度计算)到聚类分析(K-Means)、回归拟合及模型验证的完整流程,还能借鉴第三问模型、公式推导及Word文档写作的具体实现方式,为独立完成同类赛题提供有力支撑。

1. 2023年美国大学生数学建模竞赛C题:它到底在考什么,熬夜建模前先想清楚

2023年美国大学生数学建模竞赛C题给的不是复杂物理方程,也不是海量传感器数据,而是一张按天记录的Wordle游戏结果表。你要预测未来每天有多少人玩、多少人用Hard模式,还要解释为什么人数会波动。很多队拿到题就冲上去套时间序列模型,结果三天三夜全耗在调参上,最后评委一问“为什么选这个模型”就卡壳。这道题真正考的是两件事:把人类行为拆成可解释的特征,以及用对验证方式。适合想打美赛拿奖的本科生,也适合刚接触时序预测、想知道“预测人的行为”和“预测机器指标”差在哪的从业者。

2. 从赛题数据到第一份洞察:C题给的数据里,哪几个字段才是真正的信号

2.1 原始数据长什么样:先别建模,先做三次拆分

2023年C题的数据是Wordle在某个时间段内按天汇总的统计表。常见字段至少包括日期、局数编号、当日词汇、当日报告人数、Hard模式报告人数,以及结果分布类字段。以赛题实际提供的版本为准,但多数队伍都会按下面这套思路整理。

字段类型价值判断
Date日期时间序列的索引,必须转成datetime
Contest Number整数单调递增,适合做生命周期趋势项
Word文本可以挖难度特征,但通常不是主要变量
Number of Reports整数主预测目标之一
Number in Hard Mode整数主预测目标之二,常以占比形式使用

拿到表的第一件事不是画折线图,而是做三次拆分。第一,把日期拆到星期维度,看周内规律。Wordle是很多人通勤或摸鱼时玩的,周一和周五的人气往往明显不一样。第二,把局数编号拆成趋势项,看游戏生命周期。Wordle在数据覆盖期内整体热度是往下走的,但中间可能因为新闻事件出现尖峰。第三,把“骤升点”单独拉出来和新闻事件对照。这个动作的价值会在写论文的建模动机部分体现出来。

import pandas as pd df = pd.read_csv("wordle_results.csv", parse_dates=["Date"]) df["dow"] = df["Date"].dt.dayofweek # 周一=0,周日=6 df["trend"] = df["Contest Number"] # 局数编号作为趋势 df["weekend"] = (df["dow"] >= 5).astype(int) # 周末标记 print(df.groupby("dow")["Number of Reports"].mean())

这段代码做完,你会看到星期哑变量的均值差。如果周内差异超过百分之十,就说明星期效应不能忽略。trend列不要直接塞进模型后就完事,它的分布形状决定了你要用线性还是对数趋势。

2.2 预测目标不是“人数”而是“百分比误差”:先搞懂评价函数再决定策略

这道题的评价指标不是RMSE,而是平均绝对百分比误差MAPE。MAPE的计算方式是:对每一天,计算真实值与预测值之差的绝对值,除以真实值,再求平均、乘100%。这意味着同样相差100人,在玩家数3000的天里误差是3%,在玩家数300的天里误差是33%。所以模型必须优先保住“低人气日”的预测精度,而低人气日恰好容易出现在周末和节假日。

能不能用RMSE代替MAPE做训练?可以,但分数不会太好。RMSE对大误差敏感,会把力气花在修正几个尖峰日上;MAPE则惩罚的是“相对偏差”,更贴合赛题。因此常见做法是以log1p之后的目标做回归,让模型在指数尺度上缩小相对误差,再把预测结果做expm1还原。还有一个很实在的坑:如果真实值本身接近零,MAPE会瞬间变大,所以预测值必须被限制在一个正数下限以上。

import numpy as np from sklearn.metrics import mean_absolute_percentage_error y_true = np.array([12000, 8000, 3500, 900]) y_pred = np.array([11000, 8200, 3000, 700]) print(mean_absolute_percentage_error(y_true, y_pred)) def mape_clip(y_true, y_pred, floor=100): y_pred = np.maximum(y_pred, floor) return np.mean(np.abs(y_true - y_pred) / y_true) * 100

这里对预测值加了一个下限,避免把很冷清的一天预测成接近零。floor=100是一个经验值,你可以按数据量级调整。用这个函数做最终评估,比直接调用库函数更能反映赛题场景。

2.3 两个必须处理的数据缺口:缺失的日期和零报告

Wordle官方数据偶尔会出现某一天没有记录的情况。直接删掉会让时间序列不连续,滞后特征错位。零报告比缺失更隐蔽:不是没人玩,而是当天数据没入库。如果放任不管,模型会学到“某天突然归零”,导致滞后特征全部被污染。

处理时先区分“真零”和“假零”。真零在数据里几乎不存在,因为Wordle这种全民级游戏不会真的没人玩。遇到疑似零值,先看前后几天。前后都是正常量级,中间一个零,那八成是缺数。常见补法是用前一天和后一天的平均值,或者直接做线性插值。做插值要放在构造滞后特征之前,否则shift出来的窗口里全是脏数据。这个顺序性很强,见过有队伍先造特征再清洗,结果回填值被当成真实波动,模型直接翻车。

3. 先跑通一个能拿分的基线方案:线性回归把星期效应和生命周期放进同一张表

3.1 为什么不直接上Prophet、LSTM或XGBoost

美赛C题不是Kaggle排位赛,评委看的是“你有没有想清楚为什么这样做”。Prophet能跑,但它的趋势、节假日和季节项对评委来说是个黑匣子。LSTM更是吃力不讨好,几百行数据训练深度模型,方差大、可解释性差。XGBoost能拟合得很漂亮,但特征重要性一出来,评委追问“为什么这个特征排第一”时很难答。线性回归加手工特征的组合,是这道题性价比最高的开局:每个特征你都能解释来源,每个系数都能转成一句业务结论。

最朴素的一组特征就能拿到一个能看的基线:星期几哑变量、局数编号、滞后7天的平均报告人数。这三样分别对应人类行为中的周规律、生命周期、惯性。别贪多,先让这组特征跑通全流程。

3.2 最小特征集代码:构建特征、拟合、评价

import pandas as pd import numpy as np import statsmodels.api as sm df["log_reports"] = np.log1p(df["Number of Reports"]) # 滞后7天均值:只使用过去信息,不做未来泄漏 df["last7"] = ( df["Number of Reports"] .shift(1) .rolling(7, min_periods=1) .mean() ) # 星期哑变量 dow_dummies = pd.get_dummies(df["dow"], prefix="dow", drop_first=True).astype(int) X = pd.concat([ dow_dummies, df[["trend", "last7"]].reset_index(drop=True) ], axis=1) y = df["log_reports"] # 去掉头部有NaN的行 mask = X.notna().all(axis=1) & y.notna() X, y = X[mask], y[mask] X = sm.add_constant(X) model = sm.OLS(y, X).fit() print(model.summary())

shift(1)是为了使用“前一天”的信息,rolling(7, min_periods=1)计算的是过去7天的均值,min_periods=1保证早期数据也有值。关键点是mask过滤掉建立窗口时留下的空值,不然sm.OLS会直接报错。输出里的系数解释是:trend系数为负说明游戏热度随局数增加在衰减;last7系数接近1说明玩法有强烈惯性;某个星期哑变量为负说明那天人气低于基准日。

3.3 参数怎么设:趋势用“对数”而不是一根直线

很多队伍把局数编号直接当线性特征扔进模型,结果预测到后期变成负数人群,完全不可信。热度的衰减不会是一条直线到底,更像是对数衰减。用trend_log = np.log(contest_number)替代trend是最简单的修正。另外可以考虑在新闻事件前后加一个分段转折点,事件后的日期标1,事件前标0,这样模型能学到一个结构性变化。

df["trend_log"] = np.log(df["trend"]) df["post_news"] = (df["Date"] > "2022-02-01").astype(int)

日期节点要根据你使用的数据版本去选,这里只是一个示例。判断转折点的方法很简单:画一下序列图,找到斜率突变的日期,再结合公开新闻事件做对照。如果你选了多个事件节点,记得检查系数显著性和VIF,避免互相打架。

4. 从基线到能讲故事的模型:滞后特征、滚动验证和可解释性三板斧

4.1 加滞后特征像走钢丝:什么时候该加,什么时候就是数据泄漏

基线里的last7属于滞后特征的一种。它有用,因为用户行为有惯性;它有风险,因为未来预测时要递归生成。训练时你可以用前一天的真实值构造lag1,测试时拿不到这个真实值,只能用前一天的预测值回填。如果不管这一点,验证集上很好看,实际提交后分数崩得很难看。

def rolling_forecast(model, X_hist, n_days=7, lag_col="lag1"): history = X_hist[lag_col].copy() preds = [] for i in range(n_days): X_new = X_hist.iloc[[-1]].copy() X_new[lag_col] = history.iloc[-1] pred = model.predict(X_new)[0] preds.append(pred) history = pd.concat([history, pd.Series([pred])]) return preds

这个函数展示了迭代预测的核心逻辑:每一轮都把上一轮的预测值当作最新历史,喂给滞后特征。它是简化版,实际使用时要先冻结外部特征(星期几、趋势),只让滞后部分递归。如果外部特征里有移动平均,同样要存一个历史序列,逐日更新,否则误差会被自己喂大的后悔药害惨。

4.2 用TimeSeriesSplit替代随机K折:序列数据不能洗牌

随机K折在普通回归里没问题,在时间序列里就是泄漏。昨天和今天是强相关的,把今天放进训练集、明天放进测试集,模型等于提前知道了答案。常见做法是TimeSeriesSplit,训练集永远在前,测试集永远在后。下面这段代码中,gap=7是我强烈建议加的:如果特征里用了滞后7天,测试集第一天会用到训练集最后7天的真实值,不设gap就等于间接偷看。

from sklearn.model_selection import TimeSeriesSplit tscv = TimeSeriesSplit(n_splits=5, test_size=7, gap=7) for train_idx, val_idx in tscv.split(X): X_train, X_val = X.iloc[train_idx], X.iloc[val_idx] y_train, y_val = y.iloc[train_idx], y.iloc[val_idx] # 在每个fold上重新拟合模型并记录MAPE

test_size=7对应一周的预测窗口,gap=7对应滞后窗口的边界。不要在小样本上把n_splits设太大,否则每个训练集只有几十行,模型波动会很大。建议至少保证每个训练fold有70天以上数据。

4.3 可解释性输出:把系数换算成“周末人气降了百分之几”这种人话

线性回归的好处是系数可以直接翻译。假设以周一为基准,周日的系数是-0.18,这句话应该写成“周日比周一低约16%”,换算方式是np.exp(-0.18) - 1 ≈ -0.165。如果用了log目标,所有解释都要先过指数函数,不能直接拿系数说“低了0.18”。这种细节在论文里特别加分,评委一看就知道你真的懂模型。

Hard模式占比也可以用同样的方式单独建模。占比是0到1之间的连续变量,直接线性回归可能出现负数。一个常见做法是做logit变换,log(p/(1-p)),预测完再还原。如果还原后某个样本超出[0,1],就截断到边界。这个模型的系数解释更绕,但结论更清晰:Hard模式占比整体平稳,说明核心玩家群体的复购率很高。

5. C题翻车避坑手册:从数据泄漏到报告重心,五个高频踩坑记录

5.1 随机打乱数据做交叉验证,验证集分数好看,上分就崩

现象:用train_test_split默认方式随机切分,MAPE低得感人,提交后完全对不上。 原因:相邻日期的样本高度相关,模型记住了昨天,而不是学会了规律。 解决:所有验证一律用TimeSeriesSplit,并在构造滞后特征后保留至少7天的gap。

5.2 用“昨天人数”做特征,预测未来7天时拿不到特征值

现象:训练集和验证集都在同一条时间轴上回测,分数不错;换成真正的未来7天,代码直接报错或者预测值千篇一律。 原因:lag1在预测未来时没有真实值可用,而模型已经把这一列当成最强信号。 解决:写一个迭代滚动预测函数,把前一天的预测值当作今天的lag1。不要偷懒,也不要用“和训练集最后一天的真实值”复制粘贴凑数。

5.3 追精度追到黑匣子模型,评委一问就卡壳

现象:某队用XGBoost把验证MAPE压到很低,答辩时被问“为什么这个特征重要”,只能答“特征是模型自动挑的”。 原因:树模型的特征重要性不能直接等价于业务归因,评委不接受黑匣子解释。 解决:即使要用XGBoost,也要同时跑一个线性参照系,把两条路线的趋势方向、星期效应做对照。论文主线讲线性回归,复杂模型放附录当稳健性检验。

5.4 对Hard模式占比用普通线性回归,预测出负数

现象:Hard模式占比预测结果里有-0.05这种值,截断后又出现一堆0和1边界值。 原因:线性回归假设目标服从正态分布,占比变量被强行拉了回来,尾部超界。 解决:改用logit回归,预测前对0.999和0.001做clip,避免log里出现0或1。提交前把边界影响写进附录。

5.5 论文全在堆公式,没有把预测偏差还原成业务故事

现象:评委看完摘要不知道这题到底研究了什么。 原因:全文只写了“我们用了ARIMA”,没有回答“为什么人会少”“是衰减还是事件冲击”。 解决:每一章开头先给结论,例如“周日比周一少15%”“新闻事件带来42%的临时尖峰”。图是辅助,文字里必须有一句明确判断。

6. 收尾:用“预测加复盘”把模型写进论文,并验证它真能用于未来一周

做完模型不验证等于白做。我的习惯是留出最后14天不训练,在滚动窗口上每天预测一次,和真实值画在一起。不是只看一个总体MAPE,而是看误差集中在星期几、是不是某次新闻事件导致整体偏移。这样写进论文,既可以当“模型有效性验证”,也可以顺带展示模型的失败边界。

复盘时还有一个容易忽略的步骤:把“预测差的那几天”单独拎出来,看看当天Wordle单词是不是特别生僻或特别简单。生僻词会让报告基数下降,但Hard模式玩家占比可能会上升。如果你想在论文里加一点点深度,把这组对照做出来,放一个表就行。这不是赛题要求里必须有的东西,但它会让你的模型显得更像“理解人的行为”,而不是在拟合数字。

另外,最终提交的论文里要有敏感性分析一页。我一般会做三个版本:基础线性回归、加滞后特征、加新闻事件哑变量。表格列出滚动验证MAPE,三行数据就能说明每个特征模块贡献了多少。评委看到这种对比,比你写一整页原理更信服。

最后说个教训:有队伍把全部精力花在把MAPE从18%压到17%,结果没有时间写清楚建模假设和验证流程,最后奖项平平。这个比赛评的不是最低误差,而是“讲一个完整可信的故事”。先保证模型每一处选择都有理由,再去优化后面小数点。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 23:42:36

从原理到实操:马尾发型的技术拆解与万能扎法全攻略

作为从业十多年的生活类博主,我见过太多造型单品火起来又迅速过气,"ponytail"却始终是个例外。它不仅是扎起来方便,更是一种能横跨运动、通勤、红毯和日常带娃场景的万能发型逻辑。今天这篇不聊玄学,就把"ponytail…

作者头像 李华
网站建设 2026/10/27 23:42:28

状态机与并发实测:三款AI模型编程能力与成本深度对比

1. 这次测试的背景和选题逻辑1.1 为什么偏偏挑“状态机并发”这种最不讨喜的组合先说这次测试的起因。我平时负责一个偏底层的业务系统,里面有一堆长连接、定时任务、异步回调,状态流转特别复杂,属于典型的“状态机驱动并发”场景。最近 gpt-…

作者头像 李华
网站建设 2026/10/27 23:39:34

多AI协作走向工程落地:2026年AI日报聚焦模型部署与Agent可靠性

AI圈子的信息流速有多快,不用我多说,光是今天一天,我就在十几个渠道里反复看到“多AI协作”“Agent搭建”“模型部署”“AI编程”这几个关键词。趁着晚上把碎片整理成这份AI日报,既是我给自己做的知识盘点,也给关注AI的…

作者头像 李华
网站建设 2026/10/27 23:39:23

算力拐点:Vera Rubin与Groq 3开启AI基础设施新路线

1. 算力拐点:为什么说2026年是AI基础设施的转折年做AI基础设施这一行,最怕的就是“按旧地图找新大陆”。过去三年我们一直在聊H100、A100、Blackwell,好像英伟达的迭代节奏就是AI算力的全部真相。但只要你稍微关注一下最近的路演材料和供应链…

作者头像 李华
网站建设 2026/10/27 23:37:14

eVTOL多机队排班:从约束建模到动态调度实战

低空经济最热闹的时候,大家聊的都是 eVTOL 原型机、电机功率和航程数据。但真正开始跑运营之后,第一个让我失眠的问题其实很朴素:好几架飞机同时挂在几条航线上,航班表到底怎么排?这个问题的复杂度远超一般人的想象。它…

作者头像 李华
网站建设 2026/10/27 23:36:26

AI生成内容检测与论文质量提升的平衡之道

1. 项目概述:AI生成内容检测与论文质量把控去年Nature期刊报道称,超过60%的学术编辑遇到过明显由AI生成的投稿论文。我在某核心期刊担任审稿人期间,曾一周内连续收到5篇ChatGPT特征明显的稿件——它们有着完美的语法结构,却充斥着…

作者头像 李华