Предиктивная аналитика для начинающих: как прогнозировать churn и lifetime value пользователей

Предиктивная аналитика для начинающих: как прогнозировать churn и lifetime value пользователей

Представьте. У вас SaaS продукт. Подписка 1000 рублей в месяц. В январе зарегистрировалось 100 новых пользователей. Вы думаете: отлично, +100 000 рублей в месяц!

Реальность: через месяц 40 пользователей ушли. Через два месяца ещё 20. Через три ещё 15. К концу года из 100 пользователей осталось 10.

Ваш реальный доход с этой когорты: не 1 200 000 рублей (100 пользователей × 12 месяцев × 1000₽), а примерно 350 000 рублей. Разница в 3.5 раза.

А что если бы вы знали заранее кто из 100 пользователей уйдёт? Что если бы могли предсказать что пользователь А принесёт 50 000 рублей за lifetime, а пользователь Б только 3 000?

Вы бы могли:

  • Вовремя спасти пользователя от ухода (персональное предложение, помощь)

  • Тратить маркетинговый бюджет правильно (платить за привлечение пользователя А до 40 000₽, а за пользователя Б не больше 2 000₽)

  • Приоритизировать фичи (делать то что удерживает высокоценных пользователей)

Это и есть предиктивная аналитика. Прогнозирование будущего поведения пользователей на основе данных.

Две ключевые метрики:

  • Churn (отток) - вероятность что пользователь уйдёт

  • LTV (Lifetime Value) - сколько денег принесёт пользователь за всё время

По данным исследований, снижение churn всего на 5% может увеличить прибыль на 25-95%. Компании которые эффективно используют LTV для сегментации увеличивают продажи на 81%.

В этой статье разбираемся как строить простые модели предсказания churn и LTV. Без сложной математики. С примерами кода на Python. Пошагово. Для начинающих.

1. Что такое churn и почему его нужно предсказывать

Определение churn (оттока)

Churn это когда клиент перестаёт пользоваться вашим продуктом. Существует два вида:

1. Voluntary churn (добровольный отток)

Пользователь сам решил уйти. Отменил подписку. Удалил приложение. Перестал заходить.

Причины:

  • Продукт не решает проблему

  • Нашёл лучшую альтернативу

  • Слишком дорого

  • Плохой UX

  • Не понял как пользоваться

2. Involuntary churn (вынужденный отток)

Платёж не прошёл. Карта заблокирована. Технические проблемы.

Обычно легче предотвратить чем voluntary churn (просто нужно повторить платёж или обновить данные карты).

Как измеряется churn

Churn Rate = (Количество ушедших пользователей / Общее количество пользователей в начале периода) × 100%

Пример: 1000 пользователей в начале месяца. 50 ушли. Churn Rate = 50/1000 × 100% = 5%.

Что считается хорошим churn rate

Тип бизнесаХороший месячный churnПлохой месячный churn
SaaS B2B< 5%> 10%
SaaS B2C< 7%> 15%
Мобильные игры< 20% (первый месяц)> 40%
E-commerce< 10%> 25%
Стриминг сервисы< 5%> 10%

Почему важно предсказывать churn

  1. Дешевле удержать чем привлечь нового. Привлечение нового клиента стоит в 5-25 раз дороже чем удержание существующего

  2. Можно успеть спасти. Если знаешь что пользователь уйдёт через неделю, можешь предложить скидку, помощь, бонусы

  3. Понимание причин. Модель показывает какие факторы влияют на отток (мало использует продукт, плохой onboarding, долго не заходит)

  4. Приоритизация ресурсов. Не тратить время на всех, а фокусироваться на тех кто с высокой вероятностью уйдёт

2. Что такое LTV и как он связан с churn

Определение Customer Lifetime Value (LTV/CLV/CLTV)

LTV это прогноз общей прибыли которую принесёт клиент за всё время использования продукта.

Простая формула LTV:

LTV = Средний чек × Количество покупок в месяц × Среднее время жизни клиента (в месяцах)

Пример: SaaS продукт с подпиской 1000₽/месяц. Средний клиент живёт 24 месяца.

LTV = 1000₽ × 1 покупка/месяц × 24 месяца = 24 000₽

