资讯动态

ML-For-Beginners 系列实践:使用新数据集构建 ARIMA 时间序列预测模型并用 MAPE 评估精度

发布时间:2026/9/11 18:30:38 来源:尧图企业网站定制
ML-For-Beginners 系列实践使用新数据集构建 ARIMA 时间序列预测模型并用 MAPE 评估精度【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners本篇文章对应 ML-For-Beginners 项目中《Time series forecasting with ARIMA》课程的课后作业assignment完整讲解如何基于一份全新的时间序列数据构建一个 ARIMA/SARIMA 预测模型并在 Jupyter Notebook 中完成数据可视化、模型训练与 MAPE 精度评估的全流程。读完本文你将掌握时间序列模型的完整实践链路从数据加载、训练/测试集切分、MinMax 归一化到 SARIMAX 参数选择、滑动窗口walk-forward验证以及用 MAPE 量化模型预测误差。作业任务速览从复现模型到迁移建模作业原文要求非常明确见 作业文档在完成课程中基于能源负荷数据的 ARIMA 模型之后使用一份全新的数据可尝试 Duke 大学时间序列数据集站点提供的公开数据集重新构建一个 ARIMA 模型并在 Notebook 中完成三件事记录工作过程对每一步操作进行文字注释与说明可视化数据与模型绘制原始数据的时序图、训练/测试划分图、模型预测效果图使用 MAPE 评估精度计算平均绝对百分比误差并明确写出模型的精度水平。作业的评分标准Rubric给出了三条梯度标准优秀Exemplary合格Adequate待改进Needs Improvement交付物提交一个 Notebook其中包含新建 ARIMA 模型的构建、测试与讲解附可视化结果并写明精度Notebook 已提交但缺少注释或存在 bug提交的 Notebook 不完整也就是说这并非一道跑通代码即可的题目而是考察你是否能把课程中学到的 ARIMA 建模方法论迁移到一份从未见过的数据上。要完成它你需要先掌握课程讲义7-TimeSeries/2-ARIMA/README.md中的完整建模流程。下面我们就按作业要求的三个交付物逐步展开。前置知识ARIMA 的构成与适用场景课程讲义明确指出ARIMAAutoRegressive Integrated Moving Average自回归积分滑动平均模型尤其适合拟合表现出**非平稳性non-stationarity**的数据。在动手之前必须理解三个核心概念平稳性Stationarity从统计学角度看平稳数据在时间平移后其分布不发生改变。非平稳数据会因趋势trend而表现出波动必须先经过变换才能用于分析。例如季节性seasonality会给数据引入波动可通过季节性差分过程来消除。差分Differencing将非平稳数据转换为平稳数据的过程通过去除数据中非常数趋势来实现。差分移除时间序列水平的变化消除趋势与季节性从而使时间序列的均值保持稳定。Shixiong 等人论文所述滞后值Lags自回归模型回看历史数据中的先前观测值这些先前值被称为滞后值。ARIMA 的名称由三部分组成正好对应模型的三个参数AR自回归模型基于自身的滞后值prior values对演化变量做回归即用过去的值预测当前值I积分/Integrated与 ARMA 模型不同ARIMA 中的 I 指对数据施加差分步骤以消除非平稳性差分阶数用参数d表示MA移动平均输出变量由当前及过去的滞后值观测决定用参数q控制。当数据存在季节性时能源负荷数据正是如此需要使用季节性的 ARIMA即SARIMA此时需要额外一组大写参数P、D、Q它们与p、d、q含义一一对应但作用于模型的季节分量另外还需要指定季节周期长度s小时级能源数据通常取 24即一天一个完整周期。步骤一加载数据——理解工具函数与数据集结构作业要求使用全新数据但为了说明完整流程我们先以课程使用的 GEFCom2014 能源负荷数据energy.csv为例。这份数据包含 2012 至 2014 年间逐小时的电力负荷与温度记录任务是对未来时刻的电力负荷进行预测该数据集的背景在 参考答案 Notebook 的开篇说明中可以得到确认。课程提供了统一的工具函数模块 7-TimeSeries/common/utils.py其中load_data()函数负责把原始 CSV 转换成一个以时间为索引、逐小时对齐的 DataFramedef load_data(data_dir): Load the GEFCom 2014 energy load data energy pd.read_csv(os.path.join(data_dir, energy.csv), parse_dates[timestamp]) # Reindex the dataframe such that the dataframe has a record for every time point # between the minimum and maximum timestamp in the time series. energy.index energy[timestamp] energy energy.reindex(pd.date_range(min(energy[timestamp]), max(energy[timestamp]), freqH)) energy energy.drop(timestamp, axis1) return energy从源码可以看到该函数的核心价值在于reindex到以小时为频率的完整时间范围从而暴露数据中是否存在缺失时间段该数据集本身没有缺失。换用你选择的全新数据时务必先完成同样的时间索引规整并检查缺失值与频率是否一致——这是时间序列建模最容易踩的坑。加载数据并绘制全量时序图的代码如下来自课程讲义与 Notebookimport os import warnings import matplotlib.pyplot as plt import numpy as np import pandas as pd import datetime as dt import math from pandas.plotting import autocorrelation_plot from statsmodels.tsa.statespace.sarimax import SARIMAX from sklearn.preprocessing import MinMaxScaler from common.utils import load_data, mape from IPython.display import Image %matplotlib inline pd.options.display.float_format {:,.2f}.format np.set_printoptions(precision2) warnings.filterwarnings(ignore) # 忽略警告信息 energy load_data(./data)[[load]] energy.head(10) energy.plot(yload, subplotsTrue, figsize(15, 8), fontsize12) plt.xlabel(timestamp, fontsize12) plt.ylabel(load, fontsize12) plt.show()说明若使用 conda 管理环境可参考课程自带的 environment.yaml 配置文件其中锁定了statsmodels0.9.0、pandas0.23.4等版本参考答案 Notebook 中则注明statsmodels0.12.2、matplotlib3.4.2、scikit-learn0.24.2的组合已知可运行。实际使用时以你环境中的可用版本为准。步骤二划分训练集与测试集——严格按时间先后切分时间序列建模与普通监督学习最大的区别在于训练集与测试集必须按时间先后切分绝不能让模型偷看未来数据。课程讲义强调测试集必须覆盖比训练集更晚的时间段。以能源数据为例train_start_dt 2014-11-01 00:00:00 test_start_dt 2014-12-30 00:00:00 train energy.copy()[(energy.index train_start_dt) (energy.index test_start_dt)][[load]] test energy.copy()[energy.index test_start_dt][[load]] print(Training data shape: , train.shape) print(Test data shape: , test.shape)输出为Training data shape: (1416, 1) Test data shape: (48, 1)在讲义中训练集实际覆盖 2014-11-01 至 2014-12-30 之间约 59 天1416 个小时测试集则是 2014-12-30 起的 48 个小时。讲义还特别指出由于能源消耗存在强季节性但近期消耗与更近的几天最相似因此使用相对较小的时间窗口做训练就已足够同时因为SARIMAX在拟合时会使用样本内验证in-sample validation所以这里不再单独划分验证集。将训练段与测试段叠加可视化可以直观看到两条曲线的衔接energy[(energy.index test_start_dt) (energy.index train_start_dt)][[load]].rename(columns{load:train}) \ .join(energy[test_start_dt:][[load]].rename(columns{load:test}), howouter) \ .plot(y[train, test], figsize(15, 8), fontsize12) plt.xlabel(timestamp, fontsize12) plt.ylabel(load, fontsize12) plt.show()迁移到全新数据时请保持同样的思路根据你对数据周期性的观察日周期、周周期、年周期来选择合适的训练窗口长度并确保测试段在时间上严格晚于训练段。步骤三数据预处理——MinMax 归一化到 (0, 1)SARIMAX对数值尺度敏感课程使用sklearn.preprocessing.MinMaxScaler把负荷数据缩放至 (0, 1) 区间from sklearn.preprocessing import MinMaxScaler scaler MinMaxScaler() train[load] scaler.fit_transform(train) train.head(10)注意先在训练集上fit_transform再用同一个scaler对测试集执行transform避免测试数据的信息泄漏到缩放器中test[load] scaler.transform(test) test.head()课程讲义还展示了缩放前后的分布对比直方图原始数据与缩放数据的plot.hist(bins100)用于确认变换没有破坏数据形态。这套先 fit 后 transform、测试集不参与 fit的规范同样适用于你的新数据集。步骤四定义并拟合 SARIMAX 模型接下来进入核心环节——用statsmodels实现模型。讲义给出的三步法是调用SARIMAX()并传入模型参数p, d, q与P, D, Q定义模型调用fit()在训练数据上拟合调用forecast()并指定预测步数horizon生成预测。三个基础参数的含义是p自回归部分参数对应模型中纳入的过去值d积分差分部分参数决定对时间序列施加的差分次数q移动平均部分参数。由于能源数据带季节性使用带季节参数的 SARIMASARIMAX需要再指定P、D、Q与季节周期s。讲义先以手动选择的参数演示HORIZON 3 print(Forecasting horizon:, HORIZON, hours) order (4, 1, 0) seasonal_order (1, 1, 0, 24) model SARIMAX(endogtrain, orderorder, seasonal_orderseasonal_order) results model.fit() print(results.summary())results.summary()会打印一张包含系数估计、标准误、AIC/BIC 等指标的统计表用于判断拟合质量。讲义坦诚地指出为 ARIMA 选择最优参数具有一定主观性且耗时可以考虑使用auto_arima()如pmdarima库提供来自动搜索课程环境配置中也确实包含pyramid-arima0.8.1见 environment.yaml但教程先引导读者手动尝试几组参数来建立直觉。步骤五滑动窗口验证Walk-Forward Validation——时间序列评估的金标准作业要求测试你的模型而课程讲义强调滑动窗口验证walk-forward validation是时间序列模型评估的黄金标准推荐在自有项目中采用。它的思路是从时间序列起点开始用训练集拟合模型预测下一个时间步将预测值与已知真实值对比把真实值并入训练集重复上述过程。每来一个新观测模型都会重新训练一次因此能最真实地反映模型在实践中的表现。代价是计算量较大要训练很多个模型数据量小或模型简单时可以接受。讲义还特别提示为了训练效率应保持训练窗口长度固定——每加入一个新观测就从窗口开头移除一个旧观测。首先为每个 HORIZON 步构造测试数据点把目标列按步数向后平移test_shifted test.copy() for t in range(1, HORIZON1): test_shifted[loadstr(t)] test_shifted[load].shift(-t, freqH) test_shifted test_shifted.dropna(howany) test_shifted.head(5)输出示例数据按 horizon 步数水平平移loadload1load22014-12-3000:00:000.330.290.272014-12-3001:00:000.290.270.272014-12-3002:00:000.270.270.30然后用固定大小的滑动窗口在循环中逐时间步训练并预测%%time training_window 720 # 用 30 天720 小时作为训练窗口 train_ts train[load] test_ts test_shifted history [x for x in train_ts] history history[(-training_window):] predictions list() # 演示时使用更简单的模型 order (2, 1, 0) seasonal_order (1, 1, 0, 24) for t in range(test_ts.shape[0]): model SARIMAX(endoghistory, orderorder, seasonal_orderseasonal_order) model_fit model.fit() yhat model_fit.forecast(steps HORIZON) predictions.append(yhat) obs list(test_ts.iloc[t]) # 移动训练窗口 history.append(obs[0]) history.pop(0) print(test_ts.index[t]) print(t1, : predicted , yhat, expected , obs)运行时可观察每个时间步的预测输出2014-12-30 00:00:00 1 : predicted [0.32 0.29 0.28] expected [0.32945389435989236, 0.2900626678603402, 0.2739480752014323] 2014-12-30 01:00:00 2 : predicted [0.3 0.29 0.3 ] expected [0.2900626678603402, 0.2739480752014323, 0.26812891674127126]将预测结果与真实负荷整理进同一个评估 DataFrame并用scaler.inverse_transform还原到原始量纲MWeval_df pd.DataFrame(predictions, columns[tstr(t) for t in range(1, HORIZON1)]) eval_df[timestamp] test.index[0:len(test.index)-HORIZON1] eval_df pd.melt(eval_df, id_varstimestamp, value_nameprediction, var_nameh) eval_df[actual] np.array(np.transpose(test_ts)).ravel() eval_df[[prediction, actual]] scaler.inverse_transform(eval_df[[prediction, actual]]) eval_df.head()输出示例timestamphpredictionactual02014-12-3000:00:00t13,008.743,023.0012014-12-3001:00:00t12,955.532,935.0022014-12-3002:00:00t12,900.172,899.00课程的工具模块中其实还封装了一个create_evaluation_df()函数见 7-TimeSeries/common/utils.py专门用于把预测结果、时间戳与真实值组装成便于评估的 DataFrame你可以直接复用这一模式。步骤六用 MAPE 评估模型精度作业明确要求用 MAPE 评估精度。MAPE平均绝对百分比误差把每个时刻的预测误差表示为相对真实值的百分比公式为MAPE (1/n) * Σ |actual_t - predicted_t| / actual_t对每个预测时点的绝对差值求和再除以拟合点数 n维基百科定义。课程讲义给出了 MAPE 的示意图工具模块中mape()的实现非常简洁7-TimeSeries/common/utils.pydef mape(predictions, actuals): Mean absolute percentage error predictions np.array(predictions) actuals np.array(actuals) return (np.absolute(predictions - actuals) / actuals).mean()在 Notebook 中依次完成三步评估1按预测步数分组计算 APE绝对百分比误差均值if(HORIZON 1): eval_df[APE] (eval_df[prediction] - eval_df[actual]).abs() / eval_df[actual] print(eval_df.groupby(h)[APE].mean())2计算单步预测的 MAPEprint(One step forecast MAPE: , (mape(eval_df[eval_df[h] t1][prediction], eval_df[eval_df[h] t1][actual]))*100, %)One step forecast MAPE: 0.5570581332313952 %3计算多步预测的整体 MAPEprint(Multi-step forecast MAPE: , mape(eval_df[prediction], eval_df[actual])*100, %)Multi-step forecast MAPE: 1.1460048657704118 %讲义对结果的解读是数字越小越好——可以这样理解MAPE 为 10 意味着平均误差 10%。单步预测 MAPE 约 0.56%、多步约 1.15%说明该模型精度相当不错。最后将预测与真实值画在同一张图上直观检查拟合效果多步预测时预测线按 horizon 步数逐级淡出if(HORIZON 1): ## 绘制单步预测 eval_df.plot(xtimestamp, y[actual, prediction], style[r, b], figsize(15, 8)) else: ## 绘制多步预测 plot_df eval_df[(eval_df.ht1)][[timestamp, actual]] for t in range(1, HORIZON1): plot_df[tstr(t)] eval_df[(eval_df.htstr(t))][prediction].values fig plt.figure(figsize(15, 8)) ax plt.plot(plot_df[timestamp], plot_df[actual], colorred, linewidth4.0) ax fig.add_subplot(111) for t in range(1, HORIZON1): x plot_df[timestamp][(t-1):] y plot_df[tstr(t)][0:len(x)] ax.plot(x, y, colorblue, linewidth4*math.pow(.9,t), alphamath.pow(0.8,t)) ax.legend(locbest) plt.xlabel(timestamp, fontsize12) plt.ylabel(load, fontsize12) plt.show()红色曲线代表真实负荷蓝色曲线代表各 horizon 步的预测——预测线与真实线贴合紧密正是模型精度良好的直观证据。在你的作业 Notebook 中这张图就是可视化模型效果的核心交付物。将流程迁移到全新数据的检查清单作业的难点在于把上述方法论套用到新数据上。结合讲义与参考答案 Notebook 的实现建议按以下清单推进数据体检确认时间索引唯一且等间隔必要时参照load_data()的reindex思路处理缺失值与异常值确认数据是否存在趋势或季节性决定是否使用 SARIMA。时间顺序切分按时间先后划分 train/test测试段必须严格晚于训练段根据数据周期小时数据取 24、日数据取 7 等决定训练窗口长度。归一化在训练集上fit_transform用同一scaler变换测试集。参数选择从p, d, q与P, D, Q, s的手动试探开始如(2, 1, 0)(1, 1, 0, 24)记录summary()中的 AIC/BIC 辅助判断数据规模允许时可尝试auto_arima()自动搜索。滑动窗口验证固定窗口如 720 步逐时间步训练、预测、回填保持窗口先进先出。MAPE 评估分别报告单步与多步 MAPE并给出文字解读如MAPE 为 1.15% 意味着平均偏差约 1.15%。可视化交付至少包含全量数据时序图、训练/测试划分图、预测对比图三张图且每张图都有对应的 markdown 注释——这正是 Rubric 中优秀档的要求。延伸思考除了 MAPE还有哪些精度指标课程最后的 Challenge 提示可以深入研究时间序列模型的其他精度指标例如 MAD平均绝对偏差、MSD均方偏差等讲义 MAPE 部分提及的参考资料即讨论了这些指标标准教材如 Forecasting: Principles and Practice 的第 3 章也有系统介绍。在作业中除了按 MAPE 评估外你还可以补充计算均方根误差RMSE或平均绝对误差MAE从不同角度刻画模型误差这会让你的 Notebook 分析更加完整、更接近优秀档的要求。小结完成这次作业的过程本质上是一次完整的时间序列建模方法论迁移训练从load_data的数据规整到按时间切分训练/测试集、MinMax 归一化、SARIMAX 建模、滑动窗口验证再到 MAPE 量化评估与可视化交付。参照课程讲义README.md、随堂 Notebookworking/notebook.ipynb与参考答案solution/notebook.ipynb把这份清单应用到你的新数据集上就能产出一份满足优秀评分标准、注释完整、可视化清晰且精度可量化的作业 Notebook。【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价