Корреляция Пирсона vs Спирмена — когда что использовать
Коротко
Корреляция Пирсона измеряет линейную связь между переменными. Корреляция Спирмена — монотонную (не обязательно линейную). Обе дают значение от −1 до +1. Пирсон чувствителен к выбросам и требует нормальности. Спирмен устойчивее — работает с рангами. Правило: данные нормальные и без выбросов → Пирсон. Ненормальные, порядковые или с выбросами → Спирмен. На собеседованиях аналитиков спрашивают разницу и когда что применять.
Быстрое сравнение
| Критерий | Пирсон (r) | Спирмен (ρ) |
|---|---|---|
| Что измеряет | Линейную связь | Монотонную связь |
| Данные | Непрерывные, нормальные | Любые (в т.ч. порядковые) |
| Выбросы | Чувствителен | Устойчив |
| Формула | По значениям | По рангам |
| Когда r ≈ ρ | Линейная зависимость, нет выбросов | — |
| Когда r ≠ ρ | Нелинейная монотонная зависимость или выбросы | — |
Корреляция Пирсона
Измеряет силу и направление линейной связи:
import numpy as np
from scipy import stats
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [2.1, 4.0, 5.8, 8.2, 10.1, 11.9, 14.0, 16.2, 18.0, 19.8]
r, p_value = stats.pearsonr(x, y)
print(f'Пирсон r = {r:.4f}, p-value = {p_value:.6f}')
# Пирсон r = 0.9998, p-value = 0.000000r = +1 — идеальная положительная линейная связь. r = 0 — нет линейной связи. r = −1 — идеальная отрицательная.
Интерпретация
| |r| | Сила связи | |-----|------------| | 0.9–1.0 | Очень сильная | | 0.7–0.9 | Сильная | | 0.5–0.7 | Средняя | | 0.3–0.5 | Слабая | | 0.0–0.3 | Очень слабая |
Корреляция Спирмена
Измеряет монотонную связь — через ранги значений:
rho, p_value = stats.spearmanr(x, y)
print(f'Спирмен ρ = {rho:.4f}, p-value = {p_value:.6f}')
# Спирмен ρ = 1.0000, p-value = 0.000000Спирмен = Пирсон, применённый к рангам. Если x растёт и y растёт (монотонно), ρ близок к 1, даже если связь нелинейная.
Когда Спирмен ≠ Пирсон
# Нелинейная, но монотонная зависимость (экспоненциальная)
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024] # y = 2^x
r, _ = stats.pearsonr(x, y) # 0.8892 — «сильная», но не идеальная
rho, _ = stats.spearmanr(x, y) # 1.0000 — идеальная монотонная связьПирсон видит, что связь не линейная (r < 1). Спирмен видит, что связь идеально монотонная (ρ = 1). Для экспоненциальных и логарифмических зависимостей Спирмен информативнее.
Влияние выбросов
# Без выброса
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
r, _ = stats.pearsonr(x, y) # 1.0000
rho, _ = stats.spearmanr(x, y) # 1.0000
# С выбросом
y_outlier = [10, 20, 30, 40, 50, 60, 70, 80, 90, 500]
r, _ = stats.pearsonr(x, y_outlier) # 0.8957 — упал
rho, _ = stats.spearmanr(x, y_outlier) # 1.0000 — не изменилсяОдин выброс (500 вместо 100) сильно повлиял на Пирсона, но не на Спирмена. Спирмен работает с рангами — выброс остаётся на своём месте (последний ранг).
Расчёт в pandas
import pandas as pd
df = pd.DataFrame({
'sessions': [10, 25, 50, 100, 200],
'revenue': [500, 1200, 2800, 5500, 12000]
})
# Пирсон
df['sessions'].corr(df['revenue'], method='pearson') # 0.9976
# Спирмен
df['sessions'].corr(df['revenue'], method='spearman') # 1.0000
# Матрица корреляций
df.corr(method='pearson')
df.corr(method='spearman')Визуализация матрицы корреляций
import seaborn as sns
import matplotlib.pyplot as plt
corr = df.corr(method='spearman')
sns.heatmap(corr, annot=True, cmap='coolwarm', center=0)
plt.title('Матрица корреляций (Спирмен)')
plt.show()Расчёт в SQL
-- Корреляция Пирсона (PostgreSQL)
SELECT CORR(sessions, revenue) AS pearson_r
FROM user_metrics;
-- Спирмена в SQL нет встроенной — через ранги
WITH ranked AS (
SELECT
RANK() OVER (ORDER BY sessions) AS rank_sessions,
RANK() OVER (ORDER BY revenue) AS rank_revenue
FROM user_metrics
)
SELECT CORR(rank_sessions, rank_revenue) AS spearman_rho
FROM ranked;PostgreSQL имеет встроенную CORR() для Пирсона. Для Спирмена — вычисляем ранги через оконные функции, потом Пирсона от рангов.
Когда что использовать
Пирсон
- Данные непрерывные и примерно нормальные
- Ожидаем линейную связь (revenue vs hours_worked)
- Нет значимых выбросов
- Нужна чувствительность к силе линейной зависимости
Спирмен
- Данные порядковые (рейтинги, оценки от 1 до 5)
- Есть выбросы
- Зависимость монотонная, но не линейная
- Распределение ненормальное (скошенное)
- Не уверены — Спирмен безопаснее
Корреляция ≠ причинность
Высокая корреляция не означает причинно-следственную связь. Подробнее — в статье про корреляцию и причинность.
# Пример: продажи мороженого коррелируют с количеством утоплений
# Корреляция высокая, но причина — жаркая погода (confounding variable)Типичные ошибки
Пирсон для нелинейной связи. Если y = x², Пирсон покажет 0, хотя связь очевидна. Проверяйте scatter plot перед расчётом.
Корреляция как причинность. r = 0.9 не значит, что X вызывает Y. Может быть обратная причинность (Y → X) или общий фактор.
Игнорирование p-value. r = 0.5 при n = 5 — не значимо. r = 0.1 при n = 10000 — значимо. Всегда смотрите на p-value вместе с r.
Вопросы с собеседований
-- Чем Пирсон отличается от Спирмена? -- Пирсон измеряет линейную связь по значениям. Спирмен — монотонную связь по рангам. Спирмен устойчивее к выбросам и работает с ненормальными данными.
-- Корреляция 0 — значит связи нет? -- Нет линейной (Пирсон) или монотонной (Спирмен) связи. Может быть нелинейная связь (параболическая). Всегда проверяйте scatter plot.
-- Когда использовать Спирмена? -- Порядковые данные, выбросы, ненормальное распределение, нелинейная монотонная связь. Если не уверены — начните со Спирмена, он безопаснее.
-- Как посчитать корреляцию в SQL?
-- CORR(x, y) в PostgreSQL — корреляция Пирсона. Для Спирмена: вычислить ранги через RANK(), затем CORR() от рангов.
Потренируйтесь решать задачи — откройте тренажёр с 1500+ вопросами для подготовки к собеседованиям аналитиков.
FAQ
Есть ли другие виды корреляции?
Кендалл (τ) — альтернатива Спирмену, более робастная при малых выборках. Точечно-бисериальная — связь бинарной и непрерывной переменных. Для большинства задач аналитика достаточно Пирсона и Спирмена.
Корреляция в pandas: какой метод по умолчанию?
df.corr() по умолчанию — Пирсон. Для Спирмена: df.corr(method='spearman'). Для Кендалла: df.corr(method='kendall').
Как тренироваться
Корреляция — обязательная тема на собеседованиях аналитика. Задачи на статистику — в тренажёре Карьерник. Больше вопросов — в разделе с примерами.