winsorize 分位可以理解为:
把极端值压到某个分位边界上,而不是直接删除。
它常用于因子研究里处理异常值,防止极端币种把截面排序带偏。
1. 最简单例子
假设某一时点有 10 个币的因子值:
[-3, -2, -1, 0, 1, 2, 3, 4, 5, 100]这里 100 明显是极端值。
如果做:
winsorize_quantile: [0.05, 0.95]意思是:
小于 5% 分位的值,压到 5% 分位;
大于 95% 分位的值,压到 95% 分位。
所以 100 不会被删除,而是被压成接近 95% 分位的值。
2. 它和删除异常值不一样
删除异常值
[-3, -2, -1, 0, 1, 2, 3, 4, 5]直接把 100 扔掉。
Winsorize
[-3, -2, -1, 0, 1, 2, 3, 4, 5, 5附近]保留这个币,但限制它的极端影响。
3. 为什么截面因子要做 winsorize?
数字货币里经常有:
插针
低流动性拉盘
刚上线暴涨
数据错误
极端成交量
异常 funding如果不处理,一个币的因子值可能特别夸张:
普通币 BreakoutScore: 0.5, 1.2, 1.8
异常币 BreakoutScore: 50后续做 zscore 时,这个 50 会把均值和标准差严重拉歪。
结果是:
不是这个币特别强,而是整个截面标准化被污染了。
4. 分位 winsorize 的含义
常见写法:
winsorize_quantile: [0.01, 0.99]意思是:
低于 1% 分位的值 → 压到 1% 分位
高于 99% 分位的值 → 压到 99% 分位也可以写:
winsorize_quantile: [0.05, 0.95]意思是:
低于 5% 分位的值 → 压到 5% 分位
高于 95% 分位的值 → 压到 95% 分位5. 0.01/0.99 和 0.05/0.95 有什么区别?
| 设置 | 含义 | 特点 |
|---|---|---|
| 0.01 / 0.99 | 只压最极端 1% | 更温和,保留更多尾部信息 |
| 0.025 / 0.975 | 压两端 2.5% | 比较常见 |
| 0.05 / 0.95 | 压两端 5% | 更激进,更抗异常 |
| 0.10 / 0.90 | 压两端 10% | 太强,容易损失真实 alpha |
6. 在你的截面策略里怎么用?
假设每个 4h 时点,有 100 个币的 BreakoutDistanceAdj。
原始值:
[-2.1, -1.5, ..., 0.8, 1.2, 2.0, 15.0]如果做:
winsorize_quantile: [0.01, 0.99]那个 15.0 可能被压到 99% 分位,比如 3.2。
然后再做:
cross_sectional_zscore这样得到的 zscore 更稳定。
7. 推荐顺序
截面因子常用流程:
原始因子值
→ winsorize 分位截尾
→ zscore 标准化
→ 多因子加权
→ 排序选头尾也就是:
先压极端值,再标准化。不要先 zscore 再 winsorize,除非你明确采用 zscore clipping。
8. 分位 winsorize vs zscore clip
这是两个常见方法。
分位 winsorize
winsorize_quantile: [0.01, 0.99]按排序位置截尾。
优点:
不依赖均值和标准差
对极端值更稳健
适合肥尾分布数字货币更推荐这个。
zscore clip
winsorize_zscore: [-5, 5]意思是:
zscore 小于 -5 的压到 -5
zscore 大于 5 的压到 5优点:
简单直观
便于多因子统一尺度缺点:
均值和标准差本身可能已经被极端值污染9. 实战建议
对数字货币截面因子,初版可以用:
winsorize:
method: quantile
lower: 0.01
upper: 0.99如果资产池比较小,比如只有 50 个币,可以用更温和的:
winsorize:
method: quantile
lower: 0.02
upper: 0.98如果是 meme 或极端波动资产池,可以用:
winsorize:
method: quantile
lower: 0.05
upper: 0.95一句话总结
winsorize 分位就是把因子值两端过于极端的部分压回到指定分位边界,保留样本但限制异常值影响。
在截面因子里,推荐流程是:
原始因子 → 分位 winsorize → 截面 zscore → 排序 → 选头尾