4. 机器学习预测方法:特征工程构建与模型调参

好,咱们进入正题。这一章我打算聊聊机器学习在负荷预测里的实战套路。说白了,就是怎么把一堆原始数据变成模型能看懂的特征,再让随机森林和XGBoost这两个老伙计帮我们把预测做准。

我个人习惯把特征工程放在模型前面讲。为什么?因为模型再牛,喂进去的是垃圾,吐出来的还是垃圾。我在项目里吃过这个亏,后来就学乖了。

4.1 特征工程:从原始数据到有效特征

特征工程,说白了就是给模型找“线索”。你想想看,负荷变化不是凭空来的,它跟时间、天气、历史负荷都有关系。我们要做的,就是把这三类线索挖出来。

4.1.1 时间特征

时间特征是最基础的。我一般会从时间戳里拆出下面这些:

  • 小时:0-23,反映日内用电规律。比如晚上8点是高峰,凌晨3点是低谷。
  • 星期几:0-6,区分工作日和周末。周一和周六的负荷曲线差别很大。
  • 月份:1-12,捕捉季节性变化。夏天开空调,冬天取暖,负荷完全两码事。
  • 是否节假日:0或1。节假日负荷通常比工作日低20%-30%。
  • 一年中的第几天:1-365,用来捕捉长期趋势。
我的小技巧: 对于“小时”这个特征,我建议做正弦-余弦编码。因为23点和0点其实很近,但直接当成数值就差远了。用sin/cos变换后,距离就对了。

4.1.2 气象特征

气象特征对负荷预测影响很大,尤其是温度。我在项目中遇到过,夏天温度每升高1℃,空调负荷可能增加5%-8%。

常用的气象特征包括:

  • 温度:当前温度、最高温、最低温
  • 湿度:影响体感温度,间接影响空调使用
  • 风速:大风天可能影响供暖或制冷需求
  • 降雨/降雪:0或1,恶劣天气会改变用电行为
  • 体感温度:综合温度和湿度的计算值,比单纯温度更准
注意: 气象数据要跟负荷数据在时间上对齐。我曾经因为气象站和负荷采集点的时间戳差了15分钟,导致模型精度掉了3个百分点。后来我专门写了个对齐脚本才解决。

4.1.3 历史负荷特征

历史负荷是预测当前负荷最重要的依据。我常用的做法是:

  • 前1小时负荷:短期惯性
  • 前24小时同时刻负荷:日周期性
  • 前168小时同时刻负荷:周周期性(7天前同一时刻)
  • 滑动平均:过去3小时、6小时的平均负荷,平滑噪声
  • 滑动标准差:反映负荷波动程度

嗯,这里要注意:历史负荷特征不能引入未来信息。比如你要预测t时刻的负荷,只能用t-1、t-24这些过去的数据,不能用t+1的。

4.2 随机森林回归实战

随机森林是个好用的模型。它由多棵决策树组成,每棵树都在数据子集和特征子集上训练,最后取平均。说白了就是“三个臭皮匠,顶个诸葛亮”。

下面是我常用的代码模板:

from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import GridSearchCV

# 初始化模型
rf = RandomForestRegressor(random_state=42)

# 参数网格
param_grid = {
    'n_estimators': [100, 200, 300],
    'max_depth': [10, 15, 20, None],
    'min_samples_split': [2, 5, 10],
    'min_samples_leaf': [1, 2, 4]
}

# 网格搜索
grid_search = GridSearchCV(
    rf, param_grid, 
    cv=5, 
    scoring='neg_mean_squared_error',
    n_jobs=-1
)

grid_search.fit(X_train, y_train)

# 最佳参数
print("最佳参数:", grid_search.best_params_)
调参心得: 我一般先调n_estimators,从100开始,看验证集误差是否收敛。如果200棵树后误差不再下降,就定在200。然后调max_depth,太深容易过拟合,我通常控制在15-20之间。

4.3 XGBoost模型调参与评估

XGBoost是梯度提升树的升级版。它比随机森林更准,但调参也更讲究。我在项目中试过,同样的数据,XGBoost比随机森林的RMSE低了8%左右。

XGBoost的核心参数:

参数 作用 推荐范围
n_estimators 树的数量 100-1000
learning_rate 学习率,控制每棵树的贡献 0.01-0.3
max_depth 树的最大深度 3-10
subsample 每棵树使用的样本比例 0.6-1.0
colsample_bytree 每棵树使用的特征比例 0.6-1.0
reg_alpha L1正则化 0-10
reg_lambda L2正则化 0-10

调参顺序我建议这样:

  1. 先定学习率和树的数量。学习率0.1,树的数量用早停法确定。
  2. 调max_depth和min_child_weight。深度从3开始试。
  3. 调subsample和colsample_bytree,防止过拟合。
  4. 最后调正则化参数reg_alpha和reg_lambda。
import xgboost as xgb

# 定义模型
xgb_model = xgb.XGBRegressor(
    n_estimators=500,
    learning_rate=0.1,
    max_depth=5,
    subsample=0.8,
    colsample_bytree=0.8,
    random_state=42
)

# 训练
xgb_model.fit(
    X_train, y_train,
    eval_set=[(X_val, y_val)],
    early_stopping_rounds=50,
    verbose=False
)

# 预测
y_pred = xgb_model.predict(X_test)
避坑指南: 我曾经在调XGBoost时,把n_estimators设到2000,learning_rate设到0.01,结果训练了3个小时还没收敛。后来我改成先粗调再细调,先用100棵树试参数范围,再逐步增加树的数量。这样效率高多了。

4.4 模型评估指标

评估模型好不好,不能光看一个指标。我一般用下面几个:

指标 公式 说明
MAE 平均绝对误差 直观反映预测偏差大小
RMSE 均方根误差 对大误差惩罚更大
MAPE 平均绝对百分比误差 反映相对误差,适合对比
决定系数 模型解释了多少方差

我个人习惯重点看RMSE和MAPE。RMSE能反映大偏差的情况——比如有没有出现某个时刻预测完全跑偏。MAPE则能看出整体精度,一般MAPE在5%以内就算不错了。

4.5 本章知识体系

下面这张图把本章的核心逻辑串起来了。从原始数据出发,经过特征工程,再到模型训练和评估,每一步都有坑也有技巧。

机器学习预测方法:特征工程与模型调参 原始数据 特征工程 时间特征 | 气象特征 | 历史负荷 模型训练 随机森林 | XGBoost 模型调参 模型评估 负荷预测结果 数据更新 → 重新训练 图:机器学习负荷预测流程

这张图里,我特别想强调左侧那条虚线——数据更新后要重新训练模型。我在项目里见过有人模型训完就不管了,结果半年后预测精度从5%掉到15%。负荷模式是会变的,模型也得跟着更新。

好了,这一章的内容就到这儿。特征工程、随机森林、XGBoost调参,这三块你吃透了,负荷预测的基本功就算打牢了。


公众号:蓝海资料掘金营,微信deep3321