← Назад к вопросам
Какие знаешь меры центральной тенденции?
2.0 Middle🔥 181 комментариев
#Статистика и A/B тестирование
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Меры центральной тенденции (Central Tendency Measures)
Меры центральной тенденции описывают типичное или среднее значение в распределении. Каждая мера имеет разные свойства и применения.
1. Mean (Среднее значение)
Сумма всех значений, разделенная на количество.
import numpy as np
import pandas as pd
data = np.array([2, 4, 4, 4, 5, 5, 7, 9])
# Вычисление
mean = np.mean(data) # или sum(data) / len(data)
print(f"Mean: {mean}")
# Для DataFrame
df = pd.DataFrame({'values': data})
mean_df = df['values'].mean()
print(f"Mean (Pandas): {mean_df}")
# Взвешенное среднее
weights = np.array([1, 1, 2, 1, 1, 2, 1, 1])
weighted_mean = np.average(data, weights=weights)
print(f"Weighted mean: {weighted_mean}")
# Harmonic mean (для скоростей, rates)
harmonic_mean = len(data) / np.sum(1 / data)
print(f"Harmonic mean: {harmonic_mean}")
# Geometric mean (для процентов роста)
geometric_mean = np.prod(data) ** (1 / len(data))
print(f"Geometric mean: {geometric_mean}")
Преимущества:
- Использует все данные
- Основа многих статистических методов
- Легко интерпретировать
Недостатки:
- Чувствителен к выбросам
- Не подходит для асимметричных распределений
Когда использовать:
- Нормальные распределения
- Когда нет выбросов
2. Median (Медиана)
Средний элемент упорядоченного набора данных.
# Медиана
data_sorted = np.sort(data)
if len(data) % 2 == 0:
median = (data_sorted[len(data)//2 - 1] + data_sorted[len(data)//2]) / 2
else:
median = data_sorted[len(data)//2]
print(f"Median: {median}")
print(f"Median (NumPy): {np.median(data)}")
print(f"Median (Pandas): {pd.Series(data).median()}")
# Пример с выбросом
data_with_outlier = np.array([2, 4, 4, 4, 5, 5, 7, 100])
mean_outlier = np.mean(data_with_outlier) # 26.38 (очень влияет выброс)
median_outlier = np.median(data_with_outlier) # 4.5 (не меняется)
print(f"Mean with outlier: {mean_outlier:.2f}")
print(f"Median with outlier: {median_outlier:.2f}")
Преимущества:
- Устойчива к выбросам
- Хороша для асимметричных распределений
- Легко интерпретируется
Недостатки:
- Не использует все данные (только центральный элемент)
- Менее "гладкая" функция (при малых изменениях может не меняться)
Когда использовать:
- Асимметричные распределения
- Когда есть выбросы (income, housing prices)
- Robust анализ
3. Mode (Мода)
Наиболее часто встречающееся значение.
from scipy import stats
# Мода для данных
data = np.array([2, 4, 4, 4, 5, 5, 7, 9])
mode = stats.mode(data, keepdims=True)
print(f"Mode: {mode.mode[0]}, Frequency: {mode.count[0]}")
# Мода для категориальных данных
categories = ['A', 'B', 'A', 'C', 'B', 'A']
mode_cat = pd.Series(categories).mode()[0]
print(f"Mode (categorical): {mode_cat}")
# Multimodal распределение
multimodal_data = np.array([1, 1, 1, 5, 5, 5, 10])
print(f"Modes: {stats.mode(multimodal_data, keepdims=True)}")
# Для непрерывных данных находим peak в гистограмме
numpy.histogram(continuous_data, bins=50)[0].argmax()
Преимущества:
- Работает с категориальными данными
- Имеет физический смысл (самое популярное значение)
Недостатки:
- Может быть несколько мод или моды вообще нет
- Для непрерывных данных требует бинирование
- Не использует все информацию о данных
Когда использовать:
- Категориальные данные
- Распределения с явным пиком
4. Quartiles (Квартили)
Значения, которые делят данные на 4 равные части.
# Квартили
q1 = np.percentile(data, 25)
q2 = np.percentile(data, 50) # медиана
q3 = np.percentile(data, 75)
print(f"Q1: {q1}, Q2 (Median): {q2}, Q3: {q3}")
# Использование в Pandas
df['values'].quantile([0.25, 0.5, 0.75])
# Describe дает summary statistics
df['values'].describe()
# Выводит: count, mean, std, min, 25%, 50%, 75%, max
5. Trimmed Mean (Урезанное среднее)
Среднее без заданного процента экстремальных значений.
from scipy.stats import trim_mean
# Удалим по 10% с обеих сторон и вычислим среднее
trimmed_mean = trim_mean(data, 0.1)
print(f"Trimmed mean (10%): {trimmed_mean}")
# Ручная реализация
def calculate_trimmed_mean(data, trim_percent=0.1):
sorted_data = np.sort(data)
n = len(data)
trim_count = int(n * trim_percent)
# Удаляем trim_count элементов с обеих сторон
trimmed = sorted_data[trim_count:n-trim_count]
return np.mean(trimmed)
trimmed = calculate_trimmed_mean(data, 0.1)
print(f"Trimmed mean: {trimmed}")
Используется: Robust анализ, когда есть несколько выбросов но не много
6. Winsorized Mean
Вместо удаления экстремальных значений, заменяем их на граничные.
from scipy.stats.mstats import winsorize
# Winsorize: заменяем top/bottom 10% на граничные значения
data_with_outlier = np.array([1, 2, 3, 4, 5, 6, 100])
winsorized_data = winsorize(data_with_outlier, limits=0.1)
print(f"Original: {data_with_outlier}")
print(f"Winsorized: {winsorized_data}")
print(f"Winsorized mean: {np.mean(winsorized_data)}")
7. Mid-Range (Середина диапазона)
Средняя точка между минимум и максимум.
mid_range = (np.min(data) + np.max(data)) / 2
print(f"Mid-range: {mid_range}")
# Очень чувствителен к выбросам, редко используется
Сравнение мер
def compare_central_tendency(data):
"""
Вычисляет все меры центральной тенденции
"""
results = {
'Mean': np.mean(data),
'Median': np.median(data),
'Mode': stats.mode(data, keepdims=True).mode[0],
'Trimmed Mean (10%)': trim_mean(data, 0.1),
'Geometric Mean': stats.gmean(data),
'Harmonic Mean': stats.hmean(data),
'Q1': np.percentile(data, 25),
'Q3': np.percentile(data, 75),
}
return results
# Разные типы распределений
print("\n=== Normal Distribution ===")
normal_data = np.random.normal(100, 15, 1000)
results = compare_central_tendency(normal_data)
for measure, value in results.items():
print(f"{measure:20}: {value:.2f}")
print("\n=== Right-Skewed Distribution ===")
skewed_data = np.random.exponential(50, 1000)
results = compare_central_tendency(skewed_data)
for measure, value in results.items():
print(f"{measure:20}: {value:.2f}")
print("\n=== With Outliers ===")
outlier_data = np.concatenate([np.random.normal(100, 15, 990), [1000] * 10])
results = compare_central_tendency(outlier_data)
for measure, value in results.items():
print(f"{measure:20}: {value:.2f}")
Практический выбор
| Ситуация | Рекомендуемая мера | Причина |
|---|---|---|
| Normal distribution | Mean | Standard, uses all data |
| Skewed distribution | Median | Robust to asymmetry |
| Categorical data | Mode | Only meaningful measure |
| With outliers | Median, Trimmed | Robust to extremes |
| Income/prices | Median | Log-normal distribution |
| Time-based data | Geometric mean | Growth rates |
| Multiple modes | Mode + context | Describe distribution |
Relationship между мерами
Нормальное распределение:
Mean = Median = Mode
Right-skewed (длинный хвост справа):
Mean > Median > Mode
(Примеры: income, house prices, web traffic)
Left-skewed (длинный хвост слева):
Mean < Median < Mode
(Примеры: test scores, exam grades)
Best Practices
- Всегда проверяй распределение перед выбором меры
- Используй несколько мер для полного понимания
- Для асимметричных данных: Median + IQR
- Для нормальных данных: Mean + Std Dev
- Описывай в контексте: не только дай число, объясни что оно значит
- Визуализируй: histogram или box plot
- Проверяй на выбросы перед использованием mean
Примеры в data science
# Анализ customer spending
spending = pd.Series([10, 15, 20, 25, 30, 35, 40, 1000]) # последний - VIP
mean_spending = spending.mean() # 196.88 (искажено VIP)
median_spending = spending.median() # 27.5 (более репрезентативно)
# Выводы
print(f"Average customer spends: ${mean_spending:.2f}") # техническое, но misleading
print(f"Typical customer spends: ${median_spending:.2f}") # better for marketing
# E-commerce example
page_loads = [1, 2, 2, 3, 3, 3, 4, 4, 5, 100] # последний - bot traffic
mean_loads = np.mean(page_loads) # 12.7
median_loads = np.median(page_loads) # 3
# Median лучше отражает реальное поведение пользователей