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

Как посчитать корреляцию у двух величин?

1.0 Junior🔥 141 комментариев
#Python и инструменты#Статистика и математика

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

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

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

Как посчитать корреляцию у двух величин?

Практический гайд по вычислению корреляции

Корреляция - это один из самых полезных инструментов Product Analyst'а для понимания связей между метриками. Но её легко неправильно интерпретировать. Расскажу как считать и что это значит.

1. Что такое корреляция

Корреляция (Pearson Correlation) показывает, как две переменные движутся вместе.

Формула:

r = Σ((x - mean_x) × (y - mean_y)) / sqrt(Σ(x - mean_x)² × Σ(y - mean_y)²)

Где:

  • r - коэффициент корреляции (от -1 до +1)
  • x, y - две переменные
  • mean_x, mean_y - среднее значение

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

r = +1    →  Идеальная положительная корреляция (когда x растет, y всегда растет)
r = +0.8  →  Сильная положительная корреляция
r = +0.5  →  Средняя положительная корреляция
r = 0     →  Нет корреляции
r = -0.5  →  Средняя отрицательная корреляция
r = -1    →  Идеальная отрицательная корреляция (когда x растет, y всегда падает)

2. Метод 1: SQL (для больших данных)

Основной способ, который я использую в работе:

-- Проверить: растет ли revenue вместе с user engagement?

SELECT 
  CORR(daily_sessions, daily_revenue) as correlation,
  -- Также посчитаю дополнительные статистики
  AVG(daily_sessions) as avg_sessions,
  AVG(daily_revenue) as avg_revenue,
  STDDEV(daily_sessions) as stddev_sessions,
  STDDEV(daily_revenue) as stddev_revenue,
  COUNT(*) as sample_size
FROM daily_metrics
WHERE date >= NOW() - INTERVAL '90 days';

Результат:

correlation    | 0.87
avg_sessions   | 5000
avg_revenue    | 50000
sample_size    | 90

Это означает: сильная положительная корреляция (0.87) между сеансами и доходом.

Пример с реальными данными

-- Корреляция между временем на сайте и конверсией

WITH daily_data AS (
  SELECT 
    DATE(session_start) as date,
    AVG(session_duration_sec) as avg_session_time,
    COUNT(DISTINCT CASE WHEN converted = true THEN user_id END)::float / 
    COUNT(DISTINCT user_id) * 100 as conversion_rate
  FROM sessions
  GROUP BY DATE(session_start)
)
SELECT 
  CORR(avg_session_time, conversion_rate)::numeric(3,2) as correlation,
  -- P-value (статистическая значимость)
  CASE 
    WHEN CORR(avg_session_time, conversion_rate) IS NOT NULL THEN
      'Significant' -- Need proper p-value calculation
    ELSE 'Not significant'
  END as significance
FROM daily_data;

-- Результат:
correlation  | 0.65
significance | Significant

-- Интерпретация: Средняя положительная корреляция
-- Когда пользователи проводят больше времени, они чаще конвертят
-- НАПОМИНАНИЕ: Это не значит, что время ВЫЗЫВАЕТ конверсию!

3. Метод 2: Python (для анализа)

Когда нужно больше контроля и визуализации:

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

# Загрузить данные
df = pd.read_csv('daily_metrics.csv')

# Способ 1: Простая корреляция Пирсона
corr = df['sessions'].corr(df['revenue'])
print(f"Correlation: {corr:.3f}")
# Результат: 0.876

# Способ 2: С p-value (важно для значимости!)
corr, p_value = stats.pearsonr(df['sessions'], df['revenue'])
print(f"Correlation: {corr:.3f}, P-value: {p_value:.4f}")
# Результат: Correlation: 0.876, P-value: 0.0000
# P-value < 0.05 = статистически значимо

# Способ 3: Матрица корреляции (для нескольких переменных)
corr_matrix = df[['sessions', 'revenue', 'bounce_rate', 'retention']].corr()
print(corr_matrix)

# Результат:
#              sessions  revenue  bounce_rate  retention
# sessions       1.000    0.876       -0.654      0.723
# revenue        0.876    1.000       -0.521      0.812
# bounce_rate   -0.654   -0.521        1.000     -0.934
# retention      0.723    0.812       -0.934      1.000

# Способ 4: Спирманова корреляция (для ненормальных распределений)
spearman_corr, spearman_p = stats.spearmanr(df['sessions'], df['revenue'])
print(f"Spearman: {spearman_corr:.3f}, P-value: {spearman_p:.4f}")
# Результат: Spearman: 0.892, P-value: 0.0000

Визуализация

import matplotlib.pyplot as plt

# Scatter plot с линией тренда
plt.scatter(df['sessions'], df['revenue'], alpha=0.6)
z = np.polyfit(df['sessions'], df['revenue'], 1)
p = np.poly1d(z)
plt.plot(df['sessions'], p(df['sessions']), "r--", label=f'Trend line')
plt.xlabel('Daily Sessions')
plt.ylabel('Daily Revenue')
plt.title(f'Correlation: {corr:.3f}')
plt.legend()
plt.show()

4. Практические примеры

Пример 1: Engagement и Retention

WITH cohort_data AS (
  SELECT 
    DATE(install_date) as cohort_date,
    AVG(events_day_1) as avg_engagement_d1,
    COUNT(DISTINCT CASE WHEN active_day_7 = true THEN user_id END)::float / 
    COUNT(*) as retention_d7
  FROM user_cohorts
  GROUP BY DATE(install_date)
  HAVING COUNT(*) > 100  -- Минимальный размер выборки
)
SELECT 
  CORR(avg_engagement_d1, retention_d7) as corr,
  COUNT(*) as cohort_count
