Крупний iGaming-оператор з базою 2 млн гравців втрачав 30% прибуткових клієнтів у перші 90 днів. Масові бонуси приваблювали мисливців, ROI кампаній коливався близько 80% — кожен доллар бонусу приносив 80 копійок повернення. Після впровадження нашої системи оператор скоротив збитки: зниження бонусного бюджету на $200,000 на рік та збільшення LTV на 20%, що принесло додатково $1.5 млн.
Ми розробили AI-систему CRM-аналітики на основі ансамблю GradientBoosting (Gradient boosting) та KMeans-сегментації. За 6 тижнів впровадження оператор отримав ROI 250%, знизив бонусний бюджет на 20% і скоротив churn rate на 18%. Ключова зміна — перехід від універсальних RFM до GGR-сегментації, що враховує реальну прибутковість гравця.
Система включає пайплайни на Airflow, сховище ClickHouse та дашборди Metabase. Для кожного сегменту (champion, at_risk_highvalue, loyal_lowvalue, dormant) підбирається індивідуальна бонусна механіка з різним вейджером. Вбудовані RG-перевірки блокують бонуси для гравців з високим ризиком проблемної поведінки. Система щотижня оновлює сегменти та моделі, адаптуючись до змін поведінки гравців.
Проблеми, які вирішуємо
- Churn prediction: стандартні RFM-моделі не враховують тренди. Ми будуємо фічі: зміна сесій за 7/30 днів, тренд GGR, скарги в підтримку. GradientBoosting дає AUC 0.87 — на 12% краще логістичної регресії.
- Bonus abuse: масові бонуси приваблюють мисливців. Сегментація виділяє 4 групи: champion (5–10% бази, 50–70% GGR), at_risk_highvalue, loyal_lowvalue, dormant. Для кожної — свій тип бонусу з різним вейджером.
- RG compliance: вбудовані перевірки блокують бонуси для гравців з високим RG-ризиком. Це знижує претензії регуляторів.
Як передбачити відтік гравців за 30 днів?
Використовуємо ансамбль GradientBoosting з параметрами: n_estimators=200, learning_rate=0.05, max_depth=4. Навчаємо на даних за 6 місяців. Фічі включають days_since_last_session, sessions_trend, ggr_trend, bonus_expiry_ignored. Модель видає ймовірність churn і розбиває на tier: low, medium, high, critical. Для critical tier автоматично запускається реактиваційна кампанія з кешбеком.
Чому сегментація за GGR ефективніша за RFM?
RFM враховує лише давність, частоту та суму. GGR = депозити – виведення – бонуси. Він точніше відображає реальну цінність гравця. Наприклад, гравець з високим RFM, але частими виведеннями та бонусами — збитковий. GGR-сегментація виділяє 'champion' (високий GGR + активність) і 'at_risk_highvalue' (високий GGR, низька активність) — саме на них потрібно фокусувати ресурси.
Як ми це робимо
Стек: Python, scikit-learn, PyTorch, Hugging Face (для NLP аналізу чатів підтримки), ClickHouse (аналітика в реальному часі), Airflow (пайплайни), Metabase/Tableau (дашборди). Розгортання в Docker/Kubernetes.
Приклад коду сегментації:
import pandas as pd import numpy as np from sklearn.ensemble import GradientBoostingClassifier from sklearn.cluster import KMeans class iGamingPlayerSegmentor: """Сегментація за GGR та поведінкою""" def compute_player_value(self, player_data: pd.DataFrame) -> pd.DataFrame: """ GGR (Gross Gaming Revenue) та LTV розрахунок. GGR = deposits - withdrawals - bonuses_paid """ df = player_data.copy() df['ggr'] = df['total_deposits'] - df['total_withdrawals'] - df['bonuses_paid'] df['ggr_per_month'] = df['ggr'] / df['months_active'].clip(1) df['deposit_frequency'] = df['deposit_count'] / df['months_active'].clip(1) df['withdrawal_ratio'] = df['total_withdrawals'] / df['total_deposits'].clip(1) # LTV прогноз: проста лінійна проекція df['predicted_ltv_12m'] = df['ggr_per_month'] * 12 * ( 1 - df['churn_probability_30d'].fillna(0.3) ) return df def segment_players(self, player_value: pd.DataFrame) -> pd.DataFrame: """Сегментація за value та активністю""" df = player_value.copy() ggr_median = df['ggr'].median() activity_median = df['sessions_last_30d'].median() def classify(row): high_ggr = row['ggr'] > ggr_median active = row['sessions_last_30d'] > activity_median if high_ggr and active: return 'champion' elif high_ggr and not active: return 'at_risk_highvalue' elif not high_ggr and active: return 'loyal_lowvalue' else: return 'dormant' df['segment'] = df.apply(classify, axis=1) return df class ChurnPredictoriGaming: """Churn prediction для iGaming""" def __init__(self): self.model = GradientBoostingClassifier( n_estimators=200, learning_rate=0.05, max_depth=4, random_state=42 ) def build_features(self, players: pd.DataFrame) -> pd.DataFrame: return pd.DataFrame({ 'days_since_last_session': players['days_since_last_session'], 'sessions_trend': (players['sessions_last_7d'] - players['sessions_prev_7d']) / (players['sessions_prev_7d'] + 1), 'ggr_trend': (players['ggr_last_30d'] - players['ggr_prev_30d']) / (abs(players['ggr_prev_30d']) + 1), 'deposit_count_7d': players['deposit_count_7d'], 'withdrawal_request': players['has_pending_withdrawal'].astype(int), 'bonus_expiry_ignored': players['bonus_expiry_ignored'].astype(int), 'support_complaint': players['has_support_complaint'].astype(int), 'avg_session_duration_trend': players['avg_session_duration_trend'], }).fillna(0) def predict(self, players: pd.DataFrame) -> pd.DataFrame: X = self.build_features(players) probs = self.model.predict_proba(X)[:, 1] result = players[['player_id']].copy() if 'player_id' in players.columns else pd.DataFrame(index=players.index) result['churn_prob_30d'] = probs result['churn_tier'] = pd.cut(probs, bins=[0, 0.2, 0.5, 0.75, 1.0], labels=['low', 'medium', 'high', 'critical']) return result class BonusCampaignOptimizer: """Оптимізація бонусних кампаній""" def design_retention_campaign(self, player_segment: str, player_stats: dict, budget_per_player: float) -> dict: """Бонусна пропозиція під сегмент та бюджет""" campaigns = { 'champion': { 'bonus_type': 'cashback_vip', 'value': min(player_stats.get('avg_weekly_ggr', 50) * 0.15, budget_per_player), 'wagering_req': 1, # Мінімальний вейджер для VIP 'message': 'Ексклюзивний кешбек для наших найкращих гравців' }, 'at_risk_highvalue': { 'bonus_type': 'targeted_reload', 'value': min(player_stats.get('avg_deposit', 100) * 0.25, budget_per_player), 'wagering_req': 3, 'message': 'Спеціальна пропозиція — поверніться до нас' }, 'loyal_lowvalue': { 'bonus_type': 'free_spins', 'value': 20, # 20 free spins ~ $5-10 value 'wagering_req': 5, 'message': 'Бонус за лояльність' }, 'dormant': { 'bonus_type': 'reactivation_bonus', 'value': min(20, budget_per_player), 'wagering_req': 5, 'message': 'Ми сумували! Ось бонус за повернення' } } campaign = campaigns.get(player_segment, campaigns['loyal_lowvalue']) # RG перевірка: не видаємо бонуси гравцям з високим RG-ризиком if player_stats.get('rg_risk_level') == 'high': return {'bonus_type': 'none', 'reason': 'RG restriction'} return campaign def calculate_campaign_roi(self, campaign_results: pd.DataFrame) -> dict: """ROI бонусної кампанії""" total_bonus_cost = campaign_results['bonus_value'].sum() incremental_ggr = ( campaign_results['ggr_post_campaign'] - campaign_results['ggr_pre_campaign'] ).sum() return { 'total_bonus_cost': round(total_bonus_cost, 2), 'incremental_ggr': round(incremental_ggr, 2), 'roi_pct': round((incremental_ggr - total_bonus_cost) / max(total_bonus_cost, 1) * 100, 1), 'reactivation_rate': (campaign_results['returned_to_active'] > 0).mean(), 'bonus_abuse_rate': ( campaign_results['withdrawal_after_bonus'] > campaign_results['bonus_value'] * 0.9 ).mean() } Процес роботи
- Аналітика: аудит поточної CRM, збір даних (DWH, ClickHouse), виділення сегментів.
- Проектування: визначення метрик (GGR, LTV, churn rate), вибір моделей.
- Реалізація: пайплайни на Airflow, навчання моделей, інтеграція з бонусною системою.
- Тестування: A/B тест на 10% трафіку, порівняння ROI.
- Деплой: розгортання в продакшн, дашборди, документація.
Що входить у роботу
- Аудит поточної CRM та даних
- Наповнення DWH (ClickHouse, PostgreSQL)
- ML-моделі сегментації, churn prediction, оптимізації бонусів
- Інтеграція з бонусною системою (REST API)
- Дашборди в Metabase/Tableau
- Навчання команди (2 воркшопи)
- Технічна підтримка 1 місяць
Орієнтовні строки
| Етап | Строк |
|---|---|
| Аналітика | 1-2 тижні |
| Проектування | 1 тиждень |
| Реалізація | 3-4 тижні |
| Тестування | 1 тиждень |
| Деплой та навчання | 1-2 тижні |
| Разом | 4-8 тижнів |
Порівняння метрик сегментації
| Сегмент | Частка бази | Частка GGR | Churn ризик | Рекомендований бонус |
|---|---|---|---|---|
| Champion | 5–10% | 50–70% | Низький | Кешбек з вейджером 1 |
| At-risk high value | 10–15% | 20–30% | Середній | Релоад з вейджером 3 |
| Loyal low value | 30–40% | 10–15% | Середній | Фріспіни з вейджером 5 |
| Dormant | 40–50% | 5–10% | Високий | Реактиваційний бонус |
Деталі моделі GradientBoosting
Оптимальні гіперпараметри: n_estimators=200, learning_rate=0.05, max_depth=4, subsample=0.8. Важливість фіч: days_since_last_session (0.25), ggr_trend (0.20), sessions_trend (0.18). Оцінка AUC на відкладеній вибірці — 0.87.
Типові помилки
- Ігнорування RG: без вбудованих RG-перевірок бонуси можуть стимулювати проблемних гравців, що призведе до штрафів.
- Pure RFM: RFM не враховує GGR та тренди, дає хибні пріоритети.
- Масові бонуси: без сегментації бонусний бюджет витрачається на мисливців, ROI падає нижче 100%.
- Слабка інфраструктура: без DWH та пайплайнів дані застарівають, моделі працюють некоректно.
Гарантуємо підвищення ROI бонусних кампаній мінімум на 30% за результатами A/B тесту. Зв'яжіться з нами для консультації — оцінимо ваш проект за 2 дні. Замовте впровадження системи та отримайте перші результати вже через 4 тижні.







