You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

训练/验证/测试集流程正确性确认及交叉验证融入方法问询

训练/验证/测试集流程验证与时间序列交叉验证方案

一、你的流程理解修正

你的整体流程逻辑是对的,但有两个关键细节需要调整,避免影响模型泛化性:

  • 拆分规则:时间序列数据必须严格按时间先后顺序划分训练/验证/测试集,绝对不能随机拆分(否则会出现「未来数据泄露」,让模型提前看到本应未知的信息)。比如按时间排序后,前70%为训练集,中间10%为验证集,最后20%为测试集。
  • 最优模型的最终训练:当你用验证集调好超参数后,不能直接用之前仅在训练集上训练的模型预测测试集。正确做法是把训练集+验证集合并作为完整训练数据,用最优超参数重新训练模型,再用这个模型预测测试集——这样模型能利用更多数据,性能更稳定。

对应你的ARIMA代码,步骤6应该调整为:

# 合并训练集和验证集
full_train_set = pd.concat([training_set, validation_set])
# 用最优超参数重新训练
final_arima_model = ARIMA(endog=full_train_set, order=(best_p, best_d, best_q)).fit()
# 预测测试集
test_forecast = final_arima_model.forecast(steps=len(test_set))
print('测试集MSE:', mean_squared_error(test_set, test_forecast))

二、时间序列场景的交叉验证实现

传统K折交叉验证(随机拆分)不适用于时间序列,必须用滚动时间窗口交叉验证——核心是每次用过去的时序数据训练,用紧接着的未来数据验证,逐步滚动窗口,避免数据泄露。

结合sklearn和ARIMA的具体步骤:

1. 先拆分出独立测试集

先从原始数据中按时间顺序拆分出20%作为最终测试集(全程只用来评估最终模型,不参与任何调参),剩下80%作为「训练+验证候选集」用于交叉验证。

2. 初始化时间序列拆分器

用sklearn的TimeSeriesSplit生成按时间顺序划分的fold:

from sklearn.model_selection import TimeSeriesSplit
# 设置折数,比如5折
tscv = TimeSeriesSplit(n_splits=5)

它会自动生成如下fold:

  • Fold1:训练集=前20%候选数据,验证集=接下来的16%
  • Fold2:训练集=前36%候选数据,验证集=接下来的16%
  • ...以此类推,逐步滚动窗口

3. 遍历超参数,用交叉验证选最优

定义ARIMA的超参数候选范围(比如order=(p,d,q)的组合),然后在每个fold上训练、评估,取平均MSE最小的参数:

import numpy as np
from statsmodels.tsa.arima.model import ARIMA
from sklearn.metrics import mean_squared_error

# 超参数候选列表
param_candidates = [(1,1,0), (1,1,1), (2,1,0), (2,1,1), (0,1,1)]

best_mse = float('inf')
best_params = None

for order in param_candidates:
    fold_mses = []
    # 遍历每个时间窗口fold
    for train_idx, val_idx in tscv.split(train_val_candidate):
        train_fold = train_val_candidate[train_idx]
        val_fold = train_val_candidate[val_idx]
        # 训练ARIMA模型
        model = ARIMA(endog=train_fold, order=order)
        fitted_model = model.fit()
        # 预测验证fold
        val_forecast = fitted_model.forecast(steps=len(val_fold))
        # 计算MSE
        mse = mean_squared_error(val_fold, val_forecast)
        fold_mses.append(mse)
    # 计算当前参数的平均MSE
    avg_mse = np.mean(fold_mses)
    # 更新最优参数
    if avg_mse < best_mse:
        best_mse = avg_mse
        best_params = order

4. 训练最终模型并评估测试集

用最优参数在全部训练+验证候选集上训练模型,最后用测试集评估泛化性能:

# 用最优参数训练完整模型
final_model = ARIMA(endog=train_val_candidate, order=best_params)
final_fitted_model = final_model.fit()

# 预测测试集并评估
test_forecast = final_fitted_model.forecast(steps=len(test_set))
print('测试集最终MSE:', mean_squared_error(test_set, test_forecast))

这种方式能更可靠地评估超参数的泛化能力,避免单一验证集带来的偶然性,同时严格遵循时间序列的时序逻辑,不会出现数据泄露。

内容的提问来源于stack exchange,提问作者mbih

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 10:25:40