Какие знаешь меры разброса данных?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Меры разброса и вариативности данных
Меры разброса (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 distribution | Std Dev | Standard, интерпретируется |
| Skewed distribution | IQR | Устойчив к выбросам |
| Сравнение масштабов | CV | Относительная мера |
| На предмет выбросов | MAD, IQR | Robust меры |
| Для confidence intervals | Std Dev | Используется в формулах |
| Сделать outlier detection | IQR | 1.5*IQR метод |
Best Practices
- Всегда проверяй распределение перед выбором меры
- Используй стандартное отклонение как основную меру
- Дополняй другими метриками для более полного понимания
- Визуализируй данные (histogram, boxplot, violin plot)
- Проверяй на выбросы перед анализом
- Трансформируй данные если нужно нормализовать распределение