Более продвинутая формула с учётом маржинальности:

LTV = (Средний чек × Gross Margin × Количество покупок в месяц × Среднее время жизни) / Churn Rate

Связь LTV и Churn

Чем выше churn, тем ниже LTV. Если churn 10% в месяц, средний клиент живёт 10 месяцев (1/0.1). Если churn 5%, клиент живёт 20 месяцев.

Пример:

  • Churn 10% → Средняя жизнь 10 месяцев → LTV = 1000₽ × 10 = 10 000₽

  • Churn 5% → Средняя жизнь 20 месяцев → LTV = 1000₽ × 20 = 20 000₽

Снизили churn в 2 раза, LTV вырос в 2 раза!

Почему важно предсказывать LTV

  1. Сколько можно тратить на привлечение. CAC (стоимость привлечения) должен быть меньше LTV. Обычно LTV/CAC = 3:1. Если LTV = 20 000₽, можно тратить до 6 600₽ на привлечение

  2. Сегментация пользователей. Есть пользователи с LTV 50 000₽ и с LTV 2 000₽. К ним разный подход

  3. Персонализация. Для высокоценных пользователей персональный менеджер, premium поддержка. Для низкоценных автоматизация

  4. Приоритизация фич. Делать то что увеличивает LTV высокоценных сегментов

3. Какие данные нужны для предсказания

Типы данных для churn prediction

1. Демографические данные

  • Возраст

  • Пол

  • Город / страна

  • Тип компании (для B2B)

  • Размер компании

2. Поведенческие данные (самые важные!)

  • Частота использования продукта (логины в неделю)

  • Глубина использования (сколько функций использует)

  • Время в продукте (минут в день)

  • Паттерны активности (когда заходит, как часто)

  • Milestone events (прошёл onboarding, добавил команду, создал первый проект)

3. Транзакционные данные

  • Тип подписки (basic, pro, enterprise)

  • Цена

  • Длительность подписки

  • История платежей (были ли проблемы)

  • Upgrades / downgrades

4. Engagement данные

  • Email open rate

  • Click rate

  • Обращения в поддержку (количество, sentiment)

  • NPS score

  • Feature adoption (какие фичи использует)

5. Временные данные

  • Tenure (сколько времени с момента регистрации)

  • Recency (когда был последний логин)

  • Seasonality (сезонность)

Типы данных для LTV prediction

Для LTV нужны те же данные плюс:

  • Исторические транзакции: сколько тратил раньше, как часто, тренд

  • RFM метрики: Recency (как давно покупал), Frequency (как часто), Monetary (сколько тратит)

  • Product mix: какие продукты покупает, средний чек, категории

Пример датасета

Типичная структура данных для churn prediction в SaaS:

user_id | tenure_days | logins_last_30d | features_used | plan_type | monthly_spend | support_tickets | nps_score | days_since_last_login | churned
--------|-------------|-----------------|---------------|-----------|---------------|-----------------|-----------|----------------------|--------
001     | 365         | 22              | 8             | pro       | 1000          | 2               | 8         | 1                    | 0
002     | 90          | 3               | 2             | basic     | 500           | 5               | 4         | 15                   | 1
003     | 730         | 28              | 12            | enterprise| 5000          | 1               | 9         | 0                    | 0

Минимальный набор данных для начала

Можно начать даже с минимума:

  1. Частота использования (логины за последние 30 дней)

  2. Recency (дней с последнего использования)

  3. Tenure (дней с момента регистрации)

  4. Тип подписки

  5. Churned (метка: ушёл или нет)

С этими 5 полями уже можно построить базовую модель!

4. Простая модель предсказания churn: пошагово

Шаг 1: Определяем что такое "churned"

Нужно чётко определить когда пользователь считается ушедшим:

  • SaaS с подпиской: отменил подписку

  • Freemium продукт: не заходил 30 дней

  • E-commerce: не покупал 90 дней

  • Мобильное приложение: не открывал 14 дней

Важно: определение churn зависит от вашего бизнеса!

Шаг 2: Собираем данные

import pandas as pd
import numpy as np

# Загружаем данные
df = pd.read_csv('users.csv')

# Смотрим структуру
print(df.head())
print(df.info())

