在数据处理(尤其是金融、生物统计、信号处理等)中,极值(异常值) 会严重影响均值、方差、相关系数等统计量的估计,并扭曲模型训练。MAD法 (Median Absolute Deviation,绝对中位差法)是一种稳健的去极值方法,比基于均值和标准差的方法(如3σ法则)对异常值更不敏感。
下面为你详细介绍MAD法的原理、计算步骤、特点及实际应用。
1. 什么是MAD法?
MAD 定义为数据点与其中位数之差的绝对值的中位数 。其公式为:
MAD = median ( ∣ X i − median ( X ) ∣ ) \text{MAD}=\text{median}(\big|X_i−\text{median}(X)\big|) MAD=median( Xi−median(X) )
- 核心思想:先找到数据中心位置(中位数),然后计算每个点偏离中心的程度,再取这些偏离程度的中位数作为"典型偏离尺度"。
- 为什么用中位数? 中位数本身不受极值影响,因此MAD也能抵抗高达50%的异常值(理论上),而标准差受单个极值影响会急剧增大。
2. 使用MAD法去极值的步骤
通常,我们会将MAD转化为与标准差可比的形式,然后设定一个阈值(如 n 倍修正后的MAD)来判断是否为极值。
步骤详解:
步骤1:计算数据的中位数
M = median ( X ) M = \text{median}(X) M=median(X)
步骤2:计算每个数据点与中位数的绝对偏差
d i = ∣ X i − M ∣ d_i = |X_i − M| di=∣Xi−M∣
步骤3:计算这些绝对偏差的中位数,即 MAD
MAD = median ( d 1 , d 2 , . . . , d n ) \text{MAD} = \text{median} (d_1,d_2,...,d_n) MAD=median(d1,d2,...,dn)
步骤4:将MAD转换为对正态分布下标准差的稳健估计
若数据服从正态分布,则:
σ robust ≈ 1.4826 × MAD \sigma_{\text{robust}} \approx 1.4826 \times \text{MAD} σrobust≈1.4826×MAD
其中 1.4826 是一个比例常数(因为对于正态分布, MAD ≈ 0.6745 σ \text{MAD} \approx 0.6745\sigma MAD≈0.6745σ,所以 σ ≈ MAD / 0.6745 ≈ 1.4826 × MAD \sigma \approx \text{MAD} / 0.6745 \approx 1.4826 \times \text{MAD} σ≈MAD/0.6745≈1.4826×MAD)。
步骤5:设定阈值,识别并处理极值
常用标准:
- 温和异常值 :超出中位数 ± 2 × 1.4826 × MAD \pm 2 \times 1.4826 \times \text{MAD} ±2×1.4826×MAD
- 极端异常值 :超出中位数 ± 3 × 1.4826 × MAD \pm 3 \times 1.4826 \times \text{MAD} ±3×1.4826×MAD
处理方式:
- 截断(Winsorizing):将超出阈值的点强制设为阈值边界值。
- 删除:直接剔除异常值(适用于对样本量要求不严的场景)。
- 填充:用中位数或邻近值替换(谨慎使用)。
3. 举例说明
假设数据集:[10, 12, 13, 15, 16, 18, 200](200是异常值)
- 中位数 M = 15(排序后第4个数)
- 绝对偏差:
[5, 3, 2, 0, 1, 3, 185] - 这些偏差的中位数 = 3 \\implies \\text{MAD} = 3
- 稳健标准差 ≈ 1.4826 × 3 ≈ 4.4478 \approx 1.4826 \times 3 \approx 4.4478 ≈1.4826×3≈4.4478
- 设阈值为 3 × 4.4478 ≈ 13.34 3 \times 4.4478 \approx 13.34 3×4.4478≈13.34,则正常范围: 15 ± 13.34 ⟹ ( 1.66 , 28.34 ) 15 \pm 13.34 \implies (1.66, 28.34) 15±13.34⟹(1.66,28.34)
- 200超出上界,被判定为极值。可截断为28.34。
4. 与3σ法的对比(重要)
| 特性 | MAD法 | 3σ法(均值±3倍标准差) |
|---|---|---|
| 中心趋势度量 | 中位数(稳健) | 均值(易受极值拉动) |
| 离散度量 | MAD(稳健) | 标准差(易受极值扩大) |
| 对异常值容忍度 | 可达50% | 单个极值就会严重干扰 |
| 适用分布 | 任何单峰分布(默认正态修正时) | 要求数据近似正态 |
| 实际效果 | 不易漏掉真实极值,不易误判正常值 | 易把正常值判为异常(当数据非正态) |
举例 :
数据:[1,2,2,2,3,3,100]
- 均值 ≈ 16.14 ≈ 16.14 ≈16.14,标准差 ≈ 35.7 ⟹ 3 σ ≈ 35.7 \implies 3σ ≈35.7⟹3σ区间为 [ 16.14 − 107.1 , 16.14 + 107.1 ] = [ − 91 , 123 ] [16.14-107.1, 16.14+107.1] = [-91, 123] [16.14−107.1,16.14+107.1]=[−91,123],几乎包含所有值,漏掉100是极值。
- MAD:中位数=2,MAD=1,稳健 σ ≈ 1.48 σ≈1.48 σ≈1.48,3倍区间 ≈ [ 2 − 4.45 , 2 + 4.45 ] = [ − 2.45 , 6.45 ] ≈[2-4.45, 2+4.45]=[-2.45, 6.45] ≈[2−4.45,2+4.45]=[−2.45,6.45],正确判定100为极值。
5. 注意事项
- 样本量要求:当数据量很小(如<10)时,MAD可能不稳定。
- 非对称分布:MAD法假设对称性(或至少使用对称阈值),对于偏态分布,可考虑使用调整后的阈值或分位数法。
- 正态性假设的修正:常数1.4826仅在希望MAD近似标准差时使用。若仅用于排序截断,可直接使用原始MAD倍数(如3倍MAD,但不乘以1.4826)。
- 多模态分布:需谨慎,可能将部分正常模式误判为异常。
6. 代码实现(Python示例)
python
import numpy as np
def mad_based_outlier(data, threshold=3, robust_sigma=True):
"""
data: 一维数组
threshold: 阈值倍数(如3)
robust_sigma: 是否转换为与标准差可比的尺度
"""
median = np.median(data)
mad = np.median(np.abs(data - median))
if robust_sigma:
mad = mad * 1.4826 # 转换为稳健标准差
upper_bound = median + threshold * mad
lower_bound = median - threshold * mad
# 截断处理
data_cleaned = np.clip(data, lower_bound, upper_bound)
# 识别异常值位置(可选)
outliers = (data < lower_bound) | (data > upper_bound)
return data_cleaned, outliers
# 测试
data = np.array([10,12,13,15,16,18,200])
cleaned, flag = mad_based_outlier(data, threshold=3)
print(cleaned)
# 输出: [10. 12. 13. 15. 16. 18. 28.34]
总结
MAD法去极值 的核心优势在于稳健性------它不会被少量极端值带偏,因此非常适合于:
- 金融收益率序列(常有极端波动)
- 生物/医学数据(测量误差或个体差异大)
- 任何含有未知或大量异常值的真实数据集
在实际使用中,建议先可视化数据分布,再选择合适的阈值(通常24倍MAD或24倍稳健标准差),并明确最终采用截断、删除还是替换策略。