Разработка AI-системы анализа поведения игроков Player Analytics

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Разработка AI-системы анализа поведения игроков Player Analytics
Средняя
~1-2 недели
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1240
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1167
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    867
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1084
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    563
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    829

AI-система аналитики поведения игроков

Аналитика игроков — ключевой инструмент монетизации и удержания в gaming. Когда игрок перестаёт прогрессировать, злится или скучает — это поведенческие сигналы, видимые в данных за минуты до churn. AI-система детектирует их в реальном времени и запускает персонализированные интервенции.

Профилирование игрока и сегментация

import numpy as np
import pandas as pd
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import GradientBoostingClassifier

class PlayerProfiler:
    """Многомерное профилирование игрока"""

    def extract_behavioral_features(self, sessions: pd.DataFrame,
                                     player_id: str,
                                     window_days: int = 30) -> dict:
        """Признаки из игровых сессий за период"""
        player_sessions = sessions[
            (sessions['player_id'] == player_id) &
            (sessions['date'] >= pd.Timestamp.now() - pd.Timedelta(days=window_days))
        ]

        if player_sessions.empty:
            return {}

        return {
            # Активность
            'sessions_per_week': len(player_sessions) / (window_days / 7),
            'avg_session_minutes': player_sessions['duration_minutes'].mean(),
            'total_play_hours': player_sessions['duration_minutes'].sum() / 60,
            'days_active': player_sessions['date'].dt.date.nunique(),

            # Прогресс
            'avg_level_gain_per_session': player_sessions['level_gained'].mean(),
            'completion_rate': player_sessions['objective_completed'].mean(),
            'win_rate': player_sessions['wins'].sum() / max(player_sessions['games_played'].sum(), 1),

            # Монетизация
            'total_spent_usd': player_sessions['purchase_usd'].sum(),
            'purchase_count': (player_sessions['purchase_usd'] > 0).sum(),
            'avg_purchase_usd': player_sessions[player_sessions['purchase_usd'] > 0]['purchase_usd'].mean() or 0,

            # Социальность
            'social_interactions': player_sessions['chat_messages'].sum() + player_sessions['party_plays'].sum(),
            'guild_member': int(player_sessions['guild_id'].notna().any()),

            # Разнообразие
            'game_modes_played': player_sessions['game_mode'].nunique(),
            'avg_frustration_events': player_sessions.get('rage_quits', pd.Series([0])).mean(),
        }

    def segment_players(self, player_features: pd.DataFrame,
                         n_segments: int = 6) -> pd.DataFrame:
        """K-Means сегментация игроков"""
        feature_cols = [c for c in player_features.columns if c != 'player_id']
        X = player_features[feature_cols].fillna(0)

        scaler = StandardScaler()
        X_scaled = scaler.fit_transform(X)

        kmeans = KMeans(n_clusters=n_segments, random_state=42, n_init=10)
        player_features['segment'] = kmeans.fit_predict(X_scaled)

        # Интерпретация сегментов по центроидам
        centroids = pd.DataFrame(
            scaler.inverse_transform(kmeans.cluster_centers_),
            columns=feature_cols
        )

        segment_labels = self._label_segments(centroids)
        player_features['segment_label'] = player_features['segment'].map(segment_labels)

        return player_features

    def _label_segments(self, centroids: pd.DataFrame) -> dict:
        """Автоматическая маркировка сегментов по характеристикам"""
        labels = {}
        for i, row in centroids.iterrows():
            spend = row.get('total_spent_usd', 0)
            sessions = row.get('sessions_per_week', 0)
            social = row.get('social_interactions', 0)

            if spend > 50 and sessions > 10:
                labels[i] = 'whale'
            elif spend > 20:
                labels[i] = 'dolphin'
            elif sessions > 14:
                labels[i] = 'hardcore_f2p'
            elif social > 100:
                labels[i] = 'social_player'
            elif sessions < 2:
                labels[i] = 'casual_at_risk'
            else:
                labels[i] = 'regular'

        return labels


