Σ
SDCalc
СреднийКонцепции·12 min

Робастная статистика: MAD, IQR и устойчивые к выбросам методы

Полное руководство по робастной статистике: медианное абсолютное отклонение (MAD) и межквартильный размах (IQR). Когда использовать устойчивые к выбросам меры разброса с примерами и кодом на Python.

Зачем нужна робастная статистика?

Стандартное отклонение — мощная мера разброса, но у неё есть критическая слабость: крайняя чувствительность к выбросам. Одно экстремальное значение может резко завысить СО, давая искажённое представление о типичной вариации.

Робастная статистика предоставляет меры разброса, устойчивые к влиянию выбросов, что делает их незаменимыми для реальных данных, где часто встречаются ошибки измерений, ошибки ввода или подлинные экстремальные случаи.

Пример: Влияние выброса

Данные: 10, 12, 11, 13, 12, 11, 100 (один выброс) Стандартное отклонение: 32,4 (поглощено выбросом) MAD: 1,0 (игнорирует выброс) IQR: 1,5 (игнорирует выброс)

Точка разрушения

«Точка разрушения» статистики — это доля данных, которая может быть экстремальной, прежде чем статистика станет бессмысленной. У СО точка разрушения 0% (один выброс может её исказить). У MAD и IQR точка разрушения 50% — половина данных может быть выбросами, и они всё равно работают.

Медианное абсолютное отклонение (MAD)

MAD — наиболее робастная мера разброса. Она вычисляет медиану абсолютных отклонений от медианы:

Формула MAD

MAD = median(|xᵢ - median(x)|)
1

Найдите медиану

Рассчитайте медиану набора данных.
2

Рассчитайте отклонения

Вычтите медиану из каждого значения и возьмите модуль.
3

Найдите MAD

Рассчитайте медиану полученных абсолютных отклонений.

Масштабирование MAD для оценки σ: Для нормально распределённых данных MAD ≈ 0,6745 × σ. Для оценки СО по MAD умножьте на 1,4826:

Оценка СО через MAD

σ̂ = 1.4826 × MAD

Почему 1,4826?

Этот масштабирующий коэффициент вытекает из связи между MAD и СО для нормальных распределений. Он обеспечивает несмещённость масштабированного MAD как оценки истинного стандартного отклонения при нормальных данных.

Межквартильный размах (IQR)

IQR измеряет разброс средних 50% данных — расстояние между 25-м и 75-м процентилями:

Формула IQR

IQR = Q3 - Q1 = 75-й процентиль - 25-й процентиль

IQR широко используется, потому что прост для понимания, легко визуализируется на диаграммах размаха и является основой распространённого правила «1,5×IQR» для обнаружения выбросов.

Масштабирование IQR для оценки σ: Для нормальных данных IQR ≈ 1,35 × σ. Для оценки СО по IQR:

Оценка СО через IQR

σ̂ = IQR / 1.35 ≈ 0.7413 × IQR

Сравнение робастных мер

Стандартное отклонение

Использует все точки данных · Наиболее эффективно для нормальных данных · Очень чувствительно к выбросам · Точка разрушения: 0%

MAD

Наиболее робастная мера · Использует медиану (не среднее) · Нечувствительно к любым выбросам · Точка разрушения: 50%

IQR

Просто для понимания · Используется в диаграммах размаха · Игнорирует крайние 50% · Точка разрушения: 25%

Когда использовать робастную статистику

  • Разведочный анализ: когда неизвестно, есть ли выбросы, начните с робастных мер
  • Проблемы качества данных: когда данные могут содержать ошибки или проблемы измерений
  • Тяжелохвостые распределения: когда экстремальные значения ожидаемы (финансовая доходность, страховые выплаты)
  • Малые выборки: когда выбросы оказывают непропорционально большое влияние из-за малого числа наблюдений
  • Обнаружение выбросов: использование СО для обнаружения выбросов — логический круг; вместо этого используйте IQR или MAD

Примеры реализации

Python
import numpy as np
from scipy import stats

def mad(data):
    """Median Absolute Deviation"""
    median = np.median(data)
    return np.median(np.abs(data - median))

def scaled_mad(data):
    """MAD scaled to estimate SD (for normal data)"""
    return 1.4826 * mad(data)

def iqr(data):
    """Interquartile Range"""
    return np.percentile(data, 75) - np.percentile(data, 25)

# Compare on data with outlier
data = [10, 12, 11, 13, 12, 11, 100]
print(f"SD: {np.std(data, ddof=1):.2f}")
print(f"MAD: {mad(data):.2f}")
print(f"Scaled MAD: {scaled_mad(data):.2f}")
print(f"IQR: {iqr(data):.2f}")