# Проверяем баланс классов
print(df['churned'].value_counts())
# Output:
# 0    8500  (не ушли)
# 1    1500  (ушли)

Шаг 3: Feature engineering (создание признаков)

# Создаём новые признаки на основе существующих

# Engagement score (насколько активен пользователь)
df['engagement_score'] = df['logins_last_30d'] / 30

# Adoption rate (сколько функций использует от общего числа)
df['feature_adoption_rate'] = df['features_used'] / 15  # если всего 15 функций

# Inactivity (как давно не заходил в днях)
df['inactivity_days'] = df['days_since_last_login']

# Value tier (сегмент по цене)
df['is_high_value'] = (df['monthly_spend'] > 2000).astype(int)

# Early stage (новый пользователь или нет)
df['is_early_stage'] = (df['tenure_days'] < 90).astype(int)

Шаг 4: Готовим данные для модели

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# Выбираем признаки
features = ['tenure_days', 'logins_last_30d', 'features_used', 
            'monthly_spend', 'support_tickets', 'nps_score', 
            'days_since_last_login', 'engagement_score', 
            'feature_adoption_rate', 'is_high_value', 'is_early_stage']

X = df[features]
y = df['churned']

# Разделяем на train и test (80% / 20%)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

# Масштабируем признаки
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

Шаг 5: Обучаем модель (Random Forest)

from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, roc_auc_score, confusion_matrix

# Создаём и обучаем модель
model = RandomForestClassifier(
    n_estimators=100,
    max_depth=10,
    random_state=42,
    class_weight='balanced'  # важно для несбалансированных классов
)

model.fit(X_train_scaled, y_train)

# Предсказываем на тестовых данных
y_pred = model.predict(X_test_scaled)
y_pred_proba = model.predict_proba(X_test_scaled)[:, 1]

# Оцениваем качество
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))

print("\nClassification Report:")
print(classification_report(y_test, y_pred))

print(f"\nROC-AUC Score: {roc_auc_score(y_test, y_pred_proba):.3f}")

Шаг 6: Интерпретируем результаты

# Важность признаков
feature_importance = pd.DataFrame({
    'feature': features,
    'importance': model.feature_importances_
}).sort_values('importance', ascending=False)

print("Top 5 важных признаков:")
print(feature_importance.head())

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

  • Precision (точность): из тех кого модель предсказала как churned, сколько действительно ушли

  • Recall (полнота): из всех кто ушёл, сколько мы поймали

  • ROC-AUC: общее качество модели. > 0.7 хорошо, > 0.8 отлично, > 0.9 великолепно

Шаг 7: Используем модель для предсказаний

# Предсказываем вероятность churn для всех активных пользователей
active_users = pd.read_csv('active_users.csv')
active_users_features = active_users[features]
active_users_scaled = scaler.transform(active_users_features)

churn_probabilities = model.predict_proba(active_users_scaled)[:, 1]

# Добавляем вероятность в датафрейм
active_users['churn_probability'] = churn_probabilities

# Сортируем по вероятности (самые рискованные сверху)
at_risk_users = active_users.sort_values('churn_probability', ascending=False)

# Топ 100 пользователей с высоким риском
high_risk = at_risk_users.head(100)

print("Топ 10 пользователей с риском churn:")
print(high_risk[['user_id', 'churn_probability', 'monthly_spend']].head(10))

5. Простая модель предсказания LTV: пошагово

Подход 1: RFM + простая формула

Для начала можно использовать RFM анализ:

# Вычисляем RFM метрики для каждого пользователя

# R (Recency) - как давно покупал (дней назад)
# F (Frequency) - как часто покупает (количество покупок за период)
# M (Monetary) - сколько тратит (средний чек)

import datetime

current_date = datetime.datetime.now()

rfm = df.groupby('user_id').agg({
    'order_date': lambda x: (current_date - x.max()).days,  # Recency
    'order_id': 'count',                                      # Frequency
    'order_value': 'sum'                                      # Monetary
}).reset_index()

rfm.columns = ['user_id', 'recency', 'frequency', 'monetary']

# Простая формула LTV
# Предполагаем что пользователь будет покупать с той же частотой ещё 12 месяцев

