4. 因子标准化:让不同量纲的数据站在同一起跑线
做多因子模型,最头疼的问题之一就是——因子量纲不统一。
你想想看,市盈率可能是十几倍,换手率是百分之几,市值是几百亿。这些数字放在一起,根本没法直接比较。我刚开始做因子研究时,就吃过这个亏。把原始数据直接扔进模型,结果市值因子一家独大,其他因子全被淹没了。
所以,标准化是必须的。今天聊三种主流方法:Z-score、MAD、排名标准化。每种都有它的脾气。
核心观点:标准化不是为了标准化而标准化,而是为了让因子之间的比较有意义,同时保留尽可能多的信息。
4.1 Z-score标准化:最经典,也最脆弱
Z-score的原理很简单:
# Z-score标准化
z = (x - mean) / std
把每个值减去均值,再除以标准差。结果就是均值为0,标准差为1的分布。
适用场景:
- 因子近似正态分布时
- 数据没有极端异常值
- 需要保留因子间的相对距离信息
我在项目中遇到过一个问题:某次用Z-score处理换手率因子,结果发现有个股票因为某天异常放量,Z-score直接飙到15。整个因子分布被拉偏了。嗯,这就是Z-score的软肋——它对异常值极其敏感。
避坑指南:我曾经因为没做异常值处理直接Z-score,导致模型回测结果虚高。后来发现,那个异常值在实盘中根本不会出现。所以,用Z-score前,务必先做缩尾或截尾处理。
4.2 MAD法:比Z-score更稳健
MAD,全称是Median Absolute Deviation(中位数绝对偏差)。它用中位数代替均值,用MAD代替标准差。
# MAD标准化
median_val = np.median(x)
mad = np.median(np.abs(x - median_val))
z_mad = (x - median_val) / (1.4826 * mad)
为什么乘以1.4826?为了让MAD在正态分布下与标准差保持一致。说白了,就是个校准系数。
MAD的优势在哪?
- 对异常值不敏感——中位数比均值稳健得多
- 保留了因子的大致分布形态
- 适合金融数据这种经常有厚尾分布的场景
我个人习惯在因子初筛阶段用MAD。因为金融数据里,异常值往往不是错误,而是极端事件。MAD能把这些极端值保留下来,但又不会让它们过度影响整体分布。
小技巧:如果你发现MAD标准化后的因子仍然有大量值超过±3,说明这个因子的分布确实很肥尾。这时候可以考虑用排名标准化。
4.3 排名标准化:简单粗暴,但有效
排名标准化,就是把因子值转换成排名,再映射到某个区间。最常见的是映射到[0,1]或[-1,1]。
# 排名标准化(映射到0~1)
rank = x.rank()
rank_norm = (rank - 1) / (len(rank) - 1)
# 或者映射到-1~1
rank_norm_2 = 2 * rank_norm - 1
什么时候用排名标准化?
- 因子分布严重偏态时
- 你只关心股票的相对排序,不关心具体数值
- 因子存在大量异常值,且无法有效处理
你想想看,排名标准化本质上丢弃了因子值之间的距离信息。比如,排名第1和第2的股票,实际因子值可能差很多,也可能只差一点点。但在排名标准化后,它们之间的差距被固定了。
这既是优点也是缺点。优点是稳健,缺点是信息损失。
我的经验:做截面回归时,我倾向于用Z-score或MAD。做分组回测时,排名标准化反而更好用。因为分组只看相对顺序,不看具体数值。
4.4 三种方法的对比
| 方法 | 对异常值敏感度 | 信息保留程度 | 适用分布 | 典型场景 |
|---|---|---|---|---|
| Z-score | 高 | 高(保留距离信息) | 近似正态 | 截面回归、因子合成 |
| MAD | 低 | 中高(保留距离,但更稳健) | 厚尾、偏态 | 金融因子初筛、异常值较多的数据 |
| 排名标准化 | 极低 | 低(只保留排序信息) | 任意分布 | 分组回测、因子组合构建 |
4.5 我的选择策略
说实话,没有万能的方法。我一般按这个逻辑来选:
- 先看因子分布——画个直方图,看看有没有异常值
- 异常值少且分布对称——用Z-score,简单高效
- 异常值多但不想丢弃——用MAD,保留信息的同时控制影响
- 异常值多且分布严重偏态——用排名标准化,稳健第一
- 做分组回测——直接上排名标准化,省心
一个小建议:同一个因子在不同时间截面上的分布可能变化很大。我习惯在每个截面期都重新做标准化,而不是用全局参数。这样能更好地捕捉市场结构的变化。
4.6 本章知识体系
下面这张图总结了三种标准化方法的核心逻辑和选择路径:
最后说一句:标准化不是终点,而是起点。真正重要的是,你选择的标准化方法能不能让因子在后续的模型中发挥应有的作用。多试试,找到适合你数据的那一款。
公众号:蓝海数据掘金营,微信 deep3321