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

为何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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 10:20:34