FROM cohort_data;

-- Результат: 0.84
-- Интерпретация: День 1 engagement СИЛЬНО коррелирует с день 7 retention
-- Это показатель что engagement на первый день важен

Пример 2: Price и Conversion

WITH product_data AS (
  SELECT 
    product_id,
    price,
    SUM(sales) as total_sales,
    SUM(impressions) as total_impressions
  FROM product_stats
  WHERE date >= NOW() - INTERVAL '30 days'
  GROUP BY product_id, price
)
SELECT 
  CORR(price, total_sales / total_impressions::float) as price_conversion_corr,
  CORR(price, total_sales) as price_revenue_corr
FROM product_data
WHERE total_impressions > 100;

-- Результат:
-- price_conversion_corr: -0.45
-- price_revenue_corr: 0.12

-- Интерпретация:
-- Когда цена растет:
-- - Конверсия падает (-0.45) - логично
-- - Но revenue растет (+0.12) - людей меньше, но они покупают дороже

Пример 3: Spending и Churn

-- Коррелирует ли spending пользователя с churn?

WITH user_data AS (
  SELECT 
    user_id,
    SUM(amount) as total_spent,
    CASE WHEN last_activity < NOW() - INTERVAL '30 days' THEN 1 ELSE 0 END as churned
  FROM users
  LEFT JOIN payments ON users.id = payments.user_id
  GROUP BY user_id
)
SELECT 
  CORR(total_spent, churned) as correlation
FROM user_data;

-- Результат: -0.72
-- Интерпретация: Сильная ОТРИЦАТЕЛЬНАЯ корреляция
-- Люди, которые тратят больше, реже уходят (логично)
-- Это показатель что нужно фокусироваться на monetization для retention

5. Важные замечания

Замечание 1: Корреляция НЕ равна причинности

Классический пример:

Корреляция между:
- Количество фильмов Nicolas Cage (исход которых он выбирал в своих фильмах)
- Количество людей, утопленных в бассейне

Корреляция: 0.81 (очень сильна!)

Вывод: Nicolas Cage НЕ вызывает утопления.
Оба явления просто растут со временем (confounding variable = время)

В аналитике:

Если я вижу корреляцию между "время на сайте" и "покупкой",
это может значить:

1. Люди, которые проводят больше времени, покупают (причинность может быть)
2. Люди, которые ХОТЯТ купить, проводят больше времени (обратная причинность)
3. Оба вызваны третьим фактором:
   - Новые пользователи (обучаются дольше, реже покупают)
   - Мотивированные пользователи (активнее, часто покупают)

Для проверки причинности нужен A/B тест, не корреляция.

Замечание 2: P-value важен

Корреляция: 0.45
P-value: 0.04 (< 0.05)
= Статистически значимо

Корреляция: 0.45
P-value: 0.25 (> 0.05)
= НЕ статистически значимо (может быть случайность)

Замечание 3: Размер выборки

Малая выборка:
Только 5 дней данных
Корреляция: 0.95
Вывод: Эта корреляция не надежна (слишком мало данных)

Большая выборка:
2 года данных (730 дней)
Корреляция: 0.72
Вывод: Эта корреляция надежна

Замечание 4: Разные типы корреляции

Pearson Correlation

  • Для линейных зависимостей
  • Чувствительна к outliers
df['x'].corr(df['y'], method='pearson')

Spearman Correlation

  • Для монотонных зависимостей (не обязательно линейных)
  • Менее чувствительна к outliers
df['x'].corr(df['y'], method='spearman')

Kendall Correlation

  • Еще более robust к outliers
  • Используется реже
df['x'].corr(df['y'], method='kendall')

6. Лучшие практики

DO:

  • Всегда проверяй p-value (нужно < 0.05)
  • Используй достаточно данных (минимум 30 точек)
  • Проверяй scatter plot визуально перед выводами
  • Используй разные методы (Pearson + Spearman) если подозреваешь outliers
  • Не забывай про confounding variables

DON'T:

  • Не интерпретируй корреляцию как причинность
  • Не сравнивай корреляции из выборок разного размера
  • Не делай выводы на основе 5-10 точек данных
  • Не забывай про selection bias (может быть выбор в данных)
  • Не игнорируй extreme values (outliers могут исказить корреляцию)

7. Реальный рабочий workflow

-- 1. Быстрая проверка корреляции
SELECT CORR(metric_a, metric_b) FROM data;

-- 2. Если интересно:
-- Посчитай по периодам
SELECT 
  DATE_TRUNC('month', date) as month,
  CORR(metric_a, metric_b) as monthly_corr
FROM data
GROUP BY DATE_TRUNC('month', date);

-- 3. Посчитай по сегментам
SELECT 
  segment,
  CORR(metric_a, metric_b) as corr
FROM data
GROUP BY segment;

-- 4. Если корреляция интересная:
-- Посчитай лаг (может быть metric_b отстает на день?)
SELECT 
  CORR(metric_a, LAG(metric_b) OVER (ORDER BY date)) as corr_lag1
FROM data;

Заключение

Корреляция - это мощный инструмент для выявления связей между метриками. Но это только первый шаг:

  1. Найти корреляцию (SQL / Python)
  2. Проверить значимость (p-value > 0.05)
  3. Проверить визуально (scatter plot)
  4. Разобраться в причине (domain knowledge)
  5. Проверить причинность (A/B test, не корреляция)

Корреляция показывает что, причинность объясняет почему.

Как посчитать корреляцию у двух величин? | PrepBro