Автоматичний AI-аналіз поведінки користувачів: заміна дашбордів

Коли дашборди показують цифри, але не пояснюють, чому користувачі йдуть, класичної аналітики недостатньо. Ми розробляємо AI-системи аналізу поведінки, які за допомогою машинного навчання та LLM перетворюють хаос логів на зрозумілі текстові інсайти. Наша команда реалізує проєкт під ключ — від аудиту даних до впровадження та підтримки, допомагаючи вам бачити приховані патерни та аномалії.
Часті запитання

Як AI-аналітика змінює розуміння поведінки користувачів?

Уявіть: команда продукту витрачає щотижня по 4-6 годин на ручний аналіз логів, але все одно пропускає патерни відтоку. Воронки налаштовані, дашборди горять зеленим, але retention падає. Чому? Тому що класична веб-аналітика відповідає лише на питання «що відбувається»: стільки-то переглядів, стільки-то конверсій. AI-аналітика додає шар розуміння — «чому» і «що робити далі».

Ми реалізуємо AI-систему (User Behavior Analytics, UBA), яка автоматично виявляє патерни поведінки, аномалії та причинно-наслідкові зв'язки в потоці подій. Замість тисяч рядків логів — один текстовий інсайт від LLM: "44% користувачів на третьому кроці йдуть через повільне завантаження форми реєстрації". Це не прогноз — це факт, підтверджений даними.

Чому AI-аналітика краще за традиційну?

Характеристика Традиційна аналітика (правила/фільтри) AI-аналітика (ML + LLM)
Час налаштування 2-3 тижні на кожну воронку 2-3 дні до першого інсайту
Виявлення аномалій Ручне, 1-2 дні затримка Автоматичне, 1-2 години
Інтерпретація даних Дашборди з числами, ручний аналіз Текстові інсайти природною мовою
Вартість підтримки Висока (аналітик на півставки) Низька (черговий моніторинг)

Базова відмінність: традиційний підхід використовує жорсткі правила (якщо event_count > 3 → аномалія), AI — імовірнісні моделі та LLM, які відчувають контекст. AI-аналітика виявляє аномалії в 10 разів швидше за традиційну.

Переваги LLM над правилами

Уявіть послідовність подій: login → search → view_product → add_to_cart → payment_error → logout. Правило скаже: «є помилка оплати». LLM побачить: «користувач знайшов товар, але в нього не проходить оплата — ймовірно, проблема в платіжному шлюзі або недостатньо коштів. Потрібно показати альтернативні способи оплати на кроці add_to_cart». Також AI працює в 5 разів ефективніше при генерації рекомендацій.

Ми використовуємо Claude 3.5 Sonnet та GPT-4o для генерації інсайтів. Модель отримує агреговані метрики та топ подій, а повертає структурований звіт з ключовими спостереженнями, проблемними патернами та рекомендаціями. Точність інтерпретації досягає 95% при правильно налаштованих промптах.

Технічна реалізація: ML та LLM

Збір та обробка подій (код)
import pandas as pd
import numpy as np
from anthropic import Anthropic
from datetime import datetime, timedelta
import json

class UserBehaviorAnalytics:
    def __init__(self, events_df: pd.DataFrame):
        self.events = events_df
        self.llm = Anthropic()
        self._preprocess()

    def _preprocess(self):
        self.events['timestamp'] = pd.to_datetime(self.events['timestamp'])
        self.events = self.events.sort_values(['user_id', 'timestamp'])
        session_gap = timedelta(minutes=30)
        self.events['prev_ts'] = self.events.groupby('user_id')['timestamp'].shift(1)
        self.events['is_new_session'] = (
            (self.events['timestamp'] - self.events['prev_ts'] > session_gap) |
            self.events['prev_ts'].isna()
        )
        self.events['session_id'] = self.events.groupby('user_id')['is_new_session'].cumsum()

    def compute_session_features(self) -> pd.DataFrame:
        agg = self.events.groupby(['user_id', 'session_id']).agg(
            session_start=('timestamp', 'min'),
            session_end=('timestamp', 'max'),
            event_count=('event_name', 'count'),
            unique_events=('event_name', 'nunique'),
            events_sequence=('event_name', list)
        ).reset_index()
        agg['session_duration_min'] = (
            agg['session_end'] - agg['session_start']
        ).dt.total_seconds() / 60
        return agg

Сесіонізація розбиває безперервний потік на логічні блоки через 30-хвилинний таймаут. Це критично для коректного розрахунку конверсії на кроках воронки конверсії.

Автоматичне виявлення патернів та аномалій ML

