3. 金融数据预处理

在金融机器学习项目中,数据预处理往往占据整个项目60%以上的工作量。原始金融数据来自行情接口、财报数据库、新闻舆情、交易日志等多个异构源,天然存在字段错位、时间戳不齐、停牌缺失、涨跌停截断、复权口径不一致等问题。若跳过清洗直接建模,模型学到的往往是数据管道的噪声而非市场规律。本节围绕数据清洗、缺失值处理、异常值检测与标准化四条主线,给出可落地的工程方法。

一、核心原理:为什么金融数据必须专门预处理

金融时间序列与常规表格数据有四点本质差异。第一,非平稳性:均值与方差随时间漂移,直接标准化会引入未来信息。第二,低信噪比:日频收益率的信噪比通常低于0.05,异常值极易主导损失函数。第三,截面相关性:同一板块股票高度联动,缺失值不能简单按独立样本填充。第四,时间因果性:任何填充、标准化、异常修正都只能使用当前及历史信息,否则造成前视偏差(Look-ahead Bias)。理解这四点,才能判断每种预处理手段是否合规。

金融数据预处理四阶段流水线 ① 数据清洗 去重 / 对齐时间戳 复权口径统一 字段类型校正 ② 缺失值处理 前向填充 / 插值 截面中位数填充 缺失指示变量 ③ 异常值检测 MAD / 分位数截断 3σ 与滚动窗口 涨跌停标记 ④ 标准化 Z-Score / Robust 截面排序归一 滚动窗口拟合 时间因果约束:所有统计量仅使用 t 时刻及之前的数据拟合,禁止全样本 fit train 拟合 → valid 变换 → test 变换,滚动窗口逐日推进 输出:对齐后的特征矩阵 X(T×N×F)与标签 y,可直接进入特征工程与模型训练 关键校验:无未来函数、无重复索引、缺失率 < 5%、异常标记可追溯

二、方法流程:四步预处理标准作业程序

  1. 数据清洗:统一时间索引(交易日历对齐),去除重复行,校正价格复权口径(前复权用于回测,后复权用于长期统计),将字符串型数值转为 float,并记录每步清洗的丢弃行数。
  2. 缺失值处理:先区分随机缺失与结构性缺失。停牌导致的缺失应保留并加标记,而非填充;财务指标缺失可用行业中位数填充;行情价格缺失用前向填充(ffill)并限制最大填充天数。
  3. 异常值检测:对收益率使用滚动MAD(中位数绝对偏差)识别,对成交量使用分位数截断,对涨跌停日单独打标,避免把真实极端行情误删。
  4. 标准化:优先使用滚动窗口的RobustScaler(中位数与IQR),截面因子可使用排序百分位归一,确保量纲一致且不泄露未来信息。

三、案例场景:A股日频因子预处理

假设我们构建一个包含500只股票、2018—2023年日频数据的动量因子。原始数据存在停牌缺失、一字涨停无法成交、财报披露滞后等问题。下面给出关键代码片段:

import pandas as pd
import numpy as np

# 1. 清洗:对齐交易日历并去重
df = df.sort_index().loc[~df.index.duplicated(keep='last')]
df = df.reindex(trade_calendar)  # 补齐停牌日

# 2. 缺失值:价格前向填充,限制5天;财务用行业中位数
df['close'] = df.groupby('code')['close'].ffill(limit=5)
df['roe'] = df.groupby(['date','industry'])['roe'].transform(
    lambda x: x.fillna(x.median()))

# 3. 异常值:滚动MAD,窗口60日,阈值5倍
def mad_clip(s, window=60, n=5):
    med = s.rolling(window).median()
    mad = (s - med).abs().rolling(window).median()
    return s.clip(med - n*1.4826*mad, med + n*1.4826*mad)
df['ret'] = df.groupby('code')['ret'].transform(mad_clip)

# 4. 标准化:滚动RobustScaler,避免未来函数
from sklearn.preprocessing import RobustScaler
scaler = RobustScaler()
df['mom_z'] = df.groupby('code')['mom'].transform(
    lambda x: scaler.fit_transform(x.values.reshape(-1,1)).ravel())
实操建议:对每个因子保存一份缺失率与异常率日志,当某因子缺失率超过30%时应考虑弃用,而非强行填充。

四、误区与复盘

常见误区后果正确做法
全样本fit标准化器前视偏差,回测虚高滚动窗口或扩展窗口fit
用均值填充收益率抹平波动,低估风险前向填充或标记缺失
3σ一刀切删异常删除真实极端行情MAD+涨跌停标记
忽略停牌结构性缺失模型学到虚假信号保留并加停牌指示变量
截面与时序标准化混用因子暴露失真按因子类型选择标准化维度
复盘要点:预处理不是一次性动作,而应封装为可复现的Pipeline。每次数据更新后重新执行,并对比新旧特征分布,防止数据源口径变化导致模型失效。

掌握本节四条主线后,你已具备将原始金融数据转化为可建模特征矩阵的能力。下一步的关键是把这些预处理步骤固化为可测试、可回滚的代码模块,为后续特征工程与模型训练打下可靠基础。