这篇讲解因子预处理的三个核心步骤——去极值(Winsorize)、标准化(Standardize)、中性化(Neutralize)。如果你发现自己的因子 IC 很高但回测收益很差,通常是预处理出了问题。
导言
在金融数据里,极值、数据量纲差异、行业偏差是最常见的三类”脏数据”问题:
- 极值:某只股票某天换手率突然暴增 100 倍(新股上市、乌龙指),如果不处理,它会主导整个因子值。
- 量纲差异:市值(百万
万亿)和股息率(0%10%)的数值范围差了几个数量级,直接拿来分组会导致因子被量纲大的变量绑架。 - 行业偏差:银行股的市净率和科技股的市净率不在同一个尺度上,直接比较没有意义。
preprocess_factor 把这三步打包成了一行代码,但理解每一步在做什么,有助于你在遇到问题时有针对性地调整。
一、去极值(Winsorize)
为什么需要去极值
金融数据里的极端值(outlier)来源广泛:财务报表更正、股票简称变更、数据采集错误、真实的极端事件。去极值的目的是把超出合理范围的数值裁剪到某个分位点,防止极端值主导因子。
三种去极值方法
1 | from betalens.factor.preprocessing import preprocess_factor, winsorize_factor |
通过 preprocess_factor 一键完成
1 | from betalens.factor.preprocessing import preprocess_factor |
preprocess_factor 会**逐截面(每天)**做去极值,确保不泄露未来数据。
二、标准化(Standardize)
为什么需要标准化
不同因子的数值范围差异巨大:市值从几百万到几万亿,换手率从 0 到 100+,股息率从 0 到 20+。如果不标准化,在多因子模型里量纲大的因子权重会天然偏大。
三种标准化方法
1 | from betalens.factor.preprocessing import standardize_factor |
学术研究里常用 Rank 标准化,因为它不假设因子分布形态,对极端值也更稳健。
在 preprocess_factor 中一键完成
1 | cleaned = preprocess_factor( |
三、中性化(Neutralize)
为什么需要中性化
假设你有一个”高ROE → 股价上涨”的因子逻辑。但事实是:大市值股票的 ROE 通常更稳定,小市值股票的 ROE 波动更大。如果不做中性化,你的因子本质上可能只是在做”小市值暴露”——不是 ROE 的能力,而是市值因子的代理。
中性化就是把目标因子对其他因子(如市值、行业)做 OLS 回归,取残差,让你只保留”不被其他因素解释”的纯粹部分。
行业中性化
1 | cleaned = preprocess_factor( |
背后逻辑:
1 | # 简化版等效代码 |
行业中性化自动做 PIT——框架会在数据库里查每只股票在调仓日属于哪个行业,保证不用未来行业变更信息。
市值中性化
市值中性化需要准备 log 市值列:
1 | # 先在 raw 数据里加上 log 市值列 |
组合中性化
1 | from betalens.factor.preprocessing import neutralize_factor_by_factor |
完整预处理流水线
1 | from betalens.factor.preprocessing import preprocess_factor |
开发者侧:逐截面处理的实现
从源码角度,preprocess_factor 对每个 input_ts(调仓日)做独立处理,这是保证”不泄露未来数据”的关键:
1 | def preprocess_factor(raw, metric, ...): |
重要:如果你的自定义因子脚本在调用 preprocess_factor 之前做了跨截面汇总(比如算某只股票的 20 日均值),就可能引入未来数据泄露。永远在 preprocess_factor 之后再做聚合,或者用 betalens.factor.factor 提供的滚动窗口函数。
常见错误
1. 去极值参数设反了
1 | # 错:lower > upper 会报错 |
2. 行业中性化但 raw 里没有行业数据
1 | # 报错或行业全是 NaN |
3. 市值中性化但没有 log 市值列
1 | # 报错:找不到 mktcap_metric 列 |
4. 多因子中性化顺序不对
正确的顺序是:先去极值 → 再标准化 → 最后中性化。如果先中性化再去极值/标准化,中性化的效果会被后续步骤破坏。
延伸阅读
- Betalens 新手系列 · 09:因子分组语义三角形——分组 API 详解。
- Betalens 新手系列 · 11:因子画像——用 profiling 检查预处理效果。
- Betalens 新手系列 · 12:参数扫描与滚动窗口——如何扫描最优预处理参数。
docs/guide/factor.rst——官方因子文档。