4、多因子特征工程:因子构建与共线性处理

大家好,我是老K。今天咱们聊聊多因子模型里最磨人、也最有意思的一环——特征工程。说实话,我见过太多人把精力全花在模型调参上,结果因子质量一塌糊涂,模型跑出来就是个笑话。嗯,这一章咱们就把这块硬骨头啃下来。

4.1 因子构建:技术指标与宏观数据

因子构建说白了,就是把原始数据变成能预测未来走势的信号。我个人习惯把因子分成两类:技术指标和宏观数据。

4.1.1 技术指标因子

技术指标因子,就是基于价格、成交量这些高频数据算出来的。我刚开始做量化时,特别喜欢堆指标,RSI、MACD、布林带全往上怼。结果呢?过拟合得一塌糊涂。后来我学乖了——因子不在多,在精。

这里我列几个实战中比较靠谱的:

  • 动量因子:过去N天的收益率。N选多少?我一般用5、10、20、60天,覆盖短中长周期。
  • 波动率因子:过去N天收益率的标准差。注意,波动率有聚集效应,我习惯用对数收益率算。
  • 成交量因子:成交量变化率、成交量与均量的比值。量在价先,这个逻辑你想想看。
  • 反转因子:过去N天的累计收益率的负值。A股里短期反转效应挺明显的。

核心经验:技术指标因子要标准化处理。我一般用z-score,但要注意剔除极端值,不然一个涨停板就能把整个因子分布拉偏。

4.1.2 宏观数据因子

宏观数据这块,很多人觉得跟股票预测没关系。我在项目中遇到过,加入宏观因子后,模型的稳定性明显提升。尤其是做中长周期预测时,宏观因子能帮你抓住大方向。

常用的宏观因子包括:

  • 利率因子:国债收益率、shibor利率。利率上升,流动性收紧,股市承压。
  • 通胀因子:CPI、PPI。通胀过高,货币政策会收紧。
  • 经济景气因子:PMI、工业增加值。经济好,企业盈利好。
  • 货币供应因子:M2增速。水多了,资产价格自然涨。

小技巧:宏观数据发布频率低,我一般用插值法对齐到日频。别用前向填充,那会引入未来信息。用后向填充或者线性插值更靠谱。

4.2 特征相关性分析

因子建好了,下一步就是看它们之间有没有「串通」。相关性分析,说白了就是看看两个因子是不是在说同一件事。

我常用的方法就两种:

  1. 皮尔逊相关系数:衡量线性关系。取值范围[-1, 1]。绝对值大于0.7,我就认为相关性过高了。
  2. 斯皮尔曼秩相关系数:衡量单调关系。对异常值不敏感,我更喜欢用这个。

来看个代码示例:

import pandas as pd
import numpy as np
from scipy.stats import spearmanr

# 假设 factor_df 是因子数据,index是时间,columns是因子名
corr_matrix = factor_df.corr(method='spearman')

# 找出相关性大于0.7的因子对
high_corr_pairs = []
for i in range(len(corr_matrix.columns)):
    for j in range(i+1, len(corr_matrix.columns)):
        if abs(corr_matrix.iloc[i, j]) > 0.7:
            high_corr_pairs.append((corr_matrix.columns[i], 
                                    corr_matrix.columns[j], 
                                    corr_matrix.iloc[i, j]))

print(f"发现 {len(high_corr_pairs)} 对高相关因子")

注意:相关性高不代表因果关系。我曾经见过两个因子相关性0.9,结果一个是动量,一个是反转——完全相反的预测方向。所以,别只看数字,要理解因子的业务含义。

4.3 多重共线性处理(VIF)

相关性分析只能看两两关系。但实际问题中,一个因子可能被多个因子联合解释。这就是多重共线性。

VIF(方差膨胀因子)是检测多重共线性的标准工具。它的逻辑很简单:对每个因子,用其他所有因子做回归,看R²有多大。R²越高,VIF越大,说明这个因子越「多余」。

VIF的计算公式:

VIF = 1 / (1 - R²)

VIF大于10,一般认为存在严重的多重共线性。我个人习惯更严格——VIF大于5我就开始警惕了。

来看实战代码:

from statsmodels.stats.outliers_influence import variance_inflation_factor
from statsmodels.tools.tools import add_constant

def calculate_vif(df):
    """
    计算VIF,df是因子数据框
    """
    # 添加截距项
    X = add_constant(df)
    
    vif_data = pd.DataFrame()
    vif_data["feature"] = X.columns
    vif_data["VIF"] = [variance_inflation_factor(X.values, i) 
                       for i in range(X.shape[1])]
    
    # 去掉截距项
    vif_data = vif_data[vif_data['feature'] != 'const']
    
    return vif_data.sort_values('VIF', ascending=False)

# 使用示例
vif_result = calculate_vif(factor_df)
print(vif_result)

处理多重共线性的策略,我一般按这个顺序来:

  1. 删除高VIF因子:最简单粗暴。但要注意,别把有预测能力的因子删了。
  2. 因子合成:用PCA或者因子正交化,把相关因子合并成一个。我比较喜欢用PCA,但解释性会变差。
  3. 正则化:L1/L2正则化天然能处理共线性。Lasso(L1)甚至能自动做特征选择。

避坑指南:我曾经在某个项目中,VIF算出来全是无穷大。查了半天,发现是因子之间完全线性相关——有个因子是其他因子的线性组合。这种情况,直接删掉冗余因子就好。

4.4 本章知识体系

下面这张图,是我自己总结的多因子特征工程核心流程。你照着这个走,基本不会出大错。

多因子特征工程核心流程 原始数据 因子构建 技术指标因子 | 宏观数据因子 特征相关性分析 皮尔逊 | 斯皮尔曼 | 热力图 多重共线性处理(VIF) 删除 | 合成 | 正则化 关键指标 VIF > 10 → 严重 VIF > 5 → 警惕 |r| > 0.7 → 高相关 |r| > 0.5 → 中等 |r| < 0.3 → 弱相关 处理策略 1. 删除冗余因子 2. PCA因子合成 3. L1/L2正则化

嗯,这一章的内容就到这。因子构建和共线性处理,说白了就是「去粗取精」的过程。你花80%的时间把因子质量搞好了,模型自然就水到渠成。别急着上模型,先把数据收拾利索了。

专注资料整理