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

使用skforecast回测时遇KeyError:索引不匹配问题求助

解决skforecast backtesting_forecaster索引不匹配的KeyError问题

问题重现

使用skforecast的backtesting_forecaster做时序回测时,触发如下KeyError:

KeyError: "None of [Int64Index([24, 25, 26, 27, 28, 29, 30, 31, 32, 33,\n            ...\n            38, 39, 40, 41, 42, 43, 44, 45, 46, 47],\n           dtype='int64', length=720)] are in the [index]"

即使传入符合要求的pandas Series(而非数组),错误仍然存在。

核心代码片段

回测代码

metric, predictions = backtesting_forecaster(
                          forecaster         = forecaster,
                          y                  = data['Count of Visits'],
                          steps              = 24,
                          metric             = 'mean_absolute_error',
                          initial_train_size = len(data.loc[:end_validation]),
                          refit              = False,
                          verbose            = True,
                          show_progress      = True
                    )

数据划分与模型初始化

# 数据划分
data = data.loc['2023-02-01 00:00:00': '2023-06-30 23:00:00'].copy()
end_train = '30-04-2023 23:59'
end_validation = '31-05-2023 23:59'

# 模型初始化与训练
from skforecast.ForecasterAutoreg import ForecasterAutoreg
from sklearn.linear_model import Ridge

forecaster = ForecasterAutoreg(
             regressor     = Ridge(random_state=123),
             lags          = 24,
             transformer_y = StandardScaler()
         )
forecaster.fit(y=data.loc[:end_validation, 'Count of Visits'])

原因分析

报错根源是索引类型不匹配:

  • 传入backtesting_forecaster的y采用时间戳索引
  • 当refit=False时,模型基于预训练参数滚动预测,生成的predictions使用整数位置索引(从训练集长度开始递增)
  • 函数内部计算指标时,用预测结果的整数索引去匹配y的时间戳索引,因索引类型完全不匹配,触发KeyError。

解决方案

方法1:启用refit=True(推荐,若业务允许)

如果允许每次回测迭代重新拟合模型,将refit设为True。此时模型会在每个回测窗口重新训练,生成的预测结果会自动匹配原数据的时间索引:

metric, predictions = backtesting_forecaster(
                          forecaster         = forecaster,
                          y                  = data['Count of Visits'],
                          steps              = 24,
                          metric             = 'mean_absolute_error',
                          initial_train_size = len(data.loc[:end_validation]),
                          refit              = True,  # 修改此处
                          verbose            = True,
                          show_progress      = True
                    )

方法2:手动对齐索引(必须refit=False时)

若不能重新拟合模型,需手动修正预测结果的索引后再计算指标:

# 先获取预测结果,关闭自动指标计算
_, predictions = backtesting_forecaster(
                          forecaster         = forecaster,
                          y                  = data['Count of Visits'],
                          steps              = 24,
                          metric             = None,  # 不自动计算指标
                          initial_train_size = len(data.loc[:end_validation]),
                          refit              = False,
                          verbose            = True,
                          show_progress      = True
                    )

# 获取回测对应的真实值及其时间索引
true_values = data['Count of Visits'].iloc[len(data.loc[:end_validation]):]

# 将预测结果的索引替换为真实值的时间索引
predictions.index = true_values.index

# 手动计算指标
from sklearn.metrics import mean_absolute_error
metric = mean_absolute_error(true_values, predictions['pred'])

方法3:确保时间索引连续(前置检查)

若时间序列存在缺失值,可能导致索引逻辑混乱,先验证并修复:

# 检查索引是否单调递增且唯一
print(data.index.is_monotonic_increasing)
print(data.index.is_unique)

# 生成连续时间索引并重新对齐数据(假设是小时级频率)
full_index = pd.date_range(start=data.index.min(), end=data.index.max(), freq='H')
data = data.reindex(full_index)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 04:16:58