在衡量预测模型的表现之前,我们需要一种可靠的方法来划分用于构建模型(训练)的数据和用于测试其预测准确性的数据。对于许多机器学习任务,您可能会随机打乱数据并将其分成训练集和测试集。然而,这种方法对于时间序列分析存在根本性缺陷。随机划分的问题时间序列数据具有固有的时间顺序。每个观测值都依赖于之前的观测值。随机打乱数据会打破这一重要顺序,导致一些问题:数据泄露: 如果您随机分配数据点,您的训练集可能包含相对于测试集中数据点而言未来的观测值。模型可能会在真实的预测场景中无意中学习到本不应获取的未来信息,从而导致过于乐观的性能估计。想象一下,用下周的数据训练一个股票价格预测器来预测本周。它在测试中可能表现出色,但在实际中毫无用处。时间结构丢失: ARIMA和SARIMA等模型明确依赖于数据中的序列和时间依赖关系(如自相关性)。打乱数据会破坏这种结构,使这些模型无法学习到有意义的模式。因此,评估时间序列模型需要一种尊重数据年代顺序的不同方法。时间划分:保持顺序划分时间序列数据的标准方法是使用一个时间上的截止点。此点之前的所有数据成为训练集,此点之后的所有数据形成测试集(有时也称为保持集)。训练集: 用于拟合预测模型的参数(例如,确定ARIMA的$p, d, q$阶)。测试集: 用于评估拟合模型在未见过的未来数据上的表现。您将模型生成的预测结果(仅在训练数据上训练)与测试集中的实际值进行比较。这种按时间顺序的划分模拟了预测场景,即您基于过去数据构建模型并用它来预测未来的结果。在Pandas中实现时间划分为了有效评估时间序列预测模型的性能,需要一种可靠的方法来将用于构建模型(训练)的数据与用于测试其预测准确性的数据分开。时间序列数据通常加载到带有DatetimeIndex的Pandas DataFrame或Series中。按时间顺序划分它很简单,您可以选择特定日期,或根据所需的划分百分比使用整数索引位置。import pandas as pd # 假设 'series' 是您带有 DatetimeIndex 的 pandas Series # 例子: # index = pd.date_range(start='2020-01-01', periods=100, freq='D') # data = range(100) # series = pd.Series(data, index=index) # 方法 1: 按日期划分 cutoff_date = '2020-03-11' # 截止日期示例 train_data = series.loc[series.index < cutoff_date] test_data = series.loc[series.index >= cutoff_date] # 方法 2: 按位置划分 (例如,80% 训练,20% 测试) split_point = int(len(series) * 0.8) train_data_pos = series.iloc[:split_point] test_data_pos = series.iloc[split_point:] print(f"原始序列长度: {len(series)}") print(f"训练集长度 (按日期划分): {len(train_data)}") print(f"测试集长度 (按日期划分): {len(test_data)}") print(f"训练集长度 (按位置划分): {len(train_data_pos)}") print(f"测试集长度 (按位置划分): {len(test_data_pos)}") 以下是这种划分的可视化表示:{"data": [{"x": ["2020-01-01", "2020-01-15", "2020-02-01", "2020-02-15", "2020-03-01", "2020-03-11", "2020-03-15", "2020-03-30", "2020-04-09"], "y": [5, 15, 30, 40, 60, 70, 75, 90, 99], "mode": "lines+markers", "name": "时间序列", "line": {"color": "#4263eb"}}, {"x": ["2020-01-01", "2020-01-15", "2020-02-01", "2020-02-15", "2020-03-01", "2020-03-10"], "y": [5, 15, 30, 40, 60, 69], "mode": "lines", "name": "训练数据", "line": {"color": "#12b886", "width": 3}}, {"x": ["2020-03-11", "2020-03-15", "2020-03-30", "2020-04-09"], "y": [70, 75, 90, 99], "mode": "lines", "name": "测试数据", "line": {"color": "#f76707", "width": 3}}], "layout": {"title": "时间序列训练-测试划分", "xaxis": {"title": "日期", "rangeslider": {"visible": false}}, "yaxis": {"title": "值"}, "shapes": [{"type": "line", "x0": "2020-03-11", "y0": 0, "x1": "2020-03-11", "y1": 100, "line": {"color": "#adb5bd", "width": 2, "dash": "dash"}, "name": "划分点"}], "annotations": [{"x": "2020-03-11", "y": 95, "xref": "x", "yref": "y", "text": "截止点", "showarrow": true, "arrowhead": 1, "ax": -20, "ay": -30}], "legend": {"yanchor": "top", "y": 0.99, "xanchor": "left", "x": 0.01}}}这是一个将时间序列数据划分为训练集(绿色)和测试集(橙色)的例子,使用截止日期。模型在垂直虚线之前的数据上训练,并在其之后的数据上评估。选择划分点和测试集大小您应该为测试集保留多少数据?没有唯一的完美答案,但以下是一些指导原则:预测范围: 测试集应至少与您打算预测的最长周期一样长。如果您需要预测未来12个月,您的测试集应至少跨越12个月。季节性: 如果您的数据具有季节性(例如,年度模式),测试集理想情况下应覆盖至少一个完整的季节周期,以确保模型捕获这种能力得到充分测试。数据可用性: 常见的划分比例从70/30(训练/测试)到90/10不等。对于非常大的数据集,测试集占比较小可能仍能提供足够的观测值。对于较小的数据集,您需要确保训练集足够大,以便可靠地估计模型参数。稳定性: 确保测试集中观察到的模式(趋势、季节性)能够合理代表训练集中所见的模式,除非您专门测试模型对变化模式的鲁棒性。步进式验证(滚动预测起点)简单的训练-测试划分仅在一个特定时期评估模型。一种更严谨的方法是步进式验证,也称为滚动预测起点的评估。这种方法能更好地估计模型在实际部署场景中随时间的表现。该过程以迭代方式进行:选择一个初始训练期(例如,数据的前70%)。在此初始期上训练模型。预测下一个单一时间步(或多个时间步,取决于您的需求)。记录该时间步的预测值和实际值。扩展训练数据,以包含您刚刚预测的那个时间步的实际值。使用扩展的训练集重新训练模型(如果模型允许,可以高效更新)。重复步骤3-6,每次将预测起点向前移动一个时间步,直到您的预测覆盖所需的评估期(相当于简单划分中的测试集)。digraph WalkForward { rankdir=TB; node [shape=box, style=rounded, fontname="sans-serif"]; edge [fontname="sans-serif"]; bgcolor="transparent"; splines=ortho; "训练 1 (t=1..N)" -> "预测 t=N+1" [label=" 拟合 "]; "预测 t=N+1" -> "记录误差 (N+1)" [label=" 与实际值比较 "]; "记录误差 (N+1)" -> "训练 2 (t=1..N+1)" [label=" 添加实际值(N+1) "]; "训练 2 (t=1..N+1)" -> "预测 t=N+2" [label=" 拟合/更新 "]; "预测 t=N+2" -> "记录误差 (N+2)" [label=" 与实际值比较 "]; "记录误差 (N+2)" -> "训练 3 (t=1..N+2)" [label=" 添加实际值(N+2) "]; "训练 3 (t=1..N+2)" -> "..." [label=" 拟合/更新 "]; "..." -> "结束" [label=" 重复 "];}步进式验证的流程。模型在扩展数据上反复训练,并在紧随其后的时间步上进行测试。优点:在不同时间点提供多个预测误差测量结果,能更好地了解模型的一致性。更接近模拟模型在生产环境中的使用方式,即定期使用新数据重新训练。缺点:计算成本更高,因为模型需要多次重新估计。像scikit-learn这样的库提供了TimeSeriesSplit等工具,可以帮助自动化生成步进式验证的索引,但您仍然需要自己实现模型拟合和预测循环。正确划分时间序列数据是进行可靠模型评估不可或缺的第一步。通过尊重时间顺序,无论是采用简单的按时间顺序划分还是更高级的步进式验证,您都能确保评估指标反映模型在未见过的未来数据上的真实预测能力。这为计算和解释MA E、RMSE等指标奠定了基础,我们将在后续内容中介绍这些指标。