rfm['avg_order_value'] = rfm['monetary'] / rfm['frequency']
rfm['purchases_per_month'] = rfm['frequency'] / 12  # если данные за год
rfm['predicted_ltv_12m'] = rfm['avg_order_value'] * rfm['purchases_per_month'] * 12

print(rfm.head())

Подход 2: Machine Learning модель

from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error, r2_score

# Готовим данные
# Для LTV нам нужны пользователи у которых уже есть история
# Берём первые 6 месяцев как признаки, следующие 12 месяцев как target

# Признаки за первые 6 месяцев
features_ltv = [
    'total_spend_6m',        # сколько потратил за 6 месяцев
    'num_orders_6m',         # количество заказов
    'avg_order_value_6m',    # средний чек
    'days_active_6m',        # сколько дней был активен
    'recency_6m',           # как давно покупал
    'tenure_days',          # как давно зарегистрировался
    'first_order_value',    # размер первого заказа
    'category_diversity'    # в скольких категориях покупал
]

X_ltv = df[features_ltv]
y_ltv = df['ltv_next_12m']  # сколько потратил в следующие 12 месяцев

# Train / test split
X_train_ltv, X_test_ltv, y_train_ltv, y_test_ltv = train_test_split(
    X_ltv, y_ltv, test_size=0.2, random_state=42
)

# Обучаем модель
ltv_model = RandomForestRegressor(
    n_estimators=100,
    max_depth=15,
    random_state=42
)

ltv_model.fit(X_train_ltv, y_train_ltv)

# Предсказываем
y_pred_ltv = ltv_model.predict(X_test_ltv)

# Оцениваем
mae = mean_absolute_error(y_test_ltv, y_pred_ltv)
r2 = r2_score(y_test_ltv, y_pred_ltv)

print(f"Mean Absolute Error: {mae:.2f} руб")
print(f"R² Score: {r2:.3f}")

# Важность признаков
ltv_feature_importance = pd.DataFrame({
    'feature': features_ltv,
    'importance': ltv_model.feature_importances_
}).sort_values('importance', ascending=False)

print("\nВажность признаков для LTV:")
print(ltv_feature_importance)

Подход 3: Probabilistic Model (BG/NBD + Gamma-Gamma)

Более продвинутый подход использует библиотеку lifetimes:

from lifetimes import BetaGeoFitter, GammaGammaFitter

# Подготовка данных в формате RFM
from lifetimes.utils import summary_data_from_transaction_data

rfm_data = summary_data_from_transaction_data(
    transactions,
    'user_id',
    'order_date',
    'order_value',
    observation_period_end='2024-12-31'
)

# BG/NBD модель для предсказания частоты покупок
bgf = BetaGeoFitter(penalizer_coef=0.0)
bgf.fit(rfm_data['frequency'], rfm_data['recency'], rfm_data['T'])

# Gamma-Gamma модель для предсказания среднего чека
returning_customers = rfm_data[rfm_data['frequency'] > 0]

ggf = GammaGammaFitter(penalizer_coef=0.0)
ggf.fit(returning_customers['frequency'], returning_customers['monetary_value'])

# Предсказываем LTV на 12 месяцев вперёд
rfm_data['predicted_purchases_12m'] = bgf.predict(
    12,  # месяцев
    rfm_data['frequency'],
    rfm_data['recency'],
    rfm_data['T']
)

# Предсказываем средний чек
rfm_data['predicted_avg_order_value'] = ggf.conditional_expected_average_profit(
    rfm_data['frequency'],
    rfm_data['monetary_value']
)

# LTV = количество покупок × средний чек
rfm_data['predicted_ltv_12m'] = (
    rfm_data['predicted_purchases_12m'] * 
    rfm_data['predicted_avg_order_value']
)

print(rfm_data[['predicted_ltv_12m']].describe())

6. Как применять предсказания на практике

Стратегия 1: Сегментация по риску churn

СегментChurn probabilityДействия
Высокий риск> 0.7Персональный outreach, спецпредложение, call от customer success
Средний риск0.3 - 0.7Автоматический email с бонусом, survey, напоминание о ценности
Низкий риск< 0.3Стандартный nurturing, upsell предложения

