为何Random Forest Regressor对2023年时间序列输出单一预测值?
问题描述
我使用Random Forest Regressor拟合了x_train(时间序列,类型为pandas.core.indexes.datetimes.DatetimeIndex)和y_train,对训练集的预测效果出色,代码如下:
from sklearn.ensemble import RandomForestRegressor regressor=RandomForestRegressor(n_estimators=25) regressor.fit(x.values.reshape(-1,1),y.reshape(-1,1)) # type(x)= DatetimeIndex pred4=regressor.predict(x.values.reshape(-1,1))
随后我生成了2023年的时间序列(类型为pandas.core.series.Series)并进行预测,代码如下:
year = 2023 x_23=pd.Series(pd.date_range(start=f'{year}-01-01', end=f'{year}-12-31 23:00:00', freq='H')) pred5=regressor.predict(x_23.values.reshape(-1,1))
但预测结果在2023年全年均为相同值(预测图显示:真实值、2022年前的预测值,以及2023年的预测值),请问这是什么原因?
原因分析与解决方案
核心原因:原始时间戳特征的分布溢出
Random Forest是基于树的模型,当输入的特征值超出训练集该特征的最大取值范围时,所有决策树都会将这类样本导向最右侧的叶子节点,该节点的输出是训练集中最大特征值对应样本的平均预测值(回归任务)。
你直接将datetime的原始数值形式(本质是纪元以来的毫秒/纳秒数)作为唯一特征,而训练集的时间范围必然早于2023年,导致2023年的所有时间戳都远大于训练集的最大时间戳。此时所有树都会把这些样本分到同一个叶子节点,最终输出固定值。
验证方式
执行以下代码确认特征分布的溢出:
print("训练集最大时间:", x.max()) print("2023年最小时间:", x_23.min())
会看到x_23.min()显著大于x.max(),验证上述结论。
解决方案:构造具有周期性的时间特征
放弃使用原始时间戳,转而提取时间序列的周期性、趋势性特征,让训练集和测试集的特征分布存在重叠,示例代码如下:
import numpy as np import pandas as pd from sklearn.ensemble import RandomForestRegressor # 定义时间特征构造函数 def create_time_features(df): df = df.copy() df['hour'] = df.index.hour df['dayofweek'] = df.index.dayofweek df['month'] = df.index.month df['dayofyear'] = df.index.dayofyear # 小时周期的正弦/余弦变换,捕捉周期性 df['hour_sin'] = np.sin(2 * np.pi * df['hour']/24) df['hour_cos'] = np.cos(2 * np.pi * df['hour']/24) return df # 处理训练集 train_df = pd.DataFrame({'y': y_train}, index=x) train_df = create_time_features(train_df) X_train = train_df.drop('y', axis=1) # 训练模型 regressor = RandomForestRegressor(n_estimators=25) regressor.fit(X_train, y_train) # 处理2023年测试集 x_23 = pd.date_range(start='2023-01-01', end='2023-12-31 23:00:00', freq='H') test_df = pd.DataFrame(index=x_23) test_df = create_time_features(test_df) X_test = test_df # 预测 pred5 = regressor.predict(X_test)
这类特征(如小时0-23、星期0-6)在训练集和测试集有一致的分布范围,模型能学习到时间序列的周期性模式,避免预测结果固定。
内容的提问来源于stack exchange,提问作者python2021
相关产品推荐
相关产品推荐

