问题描述
中位数去极值函数中,会将位于 [med - scale distance, med + scale distance] 边界之外的值替换为边界值/np.nan,这里的distance如何计算?
解决方案
在 JoinQuant 的 winsorize_med(中位数去极值)函数中,提到的 distance 实际上是指绝对中位差(Median Absolute Deviation,简称 MAD)。在聚宽的部分文档(如 BarraConstraint 风险暴露限制函数)中,这个值也被称为 MEDMED。
distance (MAD) 的具体计算步骤如下:
假设你有一个因子值序列 $X$:
-
计算中位数 (MED):
首先计算该序列 $X$ 的中位数,记为 $MED$。
$$MED = Median(X)$$ -
计算绝对偏差:
计算序列中每个因子值与中位数 $MED$ 差值的绝对值,得到一个新的序列。
$$Absolute_Deviations = |X_i - MED|$$ -
计算 distance (MAD / MEDMED):
对上一步得到的绝对偏差序列再次求中位数,这个结果就是distance。
$$distance = Median(|X_i - MED|)$$
边界计算总结
结合上述步骤,winsorize_med 函数的去极值边界 [med - scale * distance, med + scale * distance] 实际上就是:
[ 因子值中位数 - scale * 绝对中位差, 因子值中位数 + scale * 绝对中位差 ]
注:在聚宽的默认处理中(例如 Barra 风险模型的数据处理),通常会取 scale = 3,即将因子值限制在 [MED - 3 * MEDMED, MED + 3 * MEDMED] 的范围内,超出该范围的值会被替换为边界值或 np.nan(取决于 inclusive 参数的设置)。