3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在传给 analyze_factor 做单因子分析时,底层(通常是 Alphalens)会使用 pandas.qcut 将因子值划分为 N 个分位数(Quantiles)。
当你使用 winsorize_med 且 scale=1 时,去极值的边界非常窄,导致大量因子被强制赋值为相同的边界值。当大量相同的值堆积在边界时,qcut 无法生成唯一的分位数边界(即分位数切分点重叠),从而引发底层的索引错误:Requested level (factor_quantile) does not match index name (None)。
在量化金融中,使用中位数绝对偏差(MAD,Median Absolute Deviation)去极值时,scale 通常设置为 3 或 5(即常说的 3倍MAD法 或 5倍MAD法)。
建议修改代码为:
winsorize_med(df_x, scale=3, inclusive=True, inf2nan=False, axis=1)
如果由于某些特殊原因,因子本身就存在大量重复值,或者你不想单纯依赖调整 scale,可以尝试以下几种替代方案:
相比于 MAD 法,分位数去极值(Percentile Clipping)更容易控制边界值的比例,不会因为分布的偏度导致单侧堆积过多数据。可以使用聚宽的 winsorize 函数:
from jqfactor import winsorize
# 将上下 2.5% 的数据拉平到边界
winsorize(df_x, qrange=[0.025, 0.975], inclusive=True, inf2nan=False, axis=1)
如果你认为极值是错误数据(如财务造假或数据异常),而不是“表现极好/极差”的股票,可以将 inclusive 设置为 False。这样极值会被替换为 NaN,在后续处理中被丢弃,从而避免大量相同边界值的堆积:
winsorize_med(df_x, scale=3, inclusive=False, inf2nan=False, axis=1)
如果因子值重复较多,切分 5 组或 10 组容易导致边界重叠。你可以尝试在调用 analyze_factor 时,减少 quantiles 的数量(例如从默认的 5 降到 3):
far = analyze_factor(factor=df_x, quantiles=3, ...)
如果因子本身离散度极低(例如某些哑变量因子或打分因子只有几个固定整数),可以通过给因子值加上极小的随机数来打破平局(Tie-breaking),使 qcut 能够成功切分:
import numpy as np
# 添加极小的噪音,不影响因子原本的排序逻辑
noise = np.random.normal(0, 1e-8, df_x.shape)
df_x = df_x + noise
最标准且最合理的做法是将 scale 调整为 3 或 5。scale=1 破坏了因子的截面分布,是导致该报错的根本原因。