
ML-For-Beginners 实战作业在 Time Series 上用新数据构建并评估你自己的 ARIMA 模型【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners本文以 7-TimeSeries/2-ARIMA/assignment.md英文源文件 7-TimeSeries/2-ARIMA/assignment.md为核心骨架结合其配套课程 7-TimeSeries/2-ARIMA/README.md 与可运行 Notebook形成一篇从零到完整交付的 ARIMA 实战指南。阅读并完成本文后你将掌握如何获取新的时间序列数据、如何用SARIMAX复刻一个 ARIMA/SARIMA 模型、如何完成训练/测试切分与 0–1 区间缩放以及如何用MAPE平均绝对百分比误差度量并可视化预测精度最终提交一份包含可视化与准确性说明的 Notebook。作业背景与目标在 ML-For-Beginners 第 7 章《Time Series》第 2 课中你已经基于 GEFCom2014 电力负荷数据energy.csv构建过一个 ARIMA 模型并使用 walk-forward前向滚动验证评估了模型精度单步预测 MAPE 约为 0.56%多步预测 MAPE 约为 1.15%。本次作业要求在既有经验之上更进一步用一份全新的数据再构建一个全新的 ARIMA 模型把完整工作流程记录在一个 Notebook 中可视化数据与模型、用 MAPE 检验其精度并附上可解释的说明文字。作业本身是一道开放题——它的评判价值在于过程是否完整自洽而不是指标是否刷到最低。因此本文会先带你系统梳理课程中完整的建模与评估方法这是作业的评分核心再给出把作业落到其他数据集上的可执行方案与自查清单。评分标准解读评分等级判据优秀ExemplaryNotebook 完整呈现新 ARIMA 模型被构建、被测试、被解释包含可视化并明确陈述精度指标合格AdequateNotebook 已提交但缺少注释或存在 bug待改进Needs Improvement仅提交了不完整的 Notebook由此可以提炼出作业的四个硬性验收点①新数据、②新模型、③可视化、④以 MAPE 陈述精度同时要已测试且已解释。下文的方法学将逐一覆盖这四点。从课程 Notebook 出发标准 ARIMA 建模流水线作业不是凭空发挥而是对课程 7-TimeSeries/2-ARIMA/working/notebook.ipynb 中流水线的复用与迁移。先完整回顾这套流水线它就是你新作业的脚手架。1. 运行环境与依赖课程 Notebook 的第一件事是加载statsmodels——Python 生态中最常用的统计模型库ARIMA/SARIMA 的SARIMAX实现就来自其statsmodels.tsa.statespace.sarimax子模块。仓库为课程 Notebook 提供了可复现的 conda 环境定义 environment.yaml其中与本作业直接相关的依赖包括statsmodels0.9.0提供SARIMAX在后续版本中statsmodels的 API 基本不变可直接使用较新版本scikit-learn0.20.3提供MinMaxScaler做 0–1 缩放pandas/matplotlib/numpy数据处理与绘图pyramid-arima课程中提及可选的auto_arima()参数自动搜索工具。运行示例在环境已创建的前提下conda env create -f environment.yaml # 按需创建2. 导入库与工具函数课程代码块的导入清单几乎就是你新作业所需的完整依赖import 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) # 忽略警告保持 Notebook 输出干净这里要特别留意from common.utils import load_data, mape。仓库在 7-TimeSeries/common/utils.py 中封装了两个在作业中会反复使用的工具utils.pyload_data(data_dir)读取energy.csv把timestamp解析为时间索引并按小时频率reindex成连续时间轴该数据集本身没有缺失时段这一步用于校验mape(predictions, actuals)直接实现 MAPE 计算(np.absolute(predictions - actuals) / actuals).mean()作业第 4 个验收点就落在它身上。换新数据时mape可以直接复用load_data的列名假设timestamp/load需要按新数据集的实际列名做等价改写。3. 数据加载与整体可视化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()本课数据为 GEFCom2014 竞赛数据覆盖 2012–2014 三年逐小时电力负荷与温度此处只取负荷做单变量建模。4. 训练集 / 测试集切分时间顺序不可颠倒时间序列建模最关键的原则之一测试集必须晚于训练集防止模型偷看未来。课程的切分策略是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) # (1416, 1) print(Test data shape: , test.shape) # (48, 1)由于电力负荷存在明显的日/周季节性且近期消费模式最相似用最近一段时间训练即可两段的可视化对比如下课程特别注明因为拟合 ARIMA 用到的函数在拟合阶段就做 in-sample 验证所以这里直接省去了单独的验证集。5. 数据预处理过滤 0–1 缩放作业中同样需要做两步预处理。第一步过滤出目标时间段与目标列第二步用MinMaxScaler把数据投影到 (0,1) 区间——这能显著改善数值稳定性与拟合收敛行为scaler MinMaxScaler() train[load] scaler.fit_transform(train) # 训练集先 fit 再 transform test[load] scaler.transform(test) # 测试集只用 transform复用训练集的缩放参数训练集原值约 2000–4500 MW 量级与缩放后0–1的分布对比⚠️作业易错点MinMaxScaler的fit只能基于训练数据测试数据只能用transform。如果对整段数据先fit_transform再切分会造成未来信息泄漏MAPE 会被虚低地美化。6. 定义模型为什么是 SARIMAX 而不是 ARIMA课程提醒我们ARIMA 拆开是三部分ARAutoRegressive自回归模型回看过去的滞后值lags来推断当前值IIntegrated差分通过对非平稳序列做差分去掉趋势与季节性、稳定均值使其平稳MAMoving Average移动平均输出由当前及过去的滞后误差项决定。而当你处理的数据带有季节性——本课数据恰恰如此——就要升级为SARIMA即在 ARIMA 的基础上增加一组季节参数。SARIMAX是带外生变量扩展的 SARIMA实现上接受两组参数order(p, d, q)非季节部分。p对应自回归项、d对应差分阶数、q对应移动平均项seasonal_order(P, D, Q, s)季节部分。P/D/Q与p/d/q含义相同但作用于季节成分s是季节周期长度本课电力数据用24表示每日 24 小时。课程先试了手动组合并打印拟合摘要order (4, 1, 0) seasonal_order (1, 1, 0, 24) model SARIMAX(endogtrain, orderorder, seasonal_orderseasonal_order) results model.fit() print(results.summary()) # 观察系数显著性、AIC/BIC 等摘要表会给出各系数估计、标准误、以及 AIC/BIC 等可用于横向比较模型优劣的信息。课程同时提示参数选择本身偏主观且耗时可借助auto_arima()来自pyramid-arima自动搜索但在作业中手动尝试几组并记录比较过程同样是被认可的做法。用 Walk-Forward 验证评估模型为什么评估时间序列不能用普通留出法普通机器学习常把样本随机打散划分但时间序列的样本间存在先后依赖随机划分会泄露未来信息。因此课程采用walk-forward validation前向滚动验证——时间序列评估的金标准用当前训练窗口拟合模型预测下一个或几个时间步把已知真实值并入训练窗口移除窗口最旧的一个观测保持窗口大小固定以控制计算量重复上述过程。这会沿时间轴走过整个测试期得到多个滚动预测比单次拟合更接近模型上线后的真实表现。代价是每个时间步都要重新拟合一次模型计算开销随数据量与模型复杂度上升。构造多步预测的目标列设定预测步数horizon后先把测试集按 horizon 逐列前移构造出每个预测点的真值列HORIZON 3 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)滚动训练 滚动预测主循环%%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 [] 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(stepsHORIZON) 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)反缩放并整理为便于评估的长表预测值目前处于 0–1 缩放空间需要用同一scaler反变换回原始 MW 量纲再整理成时间戳 × 预测步 × 预测值 × 真实值的长表eval_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()可以看到预测值已回到 3000 MW 上下、与真实负荷非常接近的数量级。用 MAPE 量化精度并可视化MAPE 是什么MAPEMean Absolute Percentage Error平均绝对百分比误差把每个预测点的绝对误差|actual - predicted|除以该点真实值得到百分比误差再对所有预测点求平均最终得到平均偏了百分之多少。仓库中 utils.py 的实现如下def mape(predictions, actuals): Mean absolute percentage error predictions np.array(predictions) actuals np.array(actuals) return (np.absolute(predictions - actuals) / actuals).mean()规则很简单越低越好。例如 MAPE 为 10意味着预测平均偏离真实值 10%作为直觉参照本课单步 MAPE ≈ 0.56%、多步 MAPE ≈ 1.15%说明滚动预测平均误差不足 1.2%。计算单步与多步 MAPE# 若 HORIZON 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()) # 单步t1MAPE print(One step forecast MAPE: , (mape(eval_df[eval_df[h] t1][prediction], eval_df[eval_df[h] t1][actual])) * 100, %) # 多步全部步长合并MAPE print(Multi-step forecast MAPE: , mape(eval_df[prediction], eval_df[actual])*100, %)参考输出课程数据One step forecast MAPE: 0.5570581332313952 % Multi-step forecast MAPE: 1.1460048657704118 %结果可视化真实负荷 vs 各步预测课程最后把真实负荷红色实线与 t1…tHORIZON 的各步预测蓝色、随步长加深透明度/变细叠加绘制直观展示预测精度绘图时注意if HORIZON 1与多步分支的差异多步图中蓝线透明度随预测步数增大而降低alphamath.pow(0.8, t)暗示预测越远越不确定。把作业迁移到一份全新数据集课程数据与代码提供了完整的模板。现在回到作业本身如何在另一份数据上复刻并交付。步骤 1挑选数据建议格式作业原文推荐 Duke 大学的公开时间序列数据集集。对作业友好的数据一般具备以下特征选数据时可逐条核对单变量或可退化为单变量的数值序列时间索引等间隔如逐时/逐日/逐月缺失段越少越好具备肉眼可辨的趋势或季节性这样 SARIMA 才有用武之地也便于可视化讲故事样本量适中本课训练集 1416 个点、测试集 48 个点可作为量级参考以便在 Notebook 中多次滚动拟合。步骤 2按新数据形状改写载入代码课程的load_data假定列名为timestamp/load且频率为小时utils.py。新数据一般需要改成df pd.read_csv(your_data.csv, parse_dates[date_col]) df df.set_index(date_col).sort_index() # 保证索引有序 series df[target_col] # 取出目标单变量 series series.asfreq(D) # 按实际频率重采样缺失即 NaN随后重复课程的切分逻辑但务必保证切分边界处于你自己的数据时间范围内。若数据跨度比 3 年短可适当缩小训练/测试窗口如训练取最近 60%–80%测试取末尾一段并在 Notebook 中说明切分依据。步骤 3让模型与数据对话——参数不再照抄课程里的order(2,1,0)、seasonal_order(1,1,0,24)是为逐小时电力数据调出来的s24编码日周期。换数据后应重新推导观测周期长度逐日数据取s7周季节性较常见逐月数据可能不需要季节项或s12通过ACF/PACF 图辅助定阶from pandas.plotting import autocorrelation_plot是课程已导入的工具也可在 Notebook 中绘制偏自相关图观察拖尾/截尾特征来初定p、q用d差分阶数消除非平稳趋势可先对原始序列做 ADF 检验若 p 值偏大说明不平稳需做一阶差分有条件时可借助auto_arima()自动搜索参数再与手动选择对比把模型选择过程本身写进 Notebook——这是作业中解释模型的重要加分内容。# 示例先用 ACF 观察再手动尝试多组参数并比较 AIC from statsmodels.graphics.tsaplots import plot_acf, plot_pacf plot_acf(series.dropna(), lags40); plot_pacf(series.dropna(), lags40)步骤 4保留 walk-forward 评估骨架只替换数据对象滚动验证、MinMaxScaler缩放/反缩放、MAPE 统计、可视化四个模块全部可以原样复用——它们与新数据的耦合点仅在于喂进去的train/test对象。这也是作业性价比最高的一步把课程 Notebook 中的评估代码段整体搬迁即可。步骤 5用评分标准做交付前自检提交前逐条对照优秀档要求Notebook 中是否明确写明了数据来源与频率、为何切分该时间段新建一节说明是否可视化过原始数据、训练/测试切分、缩放前后分布、预测 vs 真实至少四张图是否陈述了模型的order/seasonal_order选择依据手动对比或auto_arima并打印过summary()是否用mape()给出单步与多步 MAPE并解释该数值意味着平均偏离百分之几全 notebook 是否可从头到尾无错运行bug 会直接落入合格档。延伸思考Challenge 方向作业之外课程还留下一道扩展题除 MAPE 外还有哪些时间序列精度指标常见方向包括MAE / MAD平均绝对误差与 MAPE 量纲一致但不受除以真实值的影响MSE / RMSE均方/均方根误差对大偏差更敏感MASE平均绝对缩放误差通过缩放使不同量纲序列可比。MAPE 的优势在于百分比形式直观可解释它的软肋是当某个时间点真实值接近 0 时误差会被分母放大甚至发散。如果你在作业数据中发现某些时段 MAPE 异常高不妨用这些补充指标交叉验证并把结论写入 Notebook。小结作业就是一次完整的方法学迁移一句话总结这份作业的评分逻辑它检验的不是模型精度的绝对数值而是你是否掌握了ARIMA 建模 walk-forward 评估 MAPE 度量的完整闭环。复用课程 2-ARIMA Notebook 的流水线与 common/utils.py 中的load_data/mape工具换入一份新数据、重新推导季节参数与差分阶数、完整保留可视化和 MAPE 陈述你就已经覆盖了优秀档的全部判据。【免费下载链接】ML-For-Beginners12 weeks, 26 lessons, 52 quizzes, classic Machine Learning for all项目地址: https://gitcode.com/GitHub_Trending/ml/ML-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考