3. 特征工程(下):波动率与收益率特征构建、资金流向与成交量特征、特征降维(PCA主成分分析)、特征重要性评估

好,咱们接着聊特征工程。上一节我们把基础的价格特征和基本面特征搞定了,这一节要动真格的了——波动率、收益率、资金流向,这些才是量化选股的灵魂。我个人习惯把这一节叫做「特征工程的深水区」,因为这里稍不注意,你的模型就会学到一堆噪音。

3.1 波动率与收益率特征构建

先说波动率。很多人以为波动率就是标准差,其实没那么简单。我在项目中遇到过一个问题:用简单标准差算出来的波动率,对极端行情反应太慢。后来我改用指数加权波动率(EWMA),效果好了不少。

核心思路:波动率要能反映近期市场情绪的变化,而不是平均主义。

具体怎么构建?我一般会做这几类:

  • 历史波动率:过去5日、20日、60日的收益率标准差
  • EWMA波动率:给近期数据更高权重,衰减因子λ通常取0.94
  • 日内波动率:用最高价/最低价估算,公式是 (high - low) / (high + low) * 2
  • 波动率变化率:今天的波动率相比昨天是变大了还是变小了

收益率特征呢?说白了就是看股票过去涨得怎么样。但别只算简单收益率,我建议做这些:

  1. 对数收益率:ln(P_t / P_{t-1}),比简单收益率更符合正态分布假设
  2. 累计收益率:过去5天、20天的累计涨跌幅
  3. 超额收益率:个股收益率减去大盘收益率,剔除市场系统性影响
  4. 收益率偏度:过去一段时间收益率的偏斜程度,判断涨跌不对称性

小技巧:构建收益率特征时,记得做「未来信息屏蔽」。我曾经犯过这个错——用当天的收盘价去算过去5天的收益率,结果模型在回测里表现完美,实盘一塌糊涂。嗯,血的教训。

3.2 资金流向与成交量特征

资金流向特征,说白了就是看「谁在买、谁在卖」。A股市场里,主力资金和大单资金的行为往往能预示短期走势。我一般会构建以下特征:

特征名称 计算方式 说明
主力净流入 大单买入额 - 大单卖出额 反映机构资金态度
资金强度 净流入额 / 成交额 归一化后的资金力度
大单占比 大单成交额 / 总成交额 判断是否由主力主导
资金集中度 前5大单净流入 / 总净流入 资金是否集中在少数机构

成交量特征呢?成交量是市场的「燃料」。没有成交量的上涨,说白了就是虚涨。我常用的成交量特征有:

  • 成交量变化率:今日成交量 / 过去5日均量 - 1
  • 量价配合度:当日涨跌幅与成交量变化的相关系数
  • 换手率:成交量 / 流通股本,反映股票活跃度
  • 成交量变异系数:成交量标准差 / 成交量均值,判断成交稳定性

避坑指南:我曾经在构建资金流向特征时,直接用分钟级数据算净流入,结果发现数据源里的大单定义不一致。有的数据商把50万以上算大单,有的把100万以上算大单。所以,用之前一定要确认数据口径。

3.3 特征降维(PCA主成分分析)

特征多了,问题就来了。你想想看,几十个特征之间肯定有相关性。比如波动率和振幅高度相关,资金净流入和成交量也高度相关。这时候PCA就派上用场了。

PCA说白了就是「把多个相关特征压缩成几个不相关的综合指标」。我一般这样用:

from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

# 标准化:PCA对尺度敏感,必须先标准化
scaler = StandardScaler()
features_scaled = scaler.fit_transform(features)

# PCA降维:保留95%的方差信息
pca = PCA(n_components=0.95)
features_pca = pca.fit_transform(features_scaled)

# 看看每个主成分的解释方差比
print(f"主成分数量: {pca.n_components_}")
print(f"解释方差比: {pca.explained_variance_ratio_}")

这里有个关键点:PCA后的特征失去了可解释性。第一个主成分可能是波动率、收益率、资金流向的某种线性组合,你很难说它具体代表什么。所以,如果你需要向老板解释模型逻辑,建议谨慎使用PCA。

我的经验:PCA适合用在聚类分析的前置步骤。先把50个特征降到10个主成分,然后用这10个主成分做聚类,效果往往比直接用原始特征好。因为PCA去掉了噪音,保留了核心结构。

3.4 特征重要性评估

特征建好了,降维也做了,接下来要问:哪些特征真正有用?特征重要性评估,说白了就是给每个特征打个分。

我常用的方法有三种:

  1. 基于树模型的特征重要性:用随机森林或XGBoost训练一个模型,直接输出特征重要性分数。优点是快,缺点是偏向于数值型特征。
  2. 相关系数法:计算每个特征与目标变量(比如未来收益率)的相关系数。简单直观,但只能捕捉线性关系。
  3. Permutation Importance:打乱某个特征的值,看模型效果下降多少。下降越多,特征越重要。这个方法最稳健,但计算量大。

举个例子,用随机森林看特征重要性:

from sklearn.ensemble import RandomForestRegressor

# 训练一个简单的随机森林
rf = RandomForestRegressor(n_estimators=100, random_state=42)
rf.fit(features, target)

# 获取特征重要性
importance = rf.feature_importances_
feature_names = features.columns

# 排序展示
sorted_idx = np.argsort(importance)[::-1]
for i in range(10):
    print(f"{feature_names[sorted_idx[i]]}: {importance[sorted_idx[i]]:.4f}")

注意:特征重要性高不代表因果关系。我曾经遇到一个特征「昨日涨停」重要性排第一,但仔细一想,这是因为涨停的股票第二天往往有惯性上涨,而不是这个特征本身有预测能力。所以,特征重要性要结合业务逻辑去理解。

最后,我建议把特征重要性做成可视化图表,一目了然。用matplotlib画个水平条形图,把最重要的10个特征标出来,方便跟团队沟通。

特征工程核心流程 原始数据 特征构建 波动率/收益率 资金流向/成交量 PCA降维 保留95%方差 特征 重要性 评估 特征工程不是一次性的,需要反复迭代 迭代优化 关键要点: 1. 波动率用EWMA比简单标准差更灵敏 2. 资金流向特征要注意数据口径一致性 3. PCA降维后特征失去可解释性 4. 特征重要性要结合业务逻辑判断

好了,特征工程的核心内容就这些。从波动率到资金流向,从PCA降维到特征重要性评估,每一步都有坑,但也都有对应的解法。我个人觉得,特征工程做得好不好,直接决定了模型的天花板。算法可以调参,但特征不行就是不行。


专注资料整理