问题描述
请问大家,因子数据的标准化、去极值、补空值、中性化有没有先后顺序,为什么?
解决方案
在量化交易的多因子模型构建中,因子数据的处理(去极值、补空值、标准化、中性化)是有严格的先后顺序的。不合理的顺序会导致统计指标失真,进而影响因子的有效性和模型的表现。
业界公认的标准处理顺序通常为:去极值 -> 补空值 -> 标准化 -> 中性化。(注:有时中性化后会再进行一次标准化)。
以下是详细的顺序解析及背后的统计学原因:
第一步:去极值 (Winsorize)
为什么第一步做?
金融数据中常存在极端异常值(如由于数据错误或极端市场事件导致)。如果先做标准化或补空值,这些极端值会严重拉偏整体的均值 (Mean) 和 标准差 (Standard Deviation)。因此,必须首先将极端值拉回合理边界(如使用MAD中位数去极值法或3倍标准差法)。
JoinQuant API: winsorize(data) 或 winsorize_med(data)
第二步:补空值 (Imputation / Fillna)
为什么第二步做?
在去除了极端值的干扰后,整体数据的均值和中位数变得更加稳健和可靠。此时,使用行业均值、整体均值或中位数来填补缺失值(NaN),填补的数据才会更加贴近真实分布,不会被异常值带偏。
第三步:标准化 (Standardize / Z-Score)
为什么第三步做?
标准化(通常是Z-Score标准化:(x - mean) / std)依赖于全样本的均值和标准差。只有在去极值(保证均值/标准差不被扭曲)和补空值(保证样本量完整,不丢失信息)之后进行标准化,才能得到准确的、均值为0、标准差为1的无量纲数据。标准化使得不同量纲的因子可以放在一起比较或相加。
JoinQuant API: standardlize(data)
第四步:中性化 (Neutralize)
为什么最后做?
中性化通常是通过横截面线性回归(OLS)剔除行业(Industry)和市值(Market Cap)等风格因子的影响,取回归的残差作为新的因子值。线性回归对数据的量纲和异常值非常敏感:
- 如果不先去极值,回归线会被极端值严重带偏。
- 如果不先标准化,不同因子的回归系数缺乏可比性,且可能导致矩阵求解时的数值不稳定。
因此,中性化必须在去极值和标准化之后进行。
JoinQuant API:neutralize(data, how=['jq_l1', 'market_cap'])
JoinQuant 平台代码示例
在 JoinQuant 平台中,官方提供了便捷的因子处理 API。值得注意的是,JoinQuant 的 neutralize 函数内置了 fillna 参数,可以在中性化的同时进行行业均值填补。
标准处理流程代码示例:
import pandas as pd
import numpy as np
from jqfactor import winsorize_med, standardlize, neutralize
# 假设 data 是一个 DataFrame,index 为股票代码,包含某因子的原始数据
# data = get_factor_values(...)['factor_name']
# 1. 去极值:使用中位数去极值法 (MAD)
data_win = winsorize_med(data, scale=3, inclusive=True, inf2nan=True, axis=0)
# 2. 标准化:Z-Score 标准化
data_std = standardlize(data_win, inf2nan=True, axis=0)
# 3. 补空值与中性化:剔除市值和行业影响,并用行业均值填充缺失值
# 注意:JoinQuant 的 neutralize 函数支持通过 fillna 参数直接进行缺失值填充
data_neu = neutralize(data_std,
how=['jq_l1', 'market_cap'],
date='2023-10-10',
axis=0,
fillna='jq_l1') # 使用聚宽一级行业均值填充缺失值
# 此时的 data_neu 即为处理完毕,可用于打分或回归的纯净因子数据
总结: 严格遵循 去极值 -> 补空值 -> 标准化 -> 中性化 的顺序,是保证量化多因子模型稳健性的基础。