数据分析中的异常值处理:MAD

在数据处理(尤其是金融、生物统计、信号处理等)中,极值(异常值) 会严重影响均值、方差、相关系数等统计量的估计,并扭曲模型训练。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是异常值)

  1. 中位数 M = 15(排序后第4个数)
  2. 绝对偏差:[5, 3, 2, 0, 1, 3, 185]
  3. 这些偏差的中位数 = 3 \\implies \\text{MAD} = 3
  4. 稳健标准差 ≈ 1.4826 × 3 ≈ 4.4478 \approx 1.4826 \times 3 \approx 4.4478 ≈1.4826×3≈4.4478
  5. 设阈值为 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)
  6. 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倍稳健标准差),并明确最终采用截断、删除还是替换策略。

相关推荐
飞Link2 小时前
LangGraph 核心架构解析:节点 (Nodes) 与边 (Edges) 的工作机制及实战指南
java·开发语言·python·算法·架构
Mr_Xuhhh2 小时前
深入理解二叉树:从数据结构到算法实战
数据结构·算法
xuhaoyu_cpp_java2 小时前
Boyer-Moore 投票算法
java·经验分享·笔记·学习·算法
kobesdu3 小时前
FAST-LIO2 + 蓝海M300激光雷达:从建图到实时栅格图的完整流程
算法·机器人·ros·slam·fast lio
x_xbx3 小时前
LeetCode:438. 找到字符串中所有字母异位词
算法·leetcode·职场和发展
MThinker3 小时前
K230+canMV+micropython实现低成本MLX90640红外热成像测温模块(续)
算法·智能硬件·micropython·canmv·k230
小菜鸡桃蛋狗3 小时前
C++——string(下)
算法
学习永无止境@3 小时前
灰度图像中值滤波算法实现
图像处理·算法·计算机视觉
ysa0510303 小时前
斐波那契上斐波那契【矩阵快速幂】
数据结构·c++·笔记·算法