3. 单变量变换:对数变换、Box-Cox变换、标准化与归一化
单变量变换是因子研究中最基础也最常用的变量衍生手段。原始因子数据往往存在偏态分布、量纲不统一或异常值集中等问题,直接用于建模会导致模型对极端值敏感、因子载荷不稳定。本节系统讲解四种核心变换方法:对数变换、Box-Cox变换、标准化与归一化,并给出量化场景下的选择建议。
核心观点:变换的目标不是“让数据变漂亮”,而是让因子分布更接近建模假设(正态性、同方差性、无量纲可比性),从而提升因子与收益之间的线性相关性。
3.1 对数变换
对数变换是处理右偏分布(长尾在右侧)最常用的方法,尤其适用于市值、成交量、波动率等严格为正的金融因子。
| 属性 | 说明 |
|---|---|
| 公式 | x' = ln(x + c),其中 c 为偏移常数(通常取 1 或 min(x) 的绝对值) |
| 适用场景 | 市值因子、成交额因子、波动率因子、估值类因子(PE/PB) |
| 效果 | 压缩大值、拉伸小值,使分布接近正态;降低异方差性 |
| 注意事项 | 输入必须为正;零值或负值需先加偏移;变换后需重新检查异常值 |
import numpy as np
def log_transform(x, c=1.0):
"""对数变换,自动处理非正数"""
x = np.asarray(x, dtype=float)
min_val = x.min()
if min_val <= 0:
c = abs(min_val) + 1.0
return np.log(x + c)
实战经验:对市值因子做对数变换后,截面回归的 R² 通常提升 5-15%。但注意:对数变换不会改变因子与收益之间的单调关系,只会改变关系的线性程度。
3.2 Box-Cox变换
Box-Cox变换是对数变换的推广,通过一个可学习的参数 λ 自动选择最优的幂变换形式,使变换后的数据最接近正态分布。
| 属性 | 说明 |
|---|---|
| 公式 | x' = (x^λ - 1) / λ 当 λ ≠ 0;x' = ln(x) 当 λ = 0 |
| λ 范围 | 通常搜索 [-2, 2] 区间,步长 0.1 或 0.01 |
| 优化目标 | 最大化对数似然函数,或最小化变换后的偏度 |
| 适用场景 | 偏态严重的连续因子;需要自动化处理大量因子时 |
| 局限性 | 要求输入严格为正;λ 估计对异常值敏感;因子含义在变换后难以解释 |
from scipy import stats
def boxcox_transform(x):
"""Box-Cox变换,自动估计最优lambda"""
x = np.asarray(x, dtype=float)
# 确保所有值为正
if x.min() <= 0:
x = x - x.min() + 1e-6
transformed, lam = stats.boxcox(x)
return transformed, lam
注意:Box-Cox变换在因子研究中的使用频率远低于对数变换,原因在于:(1) λ 估计在月度截面数据上不稳定;(2) 不同截面期估计的 λ 不一致,导致因子含义随时间变化;(3) 回测中需用历史 λ 变换未来数据,存在前瞻偏差风险。
3.3 标准化与归一化
标准化和归一化是消除量纲影响的两类方法,但目标不同:标准化保留分布形状,归一化改变分布范围。
| 方法 | 公式 | 输出范围 | 对分布形状的影响 | 适用场景 |
|---|---|---|---|---|
| Z-score标准化 | x' = (x - μ) / σ | 无固定范围,约 [-3, 3] | 保留形状(偏度、峰度不变) | 回归建模、PCA、因子合成 |
| Min-Max归一化 | x' = (x - min) / (max - min) | [0, 1] | 压缩形状,对异常值敏感 | 神经网络输入、距离度量 |
| Rank归一化 | x' = rank(x) / N | (0, 1) | 完全消除分布形状,变为均匀分布 | 非参数因子、异常值严重时 |
def zscore_standardize(x):
"""Z-score标准化"""
return (x - x.mean()) / x.std(ddof=0)
def minmax_normalize(x):
"""Min-Max归一化"""
return (x - x.min()) / (x.max() - x.min())
def rank_normalize(x):
"""Rank归一化(百分位秩)"""
ranks = x.rank(method='average')
return (ranks - 1) / (len(ranks) - 1)
量化因子研究中的推荐做法:
- 截面标准化:在每个截面期(如每月末)对所有股票的因子值做 Z-score 标准化,这是因子研究的行业标准做法。
- 异常值处理前置:标准化前必须先处理极端值(如 MAD 截尾或分位数截断),否则一个极端值会拉偏整个截面的均值和标准差。
- 避免 Min-Max:Min-Max 对异常值极度敏感,且压缩了因子在中间区域的区分度,在因子研究中不推荐使用。
- Rank归一化作为稳健替代:当因子分布极度不规则或存在大量异常值时,Rank 归一化比 Z-score 更稳健。
3.4 四种变换方法对比与选择
| 维度 | 对数变换 | Box-Cox变换 | Z-score标准化 | Rank归一化 |
|---|---|---|---|---|
| 处理偏态 | 强(右偏) | 最强(自动适配) | 无 | 完全消除 |
| 处理异常值 | 中等 | 弱(λ 估计受影响) | 弱(需前置截尾) | 强 |
| 保留排序 | 是 | 是 | 是 | 是 |
| 保留间距 | 非线性压缩 | 非线性压缩 | 线性保留 | 完全破坏 |
| 因子含义可解释性 | 高 | 低 | 高 | 中 |
| 回测稳定性 | 高 | 低 | 高 | 高 |
| 推荐使用频率 | ★★★★★ | ★★ | ★★★★★ | ★★★★ |
讲师建议:在因子研究实战中,80% 以上的场景只需要两种变换的组合:对数变换 + Z-score标准化。先对偏态因子做对数变换,再在截面期做 Z-score 标准化,最后用 MAD 截尾处理残留异常值。这套流程简单、稳定、可解释,适合大规模因子生产线。