Стратегия 2: Персонализация по LTV

СегментPredicted LTVСтратегия
VIP> 50 000₽Персональный менеджер, premium support, ранний доступ к фичам
High value20 000 - 50 000₽Приоритетная поддержка, персональные рекомендации
Medium value5 000 - 20 000₽Автоматизированный nurturing, upsell кампании
Low value< 5 000₽Self-service, минимальные затраты на retention

Стратегия 3: Матрица Churn × LTV

Самая мощная стратегия: комбинируем обе метрики

СегментОписаниеПриоритетДействия
High LTV + High Churn RiskЦенные клиенты на грани ухода🔴 КритичноСрочный call, персональное предложение, executive involvement
High LTV + Low Churn RiskЛояльные ценные клиенты🟢 РазвитиеUpsell, cross-sell, превращение в адвокатов
Low LTV + High Churn RiskНеценные клиенты уходят⚪ НизкийАвтоматический win-back, минимальные вложения
Low LTV + Low Churn RiskСтабильные недорогие🟡 NurturingПопытки увеличить engagement и LTV

Пример автоматизации

# Скрипт который каждый день скорит пользователей и триггерит действия

import requests

# Загружаем модели
churn_model = load_model('churn_model.pkl')
ltv_model = load_model('ltv_model.pkl')

# Получаем активных пользователей
active_users = get_active_users()

# Скорим
active_users['churn_prob'] = churn_model.predict_proba(active_users[churn_features])[:, 1]
active_users['predicted_ltv'] = ltv_model.predict(active_users[ltv_features])

# Сегментируем
def segment_user(row):
    if row['predicted_ltv'] > 50000:
        ltv_segment = 'VIP'
    elif row['predicted_ltv'] > 20000:
        ltv_segment = 'High'
    elif row['predicted_ltv'] > 5000:
        ltv_segment = 'Medium'
    else:
        ltv_segment = 'Low'
    
    if row['churn_prob'] > 0.7:
        churn_segment = 'High Risk'
    elif row['churn_prob'] > 0.3:
        churn_segment = 'Medium Risk'
    else:
        churn_segment = 'Low Risk'
    
    return f"{ltv_segment}_{churn_segment}"

active_users['segment'] = active_users.apply(segment_user, axis=1)

# Триггерим действия
for segment, users in active_users.groupby('segment'):
    if segment == 'VIP_High Risk':
        # Отправляем в CRM для персонального outreach
        send_to_crm(users, priority='urgent')
    elif segment == 'High_High Risk':
        # Автоматический email с промокодом
        send_retention_email(users, discount=20)
    elif segment == 'VIP_Low Risk':
        # Upsell кампания
        send_upsell_offer(users)
    # и так далее...

7. Инструменты и библиотеки

Python библиотеки

  • scikit-learn: базовые ML алгоритмы (Random Forest, Logistic Regression, XGBoost)

  • lifetimes: специализированная библиотека для CLV (BG/NBD, Gamma-Gamma модели)

  • pandas: работа с данными

  • matplotlib / seaborn: визуализация

  • xgboost / lightgbm: продвинутые gradient boosting модели

# Установка
pip install scikit-learn lifetimes pandas matplotlib seaborn xgboost

Платформы для churn prediction

  • Mixpanel: встроенная churn prediction для продуктовой аналитики

  • Amplitude: behavioral cohorts и retention анализ

  • ChurnZero: B2B SaaS customer success платформа

  • Gainsight: enterprise customer success с ML

  • Pecan: automated predictive analytics

Когда использовать готовые платформы vs строить своё

Используйте готовую платформу если:

  • У вас нет data scientist в команде

  • Нужно быстро получить результат

  • Бюджет позволяет ($500-5000/месяц)

  • Хотите готовые интеграции с CRM/email

Стройте своё если:

  • Есть data scientist / аналитик который знает Python

  • Нужна кастомизация под специфику бизнеса

  • Большой объём данных (платформы дорожают)

  • Хотите контроль и гибкость

8. Типичные ошибки начинающих

Ошибка 1: Data leakage (утечка данных)

Использование информации из будущего для предсказания.

