AI-система персонализации iGaming опыта
iGaming персонализация — это не только рекомендация игр. Это адаптация лобби, бонусных предложений, порогов ответственной игры и интерфейса под индивидуальный профиль каждого игрока. При этом RG (Responsible Gambling) инструменты — не опциональная функция, а регуляторный стандарт.
Персонализация игрового лобби
import numpy as np
import pandas as pd
from sklearn.ensemble import GradientBoostingClassifier
from anthropic import Anthropic
import json
class iGamingPersonalizationEngine:
"""Персонализация для онлайн-казино и ставок"""
GAME_CATEGORIES = ['slots', 'live_casino', 'table_games', 'poker', 'sports_betting', 'virtual_sports']
def build_player_preferences(self, session_history: pd.DataFrame,
player_id: str) -> dict:
"""Профиль предпочтений игрока"""
player_sessions = session_history[session_history['player_id'] == player_id]
if player_sessions.empty:
return {'player_id': player_id, 'is_new': True}
# Предпочтения по категориям (взвешенные по времени игры)
category_time = player_sessions.groupby('game_category')['session_duration_min'].sum()
total_time = category_time.sum()
category_preferences = (category_time / max(total_time, 1)).to_dict()
# Предпочтения по ставкам
bet_sizes = player_sessions['avg_bet_size'].dropna()
# Сессионные паттерны
return {
'player_id': player_id,
'category_preferences': category_preferences,
'top_game_category': category_time.idxmax() if len(category_time) > 0 else 'slots',
'avg_bet_size': bet_sizes.mean() if len(bet_sizes) > 0 else 0,
'avg_session_duration_min': player_sessions['session_duration_min'].mean(),
'preferred_session_time': int(player_sessions['session_start_hour'].mode().iloc[0]) if len(player_sessions) > 0 else 19,
'device_preference': player_sessions['device'].mode().iloc[0] if 'device' in player_sessions.columns else 'mobile',
'total_sessions': len(player_sessions),
'volatility_preference': self._infer_volatility_preference(player_sessions),
}
def _infer_volatility_preference(self, sessions: pd.DataFrame) -> str:
"""Предпочтение волатильности из паттернов игры"""
if 'game_volatility' not in sessions.columns:
return 'medium'
preferred_vol = sessions.groupby('game_volatility')['session_duration_min'].sum().idxmax()
return preferred_vol if preferred_vol else 'medium'
def personalize_lobby(self, player_profile: dict,
available_games: pd.DataFrame,
n_featured: int = 6) -> dict:
"""Персонализация лобби казино"""
if player_profile.get('is_new'):
return self._default_lobby(available_games, n_featured)
top_category = player_profile.get('top_game_category', 'slots')
vol_pref = player_profile.get('volatility_preference', 'medium')
games = available_games.copy()
# Скоринг игр
games['score'] = 0.0
# Категорийный матч
cat_prefs = player_profile.get('category_preferences', {})
games['score'] += games['category'].map(cat_prefs).fillna(0.05) * 0.40
# Волатильность
games['score'] += (games.get('volatility', 'medium') == vol_pref).astype(float) * 0.20
# Новинки и популярные
games['score'] += games.get('is_new', False).astype(float) * 0.10
games['score'] += (games.get('popularity_rank', 100) < 20).astype(float) * 0.15
# Джекпоты для высокорисковых игроков
if vol_pref == 'high':
games['score'] += games.get('has_jackpot', False).astype(float) * 0.15
else:
games['score'] += 0.15 # Равномерный бонус для обычных игр
featured = games.nlargest(n_featured, 'score').to_dict('records')
return {
'featured_games': featured,
'recommended_category': top_category,
'personalized_banner': self._get_personalized_banner(player_profile),
'bonus_offer': self._select_bonus(player_profile)
}
def _default_lobby(self, games: pd.DataFrame, n: int) -> dict:
return {
'featured_games': games.nlargest(n, 'popularity_rank').to_dict('records'),
'recommended_category': 'slots',
'personalized_banner': None,
'bonus_offer': {'type': 'welcome_bonus'}
}
def _get_personalized_banner(self, profile: dict) -> dict:
"""Персонализированный баннер в лобби"""
if profile.get('total_sessions', 0) > 50:
return {'type': 'loyalty_status', 'message': 'VIP игрок — эксклюзивные турниры'}
elif profile.get('top_game_category') == 'live_casino':
return {'type': 'live_tables', 'message': 'Новые live столы уже доступны'}
return {'type': 'general_promo'}
def _select_bonus(self, profile: dict) -> dict:
"""Подбор бонусного предложения под профиль"""
avg_bet = profile.get('avg_bet_size', 10)
category = profile.get('top_game_category', 'slots')
if category == 'sports_betting':
return {'type': 'free_bet', 'amount': round(avg_bet * 5, -1)}
elif category == 'live_casino':
return {'type': 'cashback', 'percentage': 10}
elif avg_bet > 50:
return {'type': 'high_roller_bonus', 'amount': round(avg_bet * 10, -1)}
else:
return {'type': 'free_spins', 'count': 20}
class ResponsibleGamblingMonitor:
"""
Мониторинг признаков проблемного игрового поведения.
ОБЯЗАТЕЛЕН по регуляторным требованиям (MGA, UKGC, Роскомнадзор).
"""
RG_INDICATORS = {
'session_duration_spike': 'Значительный рост длительности сессий',
'deposit_frequency_increase': 'Учащение депозитов',
'loss_chasing': 'Погоня за потерями (рост ставок после проигрыша)',
'time_of_day_shift': 'Ночные сессии (после 01:00)',
'multiple_sessions_per_day': 'Более 3 сессий в день',
}
def compute_rg_risk_score(self, player_behavior: dict) -> dict:
"""Оценка риска проблемного игрового поведения"""
risk_score = 0.0
triggered_indicators = []
if player_behavior.get('avg_session_duration_change_pct', 0) > 50:
risk_score += 0.25
triggered_indicators.append(self.RG_INDICATORS['session_duration_spike'])
if player_behavior.get('deposit_frequency_7d', 0) > 5:
risk_score += 0.20
triggered_indicators.append(self.RG_INDICATORS['deposit_frequency_increase'])
if player_behavior.get('avg_bet_after_loss', 0) > player_behavior.get('avg_normal_bet', 10) * 2:
risk_score += 0.30
triggered_indicators.append(self.RG_INDICATORS['loss_chasing'])
if player_behavior.get('night_session_ratio', 0) > 0.30:
risk_score += 0.15
triggered_indicators.append(self.RG_INDICATORS['time_of_day_shift'])
rg_level = 'high' if risk_score > 0.6 else 'medium' if risk_score > 0.3 else 'low'
return {
'rg_risk_score': round(min(risk_score, 1.0), 2),
'rg_level': rg_level,
'triggered_indicators': triggered_indicators,
'recommended_action': (
'mandatory_interaction' if rg_level == 'high'
else 'soft_limit_suggestion' if rg_level == 'medium'
else 'none'
)
}
Персонализация лобби повышает session depth (количество игр за сессию) на 15-25% и retention rate на 10-15%. Обязательное условие: RG-мониторинг должен работать параллельно с персонализацией — повышение engagement и защита уязвимых игроков не противоречат друг другу при правильной реализации.







