3. 数据预处理
在机器学习因子压缩与特征表示任务中,原始因子数据往往来自多个数据源、多个频率、多个资产维度,直接送入模型几乎必然导致训练不稳定、因子暴露失真甚至未来函数泄漏。数据预处理不是“清洗一下脏数据”这么简单,它决定了后续因子压缩能否保留有效信息、特征表示是否具备可解释性。本节围绕缺失值处理、标准化、异常值检测、时序对齐与因子数据清洗,给出一条可落地的实战流程。
核心原理:预处理是在保护因子的信息结构
因子数据通常具有横截面与时序双重结构。缺失值、异常值和频率错位会破坏这种结构:缺失值让协方差矩阵出现空洞,异常值让均值和方差被极端点主导,时序错位则会把未来信息混入当前特征。预处理的目标不是让数据“看起来干净”,而是让因子在压缩前保持可比、可对齐、可解释。
一个关键原则是:先对齐时间轴,再处理缺失与异常,最后做标准化。如果先标准化再对齐,不同时间窗口的统计量会互相污染;如果先异常值检测再对齐,频率错位会导致异常点被错误平滑。正确的顺序能避免大部分隐性错误。
方法流程:五步实战流水线
- 时序对齐:将所有因子统一到目标频率(如日频)。低频因子向前填充时需注意“发布滞后”,避免把未来才公布的数据提前使用。高频因子降频时,优先使用收盘值或区间统计量,而不是简单取最后一个点。
- 缺失值处理:先区分“随机缺失”和“结构性缺失”。随机缺失可用截面中位数或时序前值填充;结构性缺失(如某资产长期无数据)应标记缺失指示变量,而不是强行填充。
- 异常值检测:对每个截面使用 MAD(中位数绝对偏差)或分位数截断。MAD 比标准差更稳健,适合因子分布厚尾的场景。
- 标准化:截面 Z-score 是常用做法,但需在训练窗口内计算均值和标准差,再应用到验证与测试集。对于厚尾因子,可改用稳健标准化。
- 因子清洗:去除极值、行业中性化、市值中性化,最终输出对齐后的特征矩阵。
实战参数建议:MAD 截断阈值常用 3~5 倍;分位数截断常用 1% 与 99%;标准化窗口建议至少 60 个交易日;缺失率超过 30% 的因子应优先考虑剔除或降权。
案例/场景:多源因子对齐与清洗
假设我们有三类因子:日频量价因子、周频财务因子、月频宏观因子。目标是在日频上构建特征矩阵。周频财务因子存在发布滞后,不能直接向前填充到发布日之前;月频宏观因子需按公布日期对齐,而不是按自然月首日对齐。
import pandas as pd
import numpy as np
# 1. 时序对齐:低频因子按发布日 reindex 到日频,再前向填充
daily_index = pd.date_range("2023-01-01", "2023-12-31", freq="B")
weekly_factor = weekly_factor.reindex(daily_index, method="ffill", limit=5)
macro_factor = macro_factor.reindex(daily_index, method="ffill", limit=20)
# 2. 缺失值处理:截面中位数填充 + 缺失指示
factor_df["value"] = factor_df.groupby("date")["value"].transform(
lambda s: s.fillna(s.median())
)
factor_df["value_missing"] = factor_df["value"].isna().astype(int)
# 3. 异常值检测:MAD 截断
def mad_clip(s, n=5):
med = s.median()
mad = (s - med).abs().median()
if mad == 0:
return s
return s.clip(med - n * 1.4826 * mad, med + n * 1.4826 * mad)
factor_df["value"] = factor_df.groupby("date")["value"].transform(mad_clip)
# 4. 标准化:训练窗口统计量
train_mean = factor_df.loc[train_mask, "value"].mean()
train_std = factor_df.loc[train_mask, "value"].std()
factor_df["value_z"] = (factor_df["value"] - train_mean) / train_std
这段代码体现了三个关键点:对齐时限制前向填充长度,避免长期无更新数据被无限延续;缺失指示变量保留缺失模式;标准化统计量只来自训练窗口,防止未来信息泄漏。
误区与复盘
| 常见误区 | 后果 | 修正做法 |
|---|---|---|
| 先标准化再时序对齐 | 统计量被不同频率污染,因子暴露失真 | 先对齐,再缺失与异常,最后标准化 |
| 用全样本均值方差标准化 | 未来函数泄漏,回测虚高 | 仅用训练窗口统计量,推理阶段复用 |
| 异常值直接删除 | 丢失有效极端信号,因子方向被削弱 | 优先截断而非删除,保留方向信息 |
| 低频因子按自然月首日对齐 | 提前使用未公布数据 | 按实际发布日对齐,设置发布滞后 |
| 缺失值全部均值填充 | 掩盖结构性缺失,引入偏差 | 区分缺失类型,增加缺失指示变量 |
复盘要点:预处理流水线必须可复现。每一步的填充值、截断阈值、标准化均值与标准差都应保存为配置文件或模型附件。训练与推理使用同一套参数,是因子压缩模型上线后不“变脸”的前提。
完成本节流程后,你将得到一份时间对齐、缺失可控、异常受控、量纲统一的因子特征矩阵。它既是后续因子压缩的输入,也是特征表示学习能否稳定收敛的基础。把预处理当作模型的一部分来设计,而不是当作一次性脚本,才能真正提升因子压缩的实战效果。