异常值检测 —— MAD(median absolute deviation)

MAD 定义为,一元序列 XiXi 同其中位数偏差的绝对值的中位数(deviation,偏差本身有正有负);

MAD=median(|Ximedian(X)|)MAD=median(|Xi−median(X)|)

1. MAD 用于异常点的检测

假定数据服从正态分布,我们让异常点(outliers)落在两侧的 50% 的面积里,让正常值落在中间的 50% 的区域里:

P(|Xμ|MAD)=P(|Xμ|σMADσ)=P(ZMADσ)=1/2P(|X−μ|≤MAD)=P(|X−μ|σ≤MADσ)=P(Z≤MADσ)=1/2

其中 P(ZMADσ)=Φ(MADσ)Φ(MADσ)=1/2P(Z≤MADσ)=Φ(MADσ)−Φ(−MADσ)=1/2,又由 Φ(a)=1Φ(a)Φ(−a)=1−Φ(a),可 Φ(MAD/σ)=3/4Φ(MAD/σ)=3/4MAD/σ=Φ1(3/4)MAD/σ=Φ−1(3/4),查表可知,MAD/σMAD/σ=0.6749。

from scipy.stats import norm

def mad_based_outlier(points, thresh=3.5):
    if type(points) is list:
        points = np.asarray(points)
    if len(points.shape) == 1:
        points = points[:, None]
    med = np.median(points, axis=0)
    abs_dev = np.absolute(points - med)
    med_abs_dev = np.median(abs_dev)

    mod_z_score = norm.ppf(0.75) * abs_dev / med_abs_dev
    return mod_z_score > thresh

2. MAD 与基于分位数方法的对比

MAD 的方法相对于分位数方法的一大优势即在于 MAD 方法对样本大小是不敏感也即是稳定的鲁棒的一种评价指标。

def percentile_based_outlier(data, threshold=95):
    diff = (100 - threshold) / 2.0
    minval, maxval = np.percentile(data, [diff, 100 - diff])
    return (data < minval) | (data > maxval)

Pythonic way of detecting outliers in one dimensional observation data

转载于:https://www.cnblogs.com/mtcnn/p/9420971.html

你可能感兴趣的:(异常值检测 —— MAD(median absolute deviation))