第四章 特征工程基础:如何从原始数据中提取有效特征

大家好,我是老张。在风电功率预测这个行当摸爬滚打了快十年,我越来越觉得——特征工程做得好,模型就成功了一半。这话一点不夸张。

你想想看,原始数据里那些风速、温度、湿度,直接扔进模型,效果往往很一般。为什么?因为模型看不懂这些数字背后的规律。我们需要帮它一把,把隐藏的信息挖出来。这就是特征工程要做的事。

核心观点:特征工程不是锦上添花,而是雪中送炭。好的特征能让简单模型跑出复杂效果,坏的特征能让深度学习模型原地踏步。

4.1 滑动平均:把噪声滤掉,趋势露出来

先说滑动平均。这玩意儿说白了就是「取一段时间的平均值」。比如你有一分钟一条的风速数据,但风机叶片受湍流影响,数据跳得厉害。直接拿原始数据去预测,模型会被噪声带偏。

我习惯用滑动平均来平滑数据。举个例子:

import pandas as pd

# 假设df是原始数据,风速列叫'wind_speed'
# 计算过去10分钟的滑动平均
df['ws_ma_10'] = df['wind_speed'].rolling(window=10).mean()

# 也可以试试30分钟窗口
df['ws_ma_30'] = df['wind_speed'].rolling(window=30).mean()

这里有个坑,我踩过好几次。窗口大小怎么选?太小了平滑效果差,太大了会把真实变化也抹掉。我个人经验是:先看数据的时间尺度。如果预测目标是15分钟后的功率,窗口选10-20分钟比较合适。如果是小时级预测,窗口可以拉到1-2小时。

小技巧:别只用一个窗口。试试多个窗口(比如5分钟、15分钟、30分钟),让模型自己去选哪个有用。这叫「多尺度特征」,效果往往比单个窗口好。

4.2 差分:让非平稳数据变平稳

风电数据有个特点——它不平稳。什么意思?就是均值、方差会随时间变化。比如白天风速大,晚上风速小。这种趋势会让模型学偏。

差分就是解决这个问题的。它计算的是「当前值减去上一个值」,说白了就是看变化量,而不是绝对值。

# 一阶差分:当前风速减去上一分钟风速
df['ws_diff_1'] = df['wind_speed'].diff(1)

# 也可以试试间隔5分钟的差分
df['ws_diff_5'] = df['wind_speed'].diff(5)

我记得有一次做短期预测,原始风速数据直接输入模型,误差大得离谱。后来加了差分特征,误差直接降了15%。为什么会这样?因为模型终于学会了「风速在变大还是变小」,而不是死记硬背「风速是多少」。

注意:差分会丢失数据量。一阶差分少一行,二阶差分少两行。如果你的数据本来就少,要谨慎使用。另外,差分后的数据如果出现异常大的值,可能是传感器跳变,记得先做异常值处理。

4.3 时间特征:把时间变成模型能懂的数字

时间本身不是数字,但模型只认数字。所以我们需要把时间「翻译」成特征。比如:

  • 小时:0-23,表示一天中的时刻
  • 星期几:0-6,表示一周中的位置
  • 月份:1-12,表示季节信息
  • 是否节假日:0或1,节假日用电模式不同

但这里有个细节——时间特征是循环的。23点和0点其实只差1小时,但数值上差了23。直接扔给模型,它会觉得这两个时间点「差很远」。这不对。

我建议用正弦余弦变换来处理循环特征:

import numpy as np

# 小时特征的正弦余弦编码
df['hour_sin'] = np.sin(2 * np.pi * df['hour'] / 24)
df['hour_cos'] = np.cos(2 * np.pi * df['hour'] / 24)

# 月份同理
df['month_sin'] = np.sin(2 * np.pi * df['month'] / 12)
df['month_cos'] = np.cos(2 * np.pi * df['month'] / 12)

这样处理后,23点和0点在二维空间里是相邻的,模型就能理解「它们其实很近」。这个技巧我在多个项目里用过,效果很稳。

4.4 特征组合:1+1 > 2

单个特征有时候不够用。比如风速和风向单独看,信息有限。但把它们组合起来——比如计算「风速在风向方向上的分量」——就能反映风到底往哪个方向吹,这对功率预测很关键。

常见的组合方式:

  • 风速 × 风向分量:反映有效风速
  • 温度 × 湿度:反映空气密度(影响发电效率)
  • 滑动平均 × 差分:既看趋势又看变化速度

我的习惯:先做单特征分析,看看每个特征和目标的相关性。然后挑几个相关性高的,做两两组合。别一上来就搞几十个组合,容易过拟合。

4.5 特征选择:别什么都往里塞

特征不是越多越好。我见过有人搞了200多个特征,模型训练慢得要命,效果还不好。这叫「维度灾难」。

怎么选?我常用的方法:

  1. 相关性分析:计算每个特征和目标变量的相关系数,去掉相关性低的
  2. 特征重要性:用随机森林或XGBoost跑一次,看模型认为哪些特征重要
  3. 业务常识:有些特征虽然统计上相关,但物理上说不通,果断去掉

我曾经在一个项目里,用相关性分析筛掉了30%的特征,模型速度提升了40%,精度反而没降。嗯,这就是「少即是多」的道理。

4.6 本章知识体系

下面这张图总结了特征工程的完整流程,我画了很久,希望能帮你理清思路:

特征工程知识体系 原始数据 滑动平均 平滑噪声,提取趋势 差分 处理非平稳数据 时间特征 正弦余弦编码 特征组合 1+1 > 2 特征选择(相关性 + 重要性 + 业务常识) 最终特征集 输入模型训练

这张图展示了特征工程的完整链路:从原始数据出发,经过滑动平均、差分、时间特征、特征组合四个核心步骤,再通过特征选择筛选出最有用的部分,最终输入模型。每一步都有它的作用,缺一不可。

4.7 避坑指南

最后,分享几个我踩过的坑:

  • 不要用未来数据做特征:比如用t+1时刻的数据预测t时刻,这叫「数据泄露」。我见过有人犯这个错,模型在测试集上表现完美,一上线就崩。
  • 训练集和测试集要分开做特征:滑动平均、差分这些操作,要在训练集和测试集上分别计算,不能混在一起。
  • 特征标准化别忘了:不同特征的量级差异很大(风速0-30,温度-10-40),不做标准化,模型会偏向数值大的特征。

一句话总结:特征工程不是炫技,而是理解数据、提炼信息的过程。多花时间在特征上,模型会给你回报。


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