美赛官网发布,决定今年(仅限2023年)设立一次春季 MCM/ICM竞赛。将在今年的3月30日至4月3日期间举行。已参加了今年刚结束的常规竞赛的团队也可以报名参加这次新增的春季竞赛。

所以数乐君今天给大家整理了刚结束的2023年美赛2月常规赛的 C题:Predicting Wordle Results (预测Wordle的结果)的解题思路 ,希望可以帮助到即将参加美赛春季赛的同学,一定要认真的研究历年赛题,把自己团队的成果展示出来~话不多话,我们首先来看一下赛题吧~

问题C:预测Wordle的结果

题目叙述

《纽约时报》要求您对本文件中的结果进行分析,以回答几个问题。

问题1:报告结果的数量每天都在变化。开发一个模型来解释这种变化,并使用您的模型为2023年3月1日报告的结果数量创建一个预测区间。这个词的任何属性是否会影响报告的在困难模式下播放的分数的百分比?如果是这样,如何?如果不是,为什么不呢?

问题2:对于未来日期的给定未来解决方案词,开发一个模型,使您能够预测报告结果的分布。换句话说,预测未来日期 (1, 2, 3, 4, 5, 6, X) 的相关百分比。哪些不确定性与您的模型和预测相关?举一个你对2023年3月1日EERIE这个词的预测的具体例子。你对你的模型的预测有多自信?

问题3:开发并总结一个模型来按难度对解决方案单词进行分类。识别与每个分类关联的给定词的属性。使用您的模型,EERIE这个词有多难?讨论分类模型的准确性。

问题4:列出并描述这个数据集的其他一些有趣的特征

1、问题一
1.1 第一小问

第一小问,建立一个时间序列预测模型,首先对数据按先后顺序排序,查看数据分布

import pandas as pd

import datetime as dt

import numpy as np

import matplotlib.pyplot as plt

import seaborn as sns

from scipy.stats import skew,kurtosis

pd.options.display.notebook_repr_html=False # 表格显示

plt.rcParams['figure.dpi'] = 75 # 图形分辨率

sns.set_theme(style='darkgrid') # 图形主题

df = pd.read_excel('data/Problem_C_Data_Wordle.xlsx',header=1)

data = df.drop(columns='Unnamed: 0')

data['Date'] = pd.to_datetime(data['Date'])

data.set_index("Date", inplace=True)

data.sort_index(ascending=True,inplace=True)

data

(1)查看数据分布

sns.lineplot(x="Date", y="Number of reported results",data=data)

plt.savefig('img/1.png',dpi=300)

plt.show()

(2)使用箱线图进行查看异常值,300000以上是异常值,黑色的,需要进行处理,本代码中采用的向前填充法,就是用异常值前一天的数据来填充。

sns.boxplot(data['Number of reported results'],color='red')

plt.savefig('img/2.png',dpi=300)

(3)因为Number of reported results是数值特征,在线性回归模型中,为了取得更好的建模效果,在建立回归评估模型之前,应该检查确认样本的分布,如果符合正态分布,则这种训练集是及其理想的,否则应该补充完善训练集或者通过技术手段对训练集进行优化。由KDE图和Q-Q图可知,价格属性呈右偏分布且不服从正态部分,在回归之前需要对数据进一步数据转换。

import scipy.stats as st

plt.figure(figsize=(20, 6))

y = data.Numbers

plt.subplot(121)

plt.title('johnsonsu Distribution fitting',fontsize=20)

sns.distplot(y, kde=False, fit=st.johnsonsu, color='Red')

y2 = data.Numbers

plt.subplot(122)

st.probplot(y2, dist="norm", plot=plt)

plt.title('Q-Q Figure',fontsize=20)

plt.xlabel('X quantile',fontsize=15)

plt.ylabel('Y quantile',fontsize=15)

plt.savefig('img/5.png',dpi=300)

plt.show()

转换前

转换后,注意,预测得到的结果,还要转换回来,采用指数转换。公式是log(x) =y,x=e^y。

import scipy.stats as st

plt.figure(figsize=(20, 6))

y = np.log(data.Numbers)

plt.subplot(121)

plt.title('johnsonsu Distribution fitting',fontsize=20)

