← Назад к вопросам

Какие знаешь меры разброса данных?

1.0 Junior🔥 201 комментариев
#Статистика и A/B тестирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Меры разброса и вариативности данных

Меры разброса (dispersion measures) описывают, как данные распределены вокруг центральной тенденции. Это критично для понимания данных и выбора алгоритмов ML.

1. Дисперсия (Variance)

Средний квадрат отклонения от среднего значения.

import numpy as np
import pandas as pd
from scipy import stats

data = np.array([2, 4, 4, 4, 5, 5, 7, 9])

# Формула
mean = np.mean(data)
variance = np.mean((data - mean) ** 2)
print(f"Variance: {variance}")

# Встроенные функции
variance_numpy = np.var(data)  # population variance
variance_pandas = pd.Series(data).var()  # sample variance (ddof=1)

print(f"NumPy: {variance_numpy}")
print(f"Pandas: {variance_pandas}")

# Разница между population и sample variance
population_var = np.var(data)  # делим на N
sample_var = np.var(data, ddof=1)  # делим на N-1

print(f"Population variance: {population_var}")
print(f"Sample variance: {sample_var}")

Интерпретация:

  • Высокая дисперсия → данные разбросаны
  • Низкая дисперсия → данные близко к среднему

Недостаток: Единица измерения в квадратах

2. Стандартное отклонение (Standard Deviation)

Квадратный корень из дисперсии. Самая популярная мера разброса.

# Стандартное отклонение
std = np.std(data)  # population
std_sample = np.std(data, ddof=1)  # sample

print(f"Standard deviation: {std}")
print(f"Sample std: {std_sample}")

# Связь с дисперсией
print(f"Sqrt(variance) = std: {np.sqrt(variance) == std}")

# Правило 68-95-99.7 (для нормального распределения)
mean = np.mean(data)
std = np.std(data)

within_1std = np.sum((data >= mean - std) & (data <= mean + std))
within_2std = np.sum((data >= mean - 2*std) & (data <= mean + 2*std))

print(f"Within ±1σ: {within_1std/len(data)*100:.1f}%")  # ~68%
print(f"Within ±2σ: {within_2std/len(data)*100:.1f}%")  # ~95%

Преимущества:

  • Измеряется в тех же единицах что и исходные данные
  • Легко интерпретировать
  • Используется в доверительных интервалах

3. Диапазон (Range)

Разница между максимум и минимум.

range_val = np.max(data) - np.min(data)
print(f"Range: {range_val}")  # 9 - 2 = 7

# Чувствителен к выбросам
data_with_outlier = np.array([2, 4, 4, 4, 5, 5, 7, 100])
range_with_outlier = np.max(data_with_outlier) - np.min(data_with_outlier)
print(f"Range with outlier: {range_with_outlier}")  # 98

Применение: Быстрая оценка, но не надежна

4. Interquartile Range (IQR)

Разница между 75-й и 25-й квартилью. Устойчив к выбросам.

q1 = np.percentile(data, 25)
q3 = np.percentile(data, 75)
iqr = q3 - q1

print(f"Q1 (25th percentile): {q1}")
print(f"Q3 (75th percentile): {q3}")
print(f"IQR: {iqr}")

# Использование IQR для определения выбросов
lower_bound = q1 - 1.5 * iqr
upper_bound = q3 + 1.5 * iqr

outliers = data[(data < lower_bound) | (data > upper_bound)]
print(f"Outliers: {outliers}")

# Визуализация (boxplot)
import matplotlib.pyplot as plt
plt.boxplot(data)
plt.ylabel('Value')
plt.show()

Преимущества: Не зависит от выбросов, хорош для skewed данных

5. Коэффициент вариации (Coefficient of Variation)

Относительная мера разброса (стандартное отклонение / среднее).

mean = np.mean(data)
std = np.std(data)
cv = std / mean * 100  # в процентах

print(f"Coefficient of Variation: {cv:.2f}%")

# Сравнение двух распределений с разными масштабами
data1 = np.array([10, 12, 11, 13, 9])
data2 = np.array([100, 120, 110, 130, 90])

cv1 = np.std(data1) / np.mean(data1) * 100
cv2 = np.std(data2) / np.mean(data2) * 100

print(f"CV1: {cv1:.2f}%")
print(f"CV2: {cv2:.2f}%")
# Оба примерно одинаковые, хотя стандартные отклонения разные

Использование: Сравнение вариативности когда данные на разных масштабах

6. Абсолютное отклонение от среднего (MAD)

Средний модуль отклонения от среднего.

mean = np.mean(data)
mad = np.mean(np.abs(data - mean))

print(f"Mean Absolute Deviation: {mad}")

# Сравнение с std (std более чувствителен к выбросам)
std = np.std(data)
print(f"Std: {std}, MAD: {mad}")

