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

基于sklearn TimeSeriesSplit的时间序列交叉验证数据格式疑问

关于sklearn TimeSeriesSplit的X格式与你的时序拆分需求详解

嘿,我来给你把这个问题掰明白~

首先:为什么示例里的X是二维数组?

这是因为scikit-learn的所有建模工具(包括交叉验证组件)都要求特征数据必须是二维结构:

  • 哪怕你的时间序列只有1个特征(比如单变量时序),也得把它转换成(样本数, 特征数)的二维数组,而不是一维的(样本数,)数组。
  • 示例里的X = np.array([[1, 2], [3, 4], [1, 2], [3, 4]])是4个时间步的样本,每个样本有2个特征,完全符合sklearn的输入规范。如果你的数据是单变量的,比如X = np.array([1,3,1,3]),那得转成X = X.reshape(-1, 1)才能用哦。

然后:实现你要的「前n-1个训练、第n个测试」的时序拆分

你想要的是滚动式单步预测拆分——每次用之前所有的历史数据训练,预测下一个时间步,而且严格保持时序不打乱。用TimeSeriesSplit完全可以实现,关键是调整参数:

代码示例

from sklearn.model_selection import TimeSeriesSplit
import numpy as np

# 假设我们有5个时间步的样本(单变量特征,先转成二维)
X = np.array([1, 2, 3, 4, 5]).reshape(-1, 1)
y = np.array([10, 20, 30, 40, 50])  # 对应的标签,一维数组即可

# 配置TimeSeriesSplit:n_splits设为样本数-1,test_size=1(每次测试1个样本)
tscv = TimeSeriesSplit(n_splits=len(X)-1, test_size=1)

# 遍历每折拆分,打印训练/测试集的索引
for fold_idx, (train_idx, test_idx) in enumerate(tscv.split(X)):
    print(f"第{fold_idx+1}折:")
    print(f"  训练集索引:{train_idx},对应数据:X={X[train_idx].flatten()}, y={y[train_idx]}")
    print(f"  测试集索引:{test_idx},对应数据:X={X[test_idx].flatten()}, y={y[test_idx]}")
    print("---")

输出结果解释

运行后你会看到:

第1折:
  训练集索引:[0],对应数据:X=[1], y=[10]
  测试集索引:[1],对应数据:X=[2], y=[20]
---
第2折:
  训练集索引:[0 1],对应数据:X=[1 2], y=[10 20]
  测试集索引:[2],对应数据:X=[3], y=[30]
---
第3折:
  训练集索引:[0 1 2],对应数据:X=[1 2 3], y=[10 20 30]
  测试集索引:[3],对应数据:X=[4], y=[40]
---
第4折:
  训练集索引:[0 1 2 3],对应数据:X=[1 2 3 4], y=[10 20 30 40]
  测试集索引:[4],对应数据:X=[5], y=[50]
---

完全符合你要的「前n-1个训练,第n个测试」的时序要求,而且全程没有打乱时间顺序。

关键参数说明

  • n_splits=len(X)-1:因为我们要对每个后续的样本做一次预测,所以拆分次数等于样本数减1。
  • test_size=1:指定每次测试集只取1个样本(也就是当前要预测的下一个时间步)。
  • 如果你想限制训练集的最大长度(比如只用最近的k个样本训练,而不是所有历史),可以加max_train_size=k参数,比如max_train_size=3,那第4折的训练集就会是[2,3,4]而不是所有前面的样本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:42:25