sns.distplot(y, kde=False, fit=st.johnsonsu, color='Red')

y2 = np.log(data.Numbers)

plt.subplot(122)

st.probplot(y2, dist="norm", plot=plt)

plt.title('Q-Q Figure',fontsize=20)

plt.xlabel('X quantile',fontsize=15)

plt.ylabel('Y quantile',fontsize=15)

plt.savefig('img/6.png',dpi=300)

plt.show()

(4)可视化所有特征与label的相关性,采用皮尔逊相关性方法,筛选相关性较高作为数据集的特征。得到41个特征。

# 可视化Top20相关性最高的特征

df =data.copy()

corr = df[["target_t1"]+features].corr().abs()

k = 15

col = corr.nlargest(k,'target_t1')['target_t1'].index

plt.subplots(figsize = (10,10))

plt.title("Pearson correlation with label")

sns.heatmap(df[col].corr(),annot=True,square=True,annot_kws={"size":14},cmap="YlGnBu")

plt.savefig('img/10.png',dpi=300)

plt.show()

(5)划分数据集前,需要标准化特征数据,标准化后,将1-11月的数据作为训练集,12月的数据作为测试集。可以看到用简单线性回归可以拟合曲线。

data_feateng = df[features + targets].dropna()

nobs= len(data_feateng)

print("样本数量: ", nobs)

X_train = data_feateng.loc["2022-1":"2022-11"][features]

y_train = data_feateng.loc["2022-1":"2022-11"][targets]

X_test = data_feateng.loc["2022-12"][features]

y_test = data_feateng.loc["2022-12"][targets]

n, k = X_train.shape

print("Train: {}{}, \nTest: {}{}".format(X_train.shape, y_train.shape,

X_test.shape, y_test.shape))

plt.plot(y_train.index, y_train.target_t1.values, label="train")

plt.plot(y_test.index, y_test.target_t1.values, label="test")

plt.title("Train/Test split")

plt.legend()

plt.xticks(rotation=45)

plt.savefig('img/11.png',dpi=300)

plt.show()

(5)采用线性回归

from sklearn.linear_model import LinearRegression

from sklearn.metrics import mean_squared_error

X_train = data_feateng.loc["2022-1":"2022-11"][features]

y_train = data_feateng.loc["2022-1":"2022-11"][targets]

X_test = data_feateng.loc["2022-12"][features]

y_test = data_feateng.loc["2022-12"][targets]

reg = LinearRegression().fit(X_train, y_train["target_t1"])

p_train = reg.predict(X_train)

p_test = reg.predict(X_test)

y_pred = np.exp(p_test*std+mean)

y_true = np.exp(y_test["target_t1"]*std+mean)

RMSE_test = np.sqrt(mean_squared_error(y_true,y_pred))

print("Test RMSE: {}".format(RMSE_test))

模型误差是RMSE: 1992.293296317915

模型训练和预测

from sklearn.linear_model import LinearRegression

reg = LinearRegression().fit(X_train, y_train["target_t1"])

p_train = reg.predict(X_train)

arr = np.array(X_test).reshape((1,-1))

p_test = reg.predict(arr)

y_pred = np.exp(p_test*std+mean)

print(f"预测区间是[{int(y_pred-RMSE_test)}至{int(y_pred+int(RMSE_test))}]")

预测得到的结果减去误差,得到预测区间的左边界,加上误差,得到预测区间的右边界。最后得出的预测区间是【18578-22562】

由于篇幅过长,其他赛题解析可以关注【数模乐园】公众号动态,会随时更新!本文章解题思路仅代表作者个人观点!

文章源于CSDN-Better Bench

2023年美国大学生数学建模春季竞赛报名正式开始,数模乐园继续推出2023年美赛春季赛辅助报名服务,数模乐园作为国内美赛报名最大官方平台,为参加美赛的同学解决国际支付报名难的问题,为同学们省去大部分繁琐流程的同时,还赠纸质证书打印邮寄、美赛赛题解析美赛专属礼包、赛题翻译等备赛资料,由于全国各高校报名数量较多为避免出现报名拥堵,请同学们提前完成报名!

2023年春季美赛报名方式

扫描下方二维码即可报名↓

进群领取历年真题及赛前培训资料、队友招募↓