一、特征工程导论:为什么需要特征工程?
大家好,我是老蓝。今天咱们聊聊特征工程。
说实话,我见过太多人一上来就急着跑模型。数据丢进去,调个参,然后盯着回测曲线傻乐。结果呢?实盘一跑,直接翻车。为什么?因为因子挖掘的核心,从来不是模型有多花哨,而是你喂给模型的东西——特征,到底有没有价值。
特征工程,说白了就是把你手里的原始数据,变成能真正反映市场规律的“好特征”。我个人习惯把这件事放在整个流程的最前面,因为它决定了你因子的天花板。
1.1 什么是特征工程?
特征工程,就是从原始数据中提取、构造、选择有用特征的过程。在量化领域,原始数据可能是行情数据、财务数据、舆情数据等等。但这些数据不能直接用——太脏、太乱、太冗余。
举个例子。你拿到了一堆股票的历史价格数据。直接拿收盘价去预测未来收益?效果会很差。为什么?因为价格本身是随机游走的,没有预测能力。但如果你把价格转换成收益率、波动率、动量因子、相对强弱指标……这些才是真正有信息量的特征。
核心观点:特征工程不是锦上添花,而是雪中送炭。没有好的特征,再牛的模型也是白搭。
1.2 为什么特征工程如此重要?
我总结了三层原因,你听听看有没有道理。
- 数据质量决定模型上限——垃圾进,垃圾出。这是铁律。
- 特征维度决定信息密度——你构造的特征越多,越有可能捕捉到市场中的非线性规律。
- 特征稳定性决定因子寿命——很多因子回测漂亮,实盘就失效,就是因为特征本身不稳定。
我记得有一次,团队里一个小伙伴拿了一堆高频数据直接跑LSTM。回测夏普3.0,大家兴奋得不行。结果实盘一周,夏普直接变负。后来一查,发现他用的特征里有一个是“过去5分钟成交量变化率”,这个特征在回测期内刚好跟未来收益有虚假相关性,但实盘里相关性瞬间消失。这就是典型的特征工程没做好——没有做稳定性检验。
1.3 特征工程在因子挖掘中的核心地位
因子挖掘,本质上是一个“从数据中寻找规律”的过程。而特征工程,就是帮你把数据中的规律“翻译”成模型能理解的语言。
你想想看,一个因子通常由多个特征组合而成。比如一个经典的“动量因子”,它可能包含过去N天的收益率、过去N天的波动率、过去N天的成交量变化等等。这些特征的质量,直接决定了这个因子是否有效。
我个人的经验是:特征工程占整个因子挖掘工作量的60%以上。剩下的40%才是模型选择、参数调优、回测验证。很多人本末倒置,把时间花在调参上,结果特征一塌糊涂。
避坑指南:我曾经犯过一个错误——在特征工程上偷懒,直接用原始数据跑模型。结果模型拟合得很好,但泛化能力极差。后来我花了整整两周重新做特征工程,把数据清洗、特征构造、特征选择全部重来一遍,模型效果直接翻倍。从那以后,我再也不敢跳过特征工程这一步。
1.4 特征工程的核心流程
特征工程不是一锤子买卖,而是一个迭代的过程。我一般把它分成四个步骤:
- 数据清洗——处理缺失值、异常值、重复值。这是基础,但很多人做不好。
- 特征构造——从原始数据中衍生出新特征。比如从价格数据中构造技术指标、从财务数据中构造估值指标。
- 特征选择——从大量特征中挑出最有用的那些。避免维度灾难,也避免过拟合。
- 特征降维——用PCA、自编码器等方法,把高维特征压缩成低维表示。这一步在因子挖掘中尤其重要,因为金融数据往往噪声很大。
下面这张图,是我自己画的特征工程在因子挖掘中的位置。你可以看到,特征工程是连接原始数据和模型之间的桥梁。
1.5 一个简单的例子
光说不练假把式。咱们看一个最简单的例子——用Python构造一个“动量因子”的特征。
import pandas as pd
import numpy as np
# 假设我们有一个DataFrame,包含股票的历史收盘价
df = pd.DataFrame({
'date': pd.date_range('2023-01-01', periods=100, freq='D'),
'close': np.random.randn(100).cumsum() + 100
})
# 特征构造:过去5天的收益率
df['return_5d'] = df['close'].pct_change(5)
# 特征构造:过去20天的波动率
df['volatility_20d'] = df['close'].pct_change().rolling(20).std()
# 特征构造:相对强弱指标(RSI)
delta = df['close'].diff()
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
avg_gain = gain.rolling(14).mean()
avg_loss = loss.rolling(14).mean()
rs = avg_gain / avg_loss
df['rsi_14'] = 100 - (100 / (1 + rs))
# 特征选择:这里我们只保留这三个特征
features = df[['return_5d', 'volatility_20d', 'rsi_14']].dropna()
print(features.head())
你看,就这么几行代码,我们就从原始价格数据中构造出了三个有意义的特征。这三个特征组合起来,就是一个简单的动量因子。
注意:这个例子只是为了演示特征构造的过程。实际项目中,你需要构造几十甚至上百个特征,然后通过特征选择来筛选出最有效的那些。千万别拿三个特征就去跑实盘,那跟扔硬币没区别。
1.6 特征工程与降维的关系
特征工程做完之后,你往往会得到一大堆特征。这时候问题来了——特征太多,模型容易过拟合,计算效率也低。怎么办?降维。
降维是特征工程的下一个环节。它帮你把高维特征压缩成低维表示,同时尽量保留原始信息。常用的方法有PCA、t-SNE、自编码器等。这部分内容,我们会在后面的章节详细讲。
这里我只想说一句:特征工程和降维是孪生兄弟。特征工程负责“造”,降维负责“筛”。两者缺一不可。
1.7 本章小结
好了,咱们把这一章的核心内容捋一捋:
- 特征工程是把原始数据变成好特征的过程
- 它决定了因子挖掘的上限
- 核心流程包括:数据清洗、特征构造、特征选择、特征降维
- 特征工程和降维是相辅相成的
我个人觉得,特征工程是量化领域最容易被低估的技能。很多人觉得它“不够酷”,不如跑个深度学习模型有面子。但真正在市场上赚到钱的人,都明白一个道理:好特征比好模型更重要。
下一章,咱们会深入讲数据清洗的具体方法。嗯,到时候见。