# С выбросом
data_outlier = np.array([2, 4, 4, 4, 5, 5, 7, 100])
mad_outlier = np.mean(np.abs(data_outlier - np.mean(data_outlier)))
std_outlier = np.std(data_outlier)

print(f"With outlier - MAD: {mad_outlier:.2f}, Std: {std_outlier:.2f}")
# Std сильнее реагирует на выброс

Преимущества: Более устойчив к выбросам чем std

7. Skewness (асимметрия)

Описывает асимметричность распределения.

from scipy.stats import skew

# Нормальное распределение
normal = np.random.normal(0, 1, 1000)
skewness_normal = skew(normal)
print(f"Skewness normal: {skewness_normal:.3f}")  # близко к 0

# Right-skewed (положительная асимметрия)
right_skewed = np.random.exponential(1, 1000)
skewness_right = skew(right_skewed)
print(f"Skewness right: {skewness_right:.3f}")  # > 0

# Left-skewed (отрицательная асимметрия)
left_skewed = -np.random.exponential(1, 1000)
skewness_left = skew(left_skewed)
print(f"Skewness left: {skewness_left:.3f}")  # < 0

# Визуализация
fig, axes = plt.subplots(1, 3, figsize=(12, 3))
axes[0].hist(normal, bins=30)
axes[0].set_title(f'Normal (skew={skewness_normal:.3f})')
axes[1].hist(right_skewed, bins=30)
axes[1].set_title(f'Right-skewed (skew={skewness_right:.3f})')
axes[2].hist(left_skewed, bins=30)
axes[2].set_title(f'Left-skewed (skew={skewness_left:.3f})')
plt.show()

Интерпретация:

  • Skewness ≈ 0: Симметричное распределение
  • Skewness > 0: Длинный хвост справа (Mean > Median)
  • Skewness < 0: Длинный хвост слева (Mean < Median)

8. Kurtosis (эксцесс)

Описывает "остроту" распределения (толщину хвостов).

from scipy.stats import kurtosis

# Различные распределения
normal = np.random.normal(0, 1, 1000)
uniform = np.random.uniform(-3, 3, 1000)
t_dist = np.random.standard_t(3, 1000)

kurt_normal = kurtosis(normal)
kurt_uniform = kurtosis(uniform)
kurt_t = kurtosis(t_dist)

print(f"Kurtosis normal: {kurt_normal:.3f}")  # ~0
print(f"Kurtosis uniform: {kurt_uniform:.3f}")  # < 0
print(f"Kurtosis t: {kurt_t:.3f}")  # > 0 (heavy tails)

Интерпретация:

  • Kurtosis = 0: Normal distribution
  • Kurtosis > 0: Heavy tails (leptokurtic)
  • Kurtosis < 0: Light tails (platykurtic)

9. Percentiles and Quartiles

Знапочения, которые делят данные на части.

# Percentiles
percentiles = [5, 25, 50, 75, 95]
for p in percentiles:
    val = np.percentile(data, p)
    print(f"{p}th percentile: {val}")

# Quartiles (25, 50, 75)
quartiles = np.quantile(data, [0.25, 0.5, 0.75])
print(f"Quartiles: {quartiles}")

# Deciles (10, 20, ..., 90)
deciles = np.quantile(data, np.arange(0.1, 1, 0.1))
print(f"Deciles: {deciles}")

10. Практический пример: анализ распределения

def analyze_distribution(data):
    """Полный анализ распределения"""
    
    results = {
        'count': len(data),
        'mean': np.mean(data),
        'median': np.median(data),
        'std': np.std(data),
        'variance': np.var(data),
        'min': np.min(data),
        'q1': np.percentile(data, 25),
        'q3': np.percentile(data, 75),
        'max': np.max(data),
        'iqr': np.percentile(data, 75) - np.percentile(data, 25),
        'range': np.max(data) - np.min(data),
        'cv': np.std(data) / np.mean(data) * 100,
        'skewness': skew(data),
        'kurtosis': kurtosis(data)
    }
    
    return results

# Применение
data = np.random.normal(100, 15, 1000)
analysis = analyze_distribution(data)

for key, value in analysis.items():
    print(f"{key:15}: {value:10.2f}")

Выбор меры разброса

СитуацияМераПричина
Normal distributionStd DevStandard, интерпретируется
Skewed distributionIQRУстойчив к выбросам
Сравнение масштабовCVОтносительная мера
На предмет выбросовMAD, IQRRobust меры
Для confidence intervalsStd DevИспользуется в формулах
Сделать outlier detectionIQR1.5*IQR метод

Best Practices

  1. Всегда проверяй распределение перед выбором меры
  2. Используй стандартное отклонение как основную меру
  3. Дополняй другими метриками для более полного понимания
  4. Визуализируй данные (histogram, boxplot, violin plot)
  5. Проверяй на выбросы перед анализом
  6. Трансформируй данные если нужно нормализовать распределение
Какие знаешь меры разброса данных? | PrepBro