Плохо: Включить в признаки "количество support tickets за последний месяц перед churn". Проблема: это уже следствие того что пользователь недоволен.

Хорошо: Использовать только данные которые известны ДО момента когда нужно сделать предсказание.

Ошибка 2: Игнорирование несбалансированности классов

Если churned пользователей 10%, а не ушедших 90%, модель может просто всегда предсказывать "не уйдёт" и иметь 90% accuracy, но быть бесполезной.

Решение:

  • Используйте class_weight='balanced' в модели

  • SMOTE (синтетическая генерация примеров minority класса)

  • Фокус на Precision/Recall вместо Accuracy

Ошибка 3: Обучение на всех данных без test set

Модель покажет отличные метрики на том же датасете на котором обучалась, но не будет работать на новых данных.

Решение: Всегда делайте train/test split или используйте cross-validation.

Ошибка 4: Забыть про временное разделение

При обучении модели churn нужно использовать исторические данные для обучения и более свежие для теста.

Плохо: Случайный split на train/test

Хорошо: Обучаем на данных 2024 года, тестируем на 2025

9. Чек-лист: с чего начать

Неделя 1: Подготовка

  1. ☐ Определите что такое churn для вашего продукта

  2. ☐ Соберите данные за последние 12 месяцев минимум

  3. ☐ Убедитесь что есть метка churned/not churned

  4. ☐ Выберите 5-10 ключевых признаков для начала

Неделя 2: Первая модель churn

  1. ☐ Загрузите данные в pandas

  2. ☐ Разделите на train/test (80/20)

  3. ☐ Обучите Random Forest модель

  4. ☐ Оцените на тестовых данных (ROC-AUC > 0.7 хорошо для начала)

  5. ☐ Посмотрите важность признаков

Неделя 3: Применение

  1. ☐ Скорите всех активных пользователей

  2. ☐ Выберите топ 100 с высоким риском

  3. ☐ Запустите пилотную retention кампанию

  4. ☐ Измерьте результаты через месяц

Неделя 4: LTV модель

  1. ☐ Соберите транзакционные данные

  2. ☐ Вычислите RFM метрики

  3. ☐ Постройте простую regression модель

  4. ☐ Сегментируйте пользователей по LTV

Месяц 2: Оптимизация

  1. ☐ Добавьте больше признаков

  2. ☐ Попробуйте другие алгоритмы (XGBoost, LightGBM)

  3. ☐ Настройте гиперпараметры

  4. ☐ Автоматизируйте скоринг (скрипт каждый день)

  5. ☐ Интегрируйте с CRM/email платформой

Месяц 3: Измерение эффекта

  1. ☐ Посчитайте сколько пользователей спасли от churn

  2. ☐ Измерьте ROI (сколько сэкономили vs затраты на retention)

  3. ☐ Оптимизируйте стратегии по сегментам

  4. ☐ Масштабируйте на всю базу

Заключение

Предиктивная аналитика для churn и LTV звучит сложно, но на практике можно начать с простых моделей и получить результат.

Ключевые выводы:

  1. Churn prediction помогает спасти пользователей ДО того как они ушли. Снижение churn на 5% = рост прибыли на 25-95%

  2. LTV prediction помогает правильно распределить ресурсы. Тратить больше на привлечение и retention высокоценных пользователей

  3. Можно начать с минимума данных. Даже 5 признаков дадут работающую модель

  4. Random Forest отличный старт. Простой в использовании, даёт хорошие результаты

  5. Самое важное не модель, а действия. Лучшая модель бесполезна если не триггерит retention активности

С чего начать прямо сейчас:

  1. Определите что такое churn для вашего продукта

  2. Соберите данные за последний год

  3. Выберите 5-10 признаков

  4. Обучите первую модель (это займёт 2-3 часа с примерами из этой статьи)

  5. Скорите пользователей и запустите пилот на топ 100 с риском churn

Через месяц вы увидите первые результаты. Через три месяца предиктивная аналитика станет стандартной частью вашего процесса.

В мире где привлечение клиента стоит всё дороже, умение предсказывать кто останется и сколько принесёт становится не конкурентным преимуществом, а необходимостью выживания.

А лучшие вакансии для системных, бизнес и дата аналитиков ищите на hirehi.ru