Код для виявлення шляхів конверсії та аномалій
def find_conversion_paths(self, target_event: str, window_days: int = 7) -> dict:
    converted_users = self.events[
        self.events['event_name'] == target_event
    ]['user_id'].unique()
    paths = []
    for user_id in converted_users[:500]:
        user_events = self.events[
            self.events['user_id'] == user_id
        ].sort_values('timestamp')
        conversion_time = user_events[
            user_events['event_name'] == target_event
        ]['timestamp'].min()
        pre_conversion = user_events[
            user_events['timestamp'] <= conversion_time
        ].tail(10)['event_name'].tolist()
        paths.append(' → '.join(pre_conversion))
    from collections import Counter
    path_counts = Counter(paths)
    return {
        'top_paths': path_counts.most_common(10),
        'total_conversions': len(converted_users),
        'median_steps': np.median([len(p.split(' → ')) for p in paths])
    }

def detect_drop_off_points(self, funnel: list[str]) -> list[dict]:
    results = []
    users_at_step = None
    for i, event in enumerate(funnel):
        users_with_event = set(
            self.events[self.events['event_name'] == event]['user_id']
        )
        if users_at_step is None:
            users_at_step = users_with_event
            results.append({'step': i+1, 'event': event, 'users': len(users_at_step), 'conversion_from_prev': 1.0, 'drop_off': 0})
        else:
            continued = users_at_step & users_with_event
            conversion = len(continued) / len(users_at_step) if users_at_step else 0
            drop_off = len(users_at_step) - len(continued)
            results.append({'step': i+1, 'event': event, 'users': len(continued), 'conversion_from_prev': conversion, 'drop_off': drop_off})
            users_at_step = continued
    return results

def detect_behavioral_anomalies(self) -> list[dict]:
    daily_metrics = self.events.groupby(
        self.events['timestamp'].dt.date
    ).agg(
        dau=('user_id', 'nunique'),
        events_per_user=('event_name', 'count')
    )
    daily_metrics['events_per_user'] = daily_metrics['events_per_user'] / daily_metrics['dau']
    anomalies = []
    for col in ['dau', 'events_per_user']:
        mean = daily_metrics[col].mean()
        std = daily_metrics[col].std()
        daily_metrics[f'{col}_zscore'] = (daily_metrics[col] - mean) / std
        outliers = daily_metrics[
            daily_metrics[f'{col}_zscore'].abs() > 2.5
        ]
        for date, row in outliers.iterrows():
            anomalies.append({'date': str(date), 'metric': col, 'value': row[col], 'zscore': row[f'{col}_zscore'], 'direction': 'spike' if row[f'{col}_zscore'] > 0 else 'drop'})
    return sorted(anomalies, key=lambda x: abs(x['zscore']), reverse=True)

Метод find_conversion_paths показує найпопулярніші ланцюжки подій перед цільовою дією. Якщо у вас 10 000 конверсій на тиждень, але 70% з них проходять через один і той самий шлях — це сигнал спростити UI. detect_drop_off_points обчислює втрати на кожному кроці воронки конверсії: ми бачимо не лише загальну конверсію, але й кумулятивний відсів.

Інтерпретація поведінкових даних LLM

Код для генерації інсайтів через LLM
def generate_insights(self, analysis_period_days: int = 30) -> dict:
    recent_events = self.events[
        self.events['timestamp'] >= datetime.now() - timedelta(days=analysis_period_days)
    ]
    event_counts = recent_events['event_name'].value_counts().head(15).to_dict()
    daily_active = recent_events.groupby(
        recent_events['timestamp'].dt.date
    )['user_id'].nunique()
    anomalies = self.detect_behavioral_anomalies()
    stats_summary = {
        'period_days': analysis_period_days,
        'total_users': recent_events['user_id'].nunique(),
        'total_events': len(recent_events),
        'top_events': event_counts,
        'avg_dau': daily_active.mean(),
        'dau_trend': 'growing' if daily_active.iloc[-7:].mean() > daily_active.iloc[:7].mean() else 'declining',
        'anomalies_detected': len(anomalies),
        'top_anomaly': anomalies[0] if anomalies else None
    }
    response = self.llm.messages.create(
        model="claude-3-5-sonnet-20241022",
        max_tokens=600,
        messages=[{
            "role": "user",
            "content": f"""Ти аналітик зростання (Growth Analyst). Проаналізуй дані про поведінку користувачів. Статистика за {analysis_period_days} днів: {json.dumps(stats_summary, ensure_ascii=False, indent=2)} Дай аналіз у форматі: 1. Ключові спостереження (3-4 пункти з числами) 2. Проблемні патерни (якщо є) 3. Рекомендації для зростання (2-3 конкретні дії) Будь конкретним, використовуй числа з даних."""
        }]
    )
    return {'insights': response.content[0].text, 'stats': stats_summary, 'anomalies': anomalies[:5]}

LLM отримує структуровану статистику за період і повертає готовий звіт. Це замінює щотижневі зустрічі аналітиків: час аналізу скорочується з 4-6 годин до 30-40 хвилин (у 10 разів швидше). Для покращення контексту використовуємо RAG (Retrieval-Augmented Generation), додаючи релевантні історичні дані до промпту.

