美赛数学建模速成二:时间序列回归预测模型详细讲解(超全面版本附代码示例)

模块三:时间序列预测 (Time Series Forecasting)

在美赛C题中,预测题通常占了一半的江山(例如:预测未来的能源消耗、预测药物的传播趋势)。

核心逻辑 :时间序列不仅仅是 x x x 和 y y y 的关系,而是 y t y_t yt 与 过去的时间 y t − 1 , y t − 2 . . . y_{t-1}, y_{t-2}... yt−1,yt−2... 的关系

我将根据数据量的多少数据的特征 ,把你手中的武器分为三档。请务必记住每种武器的适用条件判别方法


🔍 判别:我该用哪个模型?(决策流程图)

拿到带时间标签的数据(如:1990-2020年的数据),按以下逻辑判断:

  1. 看数据量
    • 极少 (< 15个点) :比如只给了过去10年的数据。
      • 👉 灰色预测 GM(1,1) (唯一解,强行用机器学习会过拟合)。
    • 中等 (> 20个点) 且有明显周期/节假日
      • 👉 Prophet (Facebook开源库,处理周期性极强)。
    • 中等 (> 30个点) 且追求统计学严谨性
      • 👉 ARIMA (经典,论文里公式好看)。
    • 海量 (> 1000个点) 且非线性强
      • 👉 LSTM / RNN (深度学习,慎用,除非你显卡好且时间多)。

🛠️ 武器一:灰色预测 GM(1,1) (Grey Prediction) ------ 贫信息救星

这是美赛和国内赛最喜欢的模型,专门解决"数据少、信息不全"的问题。

  • 适用情况
    • 数据样本极少(4个以上即可)。
    • 数据呈现指数增长指数衰减的趋势(如果是波动的,效果不好)。
  • 判别方法(级比检验)
    • 计算相邻两个数据的比值 λ k = x ( k − 1 ) / x ( k ) \lambda_k = x_{(k-1)}/x_{(k)} λk=x(k−1)/x(k)。
    • 如果所有比值都落在 ( e − 2 / ( n + 1 ) , e 2 / ( n + 1 ) ) (e^{-2/(n+1)}, e^{2/(n+1)}) (e−2/(n+1),e2/(n+1)) 区间内,说明可以建模。
  • 注意事项
    • 只能预测短期(往后推2-3年),推太远误差会指数级爆炸。
    • 如果数据是波动的,不要用 GM(1,1),或者先做平滑处理。

💻 Python 代码模板 (手写实现,sklearn没有)

python 复制代码
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

def gm11(x, n_pred=5):
    """
    x: 输入的原始数据序列 (1D array or list)
    n_pred: 往后预测多少期
    """
    x0 = np.array(x)
    n = len(x0)
    
    # 1. 级比检验 (可选,论文里要写这一步通过了)
    # lambda_k = x0[:-1] / x0[1:]
    # range_min, range_max = np.exp(-2/(n+1)), np.exp(2/(n+1))
    
    # 2. 累加生成 (AGO)
    x1 = np.cumsum(x0)
    
    # 3. 构造矩阵 B 和 Y
    z1 = (x1[:-1] + x1[1:]) / 2.0
    B = np.vstack([-z1, np.ones(n-1)]).T
    Y = x0[1:].reshape(-1, 1)
    
    # 4. 求解参数 a, u
    u_a = np.linalg.inv(B.T @ B) @ B.T @ Y
    a, u = u_a[0][0], u_a[1][0]
    
    # 5. 预测模型
    def predict_func(k):
        return (x0[0] - u/a) * np.exp(-a * k) + u/a
    
    # 还原 (累减)
    pred_x1 = np.array([predict_func(k) for k in range(n + n_pred)])
    pred_x0 = np.concatenate(([x0[0]], np.diff(pred_x1)))
    
    return pred_x0

# 使用示例
# history_data = [100, 110, 125, 140, 165]
# result = gm11(history_data, n_pred=3)

🛠️ 武器二:Prophet (先知) ------ 周期性数据神器

由 Facebook 开发,专门针对商业和具有周期性(Weekly, Yearly)的数据。

  • 适用情况
    • 数据有明显的季节性 (夏天高冬天低)或节假日效应
    • 数据中有缺失值异常值(Prophet 鲁棒性很强)。
  • 注意事项
    • 需要安装:pip install prophet (安装可能有点麻烦,建议提前装好)。
    • 输入数据的列名必须严格是 ds (时间) 和 y (数值)。

💻 Python 代码模板

python 复制代码
from prophet import Prophet
import pandas as pd

# 1. 准备数据 (必须是 ds 和 y 两列)
df_prophet = pd.DataFrame({
    'ds': pd.to_datetime(['2023-01-01', '2023-01-02', '...']), 
    'y': [100, 112, ...] 
})

# 2. 建模
model = Prophet(yearly_seasonality=True, weekly_seasonality=True)
model.fit(df_prophet)

# 3. 预测未来
future = model.make_future_dataframe(periods=30) # 往后推30天/年
forecast = model.predict(future)

# 4. 可视化 (Prophet自带画图,非常好用)
fig1 = model.plot(forecast) # 画预测图 (带置信区间阴影)
fig2 = model.plot_components(forecast) # 画趋势、周效应、年效应分解图 (论文素材!)

🛠️ 武器三:ARIMA 模型 ------ 统计学正统

Autoregressive Integrated Moving Average。最经典的统计模型。

  • 适用情况
    • 数据相对平稳(没有剧烈的趋势变化,或者差分后平稳)。
    • 适合做纯粹的数值推演,不涉及外部变量(如温度影响销量)。
  • 判别方法(平稳性检验 / ADF Test)
    • 如果在 p < 0.05 p < 0.05 p<0.05 (显著性水平),说明数据平稳,可以直接用。
    • 如果不平稳,需要进行差分 (Differencing) ,即 y t − y t − 1 y_t - y_{t-1} yt−yt−1,直到平稳为止。
  • 注意事项
    • 参数 ( p , d , q ) (p, d, q) (p,d,q) 很难定。建议使用 pmdarima 库的 auto_arima 自动寻找最优参数,别自己在比赛中手调 ACF/PACF 图,太慢了。

💻 Python 代码模板 (使用 auto_arima)

python 复制代码
import pmdarima as pm
from pmdarima.arima import auto_arima
# pip install pmdarima

# 1. 自动寻找最优参数 (Auto-ARIMA)
model = auto_arima(train_data, 
                   start_p=1, start_q=1, max_p=3, max_q=3, d=None, # d=None表示自动检测差分阶数
                   seasonal=False, # 如果有季节性,设为True
                   trace=True, # 打印过程
                   error_action='ignore', 
                   suppress_warnings=True)

print(model.summary()) # 打印统计表 (直接截图放论文附录)

# 2. 预测
preds, conf_int = model.predict(n_periods=10, return_conf_int=True)

# 3. 画图 (带置信区间)
# conf_int 包含了预测值的上下界,画出来就是那个漂亮的阴影带

⚠️ 模块四总结:避坑指南

在做时间序列题目时,评委最讨厌看到以下几种错误,请务必避免:

  1. 拿着非平稳数据直接跑模型

    • 比如数据明明是一直上涨的(非平稳),你却没做差分,直接丢进 ARIMA。
    • 解决 :论文里一定要提一句 "Stationarity Test (ADF Test)",或者说明用了 auto_arima 自动处理了差分。
  2. 没有置信区间 (Confidence Interval)

    • 预测未来是不确定的。如果你只画一条线,说明你不严谨。
    • 解决:画图时,一定要用浅色阴影画出 95% 的置信区间(Prophet 和 auto_arima 都会自动给出来)。这会让你的图表瞬间专业化。
  3. 预测得太远

    • 你有10年的数据,却预测未来50年。
    • 解决:通常预测长度不要超过历史数据的 1/3 或 1/2。如果在 GM(1,1) 中预测太远,要在论文中讨论"长期预测误差可能会增大"。
  4. 模型评价不当

    • 时间序列不能用随机打乱的交叉验证(K-Fold),因为时间是有顺序的!不能用未来的数据训练去预测过去。
    • 解决 :使用时间序列交叉验证 (Time Series Split),或者简单点,直接切分最后 10% 做测试集。

🎯 顾问建议

作为编程手,针对时间序列模块,你需要准备好:

  1. GM(1,1) 的 Python 函数(因为这一块现成的库不好找,必须手存)。
  2. Prophet 的环境(确保能 import prophet 不报错)。
  3. ADF 检验的代码(用来证明你检查了数据平稳性)。
python 复制代码
# 附赠:ADF 检验代码
from statsmodels.tsa.stattools import adfuller
def test_stationarity(timeseries):
    dftest = adfuller(timeseries, autolag='AIC')
    print('p-value:', dftest[1])
    if dftest[1] < 0.05:
        print("数据是平稳的 (Reject H0)")
    else:
        print("数据不平稳 (Fail to reject H0),需要差分")
相关推荐
奥特曼_ it3 小时前
【数据分析+机器学习】基于机器学习的招聘数据分析可视化预测推荐系统(完整系统源码+数据库+开发笔记+详细部署教程)✅
笔记·数据挖掘·数据分析
2501_936146044 小时前
传送带上罐体识别与分类_YOLOv26模型实现与优化_1
yolo·分类·数据挖掘
2501_936146047 小时前
基于YOLOv26的纽约标志性建筑识别与分类系统实现与训练_2
yolo·分类·数据挖掘
ID_180079054738 小时前
得物商品详情API接口在数据分析中的应用
数据挖掘·数据分析
机器学习之心9 小时前
Stacking集成传统机器学习模型与新型KAN网络回归预测+五模型回归对比
人工智能·机器学习·回归·stacking集成·kan网络回归预测
Faker66363aaa10 小时前
工业仓储环境空盒自动检测与分类_YOLOv26_1
yolo·分类·数据挖掘
byzh_rc10 小时前
[数学建模从入门到入土] 预测模型
人工智能·深度学习·线性代数·数学建模·回归·ar
KmjJgWeb12 小时前
基于YOLOv26的眼距分类识别:如何实现精准的眼部特征分析
yolo·分类·数据挖掘
凌晨一点的秃头猪12 小时前
ORB局部描述子提取
人工智能·分类·数据挖掘