3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在量化选股与因子研究中,原始因子数据往往存在异常极值(Outliers)。如果不处理极值,会导致回归分析或权重优化时结果产生严重偏差。jqfactor 库提供的 winsorize 函数是 joinquant(聚宽)平台最常用的因子去极值(缩尾处理)工具之一。
本文将详细拆解 winsorize 函数中 scale 与 qrange 两个关键参数的区别、适用场景及代码实现。
from jqfactor import winsorize
winsorize(series, scale=None, range=None, qrange=None, inclusive=True, inf2nan=True, axis=1)
注意:
scale、range和qrange三者为互斥参数(三选一),不可同时使用。
| 参数维度 | scale(标准差倍数法) |
qrange(分位数缩尾法) |
|---|---|---|
| 计算原理 | 基于均值($\mu$)与标准差($\sigma$)计算边界:$[\mu - \text{scale} \times \sigma, \mu + \text{scale} \times \sigma]$ | 基于数据的分位数(Quantile)计算边界,如 [0.05, 0.95] 表示保留 5% 到 95% 之间的数据范围 |
| 处理方式 | 将超出 $[\mu - \text{scale} \cdot \sigma, \mu + \text{scale} \cdot \sigma]$ 的值替换为边界值(或 NaN) | 将低于下分位数或高于上分位数的值替换为对应的分位数边界值(或 NaN) |
| 敏感度 | 易受极端异常值的影响(因为极值本身会拉高均值和标准差) | 对极端异常值不敏感(截取比例固定,不受异常值大小影响) |
| 适用数据分布 | 适用于近似正态分布的因子数据 | 适用于偏态分布、长尾分布或存在严重极端值的因子数据 |
| 常用设定值 | scale=3 或 scale=2.5 |
qrange=[0.025, 0.975] 或 qrange=[0.05, 0.95] |
在 JoinQuant 研究环境中,我们可以获取沪深300成分股的因子数据并演示两种方法的区别:
import pandas as pd
import numpy as np
from jqdata import get_index_stocks
from jqfactor import get_factor_values, winsorize
# 1. 获取沪深300成分股某一天的因子数据(例如市净率因子 pb_ratio)
stocks = get_index_stocks('000300.XSHG', date='2023-01-01')
factor_dict = get_factor_values(securities=stocks, factors=['book_to_price_ratio'], start_date='2023-01-01', count=1)
factor_df = factor_dict['book_to_price_ratio']
# 2. 使用 scale (3倍标准差) 去极值
df_scale = winsorize(factor_df, scale=3, inclusive=True, inf2nan=True, axis=1)
# 3. 使用 qrange (5%-95%分位数) 去极值
df_qrange = winsorize(factor_df, qrange=[0.05, 0.95], inclusive=True, inf2nan=True, axis=1)
print("原始因子最大值/最小值:", factor_df.iloc[0].max(), factor_df.iloc[0].min())
print("Scale处理后最大值/最小值:", df_scale.iloc[0].max(), df_scale.iloc[0].min())
print("Qrange处理后最大值/最小值:", df_qrange.iloc[0].max(), df_qrange.iloc[0].min())
winsorize_med(中位数去极值)或 qrange:在真实的 A 股因子数据中,财务类因子(如 PE、PB、ROE)通常呈现高度右偏形态。scale 方法容易因极值过大而把边界拉得过宽,去极值效果不明显。qrange 能够强行拉平极端比例,更加稳健。winsorize) $\rightarrow$ 中性化 (neutralize) $\rightarrow$ 标准化 (standardlize)。