Когортний аналіз та ретеншн

Код для когортного аналізу
def cohort_retention_analysis(self) -> pd.DataFrame:
    first_event = self.events.groupby('user_id')['timestamp'].min().reset_index()
    first_event.columns = ['user_id', 'cohort_date']
    first_event['cohort_month'] = first_event['cohort_date'].dt.to_period('M')
    events_with_cohort = self.events.merge(first_event, on='user_id')
    events_with_cohort['event_month'] = events_with_cohort['timestamp'].dt.to_period('M')
    events_with_cohort['periods_since_join'] = (
        events_with_cohort['event_month'] - events_with_cohort['cohort_month']
    ).apply(lambda x: x.n)
    cohort_data = events_with_cohort.groupby(
        ['cohort_month', 'periods_since_join']
    )['user_id'].nunique().reset_index()
    cohort_sizes = cohort_data[cohort_data['periods_since_join'] == 0].set_index('cohort_month')['user_id']
    retention_matrix = cohort_data.pivot(
        index='cohort_month', columns='periods_since_join', values='user_id'
    ).divide(cohort_sizes, axis=0)
    return retention_matrix

Когортний аналіз показує, як змінюється retention для різних груп користувачів. Якщо одна когорта йде швидше за іншу — це привід перевірити зміни в онбордингу.

Кейс: економія $50 000 на рік завдяки AI-аналітиці

У нашій практиці був кейс: SaaS-платформа для email-маркетингу (наш клієнт) зіткнулася з падінням конверсії з ознайомлювального періоду в платний. Ми розгорнули AI-аналітику на їхніх даних (500 000 подій на день). Система виявила: 68% користувачів, які не завершили онбординг, застрягали на кроці «налаштування інтеграції з CRM». Інтерфейс був неочевидним, і LLM-інтерпретація прямо вказала на це. Після A/B-тесту зі спрощеним UI retention на третьому тижні виріс з 41% до 64%. Річна економія від зменшення відтоку склала $50 000. Це яскравий приклад оптимізації UX через AI-аналітику.

Швидкість виявлення аномалій

Система обчислює Z-score для DAU та events_per_user щогодини. Якщо значення відхиляється більш ніж на 2.5 сигми — спрацьовує алерт. На практиці аномалії фіксуються протягом 1-2 годин після появи. Ручний моніторинг з тими самими даними зайняв би 1-2 дні. Пороги можна калібрувати під ваш продукт: для високонавантажених сервісів використовуємо динамічні довірчі інтервали (EWMA).

Процес реалізації AI-аналітики та стек технологій

  1. Аналітика джерел даних — розбираємося, які події вже збираються, де зберігаються логи, який формат. Якщо трекінгу немає — додаємо SDK (браузер, мобільний застосунок, сервер).
  2. Проєктування пайплайну — обираємо стек: PySpark або Polars для обробки, ChromaDB / pgvector для довгострокового зберігання ембедингів, MLflow для керування моделями (впроваджуємо MLOps для автоматизації).
  3. Розробка модулів — сесіонізація, детекція аномалій, когорти, LLM-інтерпретація. Кодова база на Python 3.12, моделі через Anthropic API/OpenAI API.
  4. Інтеграція з вашим продуктом — дашборди будуємо в Grafana або вбудовуємо компоненти React, алерти — через Telegram/Slack.
  5. Тестування та калібрування — проганяємо на історичних даних (3-6 місяців), перевіряємо precision/recall детекції аномалій, коригуємо промпти.
  6. Деплой та моніторинг — контейнеризація через Docker, оркестрація Kubernetes, метрики утилізації GPU при генерації інсайтів.

Що входить у роботу та строки

  • Документація пайплайну — опис архітектури, схеми даних, API.
  • Кодова база — приватний репозиторій з модулями аналізу, тестами та CI/CD.
  • Дашборди та алерти — налаштовані під ваші ключові метрики.
  • Навчання команди — 2-3 сесії з роботи з системою.
  • Підтримка — 2 тижні після запуску для коригування порогів та промптів.
Етап Строк
Аналітика та проєктування від 3 до 7 днів
Розробка базових модулів від 10 до 20 днів
Інтеграція та тестування від 5 до 10 днів
Деплой та навчання від 3 до 5 днів

Загальний строк — від 3 до 6 тижнів. Вартість проєкту стартує від $15 000, залежно від обсягу подій та необхідних модулів. Оцінимо проєкт протягом одного робочого дня після брифу.

Наша команда має 5+ років досвіду в AI/ML, реалізовано понад 30 проєктів у сфері поведінкової аналітики. Використовуємо сертифіковані моделі (Claude 3.5, GPT-4o) та гарантуємо відсутність хибних спрацьовувань вище 5% при стандартних налаштуваннях.

Напрямки AI-розробки

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1393
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    815
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139