class ChurnPredictor:
    """Предсказание оттока игроков"""

    def __init__(self):
        self.model = GradientBoostingClassifier(
            n_estimators=200, learning_rate=0.05, max_depth=4, random_state=42
        )

    def build_churn_features(self, player_history: pd.DataFrame) -> pd.DataFrame:
        """Признаки, предсказывающие churn в горизонте 14 дней"""
        features = pd.DataFrame()

        features['sessions_last_7d'] = player_history['sessions_7d']
        features['sessions_prev_7d'] = player_history['sessions_prev_7d']
        features['session_trend'] = (
            (features['sessions_last_7d'] - features['sessions_prev_7d']) /
            (features['sessions_prev_7d'] + 1)
        )
        features['days_since_last_login'] = player_history['days_since_last_login']
        features['avg_session_drop_min'] = player_history['avg_session_drop_minutes']
        features['level_progression_rate'] = player_history['level_gain_per_hour']
        features['win_rate_last_10'] = player_history['win_rate_last_10_games']
        features['frustration_events'] = player_history['rage_quits_7d']
        features['purchase_recency_days'] = player_history['days_since_last_purchase']
        features['social_activity_trend'] = player_history['social_activity_trend']

        return features.fillna(0)

    def predict_churn_risk(self, players: pd.DataFrame) -> pd.DataFrame:
        """Скор риска оттока для каждого игрока"""
        X = self.build_churn_features(players)
        churn_probabilities = self.model.predict_proba(X)[:, 1]

        result = players[['player_id']].copy()
        result['churn_probability_14d'] = churn_probabilities
        result['churn_risk'] = pd.cut(
            churn_probabilities,
            bins=[0, 0.2, 0.5, 0.75, 1.0],
            labels=['low', 'medium', 'high', 'critical']
        )
        return result


class PlayerInterventionEngine:
    """Персонализированные интервенции для удержания"""

    INTERVENTIONS = {
        'whale': {
            'critical': {'type': 'vip_outreach', 'channel': 'personal_manager'},
            'high': {'type': 'exclusive_content', 'channel': 'in_game_popup'},
        },
        'regular': {
            'critical': {'type': 'comeback_bonus', 'channel': 'push_notification'},
            'high': {'type': 'limited_offer', 'channel': 'email'},
        },
        'hardcore_f2p': {
            'critical': {'type': 'challenge_event', 'channel': 'in_game'},
            'high': {'type': 'new_content_unlock', 'channel': 'push_notification'},
        },
        'casual_at_risk': {
            'critical': {'type': 'simplified_quest', 'channel': 'push_notification'},
            'high': {'type': 'social_invite', 'channel': 'email'},
        }
    }

    def select_intervention(self, player_segment: str,
                             churn_risk: str,
                             player_context: dict) -> dict:
        segment_interventions = self.INTERVENTIONS.get(player_segment, self.INTERVENTIONS['regular'])
        intervention = segment_interventions.get(churn_risk, {'type': 'generic_reminder', 'channel': 'push'})

        # Персонализация контента интервенции
        intervention['personalized_offer'] = self._create_offer(
            player_segment, player_context
        )

        return intervention

    def _create_offer(self, segment: str, context: dict) -> dict:
        offers = {
            'whale': {'type': 'exclusive_skin', 'value': 'Limited Edition Character'},
            'dolphin': {'type': 'currency_bonus', 'value': '50% bonus gems'},
            'hardcore_f2p': {'type': 'xp_boost', 'value': '2x XP for 3 days'},
            'casual_at_risk': {'type': 'starter_pack', 'value': 'Welcome back pack'},
        }
        return offers.get(segment, {'type': 'general_bonus', 'value': 'Daily reward'})

Предсказание churn в gaming достигает AUC 0.82-0.88 с 7-дневным горизонтом. Персонализированные интервенции для сегмента «высокий риск» удерживают 25-35% потенциально уходящих игроков. Whale-сегмент (5-10% игроков) генерирует 50-70% revenue — приоритет при скоринге критических.