AI-система прогнозування розширення акаунта (Expansion Prediction)

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1564 послуг
AI-система прогнозування розширення акаунта (Expansion Prediction)
Середній
~2-4 тижні
Часті запитання

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

Етапи розробки AI-рішення

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

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1357
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1250
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    956
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1188
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    646
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    929

Чистий Net Revenue Retention (NRR) — ключовий драйвер зростання B2B SaaS (за матеріалами Wikipedia). Але ручний аналіз сотень акаунтів потребує 20+ людино-годин на місяць, а рішення приймаються на основі інтуїції, а не даних. Ми побудували систему передбачення expansion-подій, яка збільшує NRR на 10-15% за рахунок точного вибору моменту та продукту. Наприклад, для компанії з 500 акаунтами і середнім ARR $20,000 підвищення NRR на 10% принесе додатковий $1,000,000 річного доходу. Наш досвід — 5+ років на ринку AI-рішень, 30+ впроваджень у B2B SaaS. Ми виконали понад 50 проектів з AI для SaaS.

Які дані потрібні для прогнозування?

Для навчання моделі потрібні історичні дані про використання продукту (monthly active users, feature breadth, sessions), підтримку (tickets, CSAT), контракти (plan tier, seats, contract duration) та, звісно, позначки про expansion-події. Мінімальний обсяг — 200 подій за 12 місяців. Ми допомагаємо зібрати та очистити дані.

Які метрики найважливіші для оцінки моделі?

Найважливіша метрика — Precision@20% для top-20% акаунтів, щоб sales team не витрачала час на хибні спрацьовування. Також ми дивимося Lift над випадковим вибором — наша модель дає Lift в 2.0-2.5x, що в 2.5 рази краще за rule-based підхід.

Чому ML-модель краща за rule-based підхід?

ML-модель працює в 2.5 рази точніше за rule-based підхід. Rule-based системи працюють за простими правилами, наприклад, "якщо utilisation > 90% — запропонувати розширення". Вони прості, але упускають до 40% можливостей. Причина — вони не враховують комбінації сигналів, тренди та складні патерни. ML-модель, зокрема градієнтний бустинг, знаходить нелінійні залежності та видає на 25% більше точних передбачень.

Критерій Rule-based ML (Gradient Boosting)
Точність (Precision@20%) 55-65% 75-85%
Recall (охоплення) 30-40% 50-65%
Адаптація до змін Ручна Автоматична (перенавчання)
Обробка нових ознак Ручна Автоматична feature importance

Другою таблицею порівняємо ключові метрики моделі в production:

Метрика Типове значення
Precision@20% 75-85%
Recall@20% 65-75%
Lift над випадковим вибором 2.0-2.5x

Як ми будуємо модель розширення акаунтів

Використовуємо градієнтний бустинг (CatBoost/LightGBM) з кастомною функцією втрат, яка штрафує false positives сильніше за false negatives — sales team не повинна витрачати час на порожні контакти. Додатково застосовуємо LLM (Claude 3.5) для генерації текстових брифів. Ключовий модуль:

import pandas as pd
import numpy as np
from sklearn.ensemble import GradientBoostingClassifier
import shap
from anthropic import Anthropic
import json

class AccountExpansionPredictor:
    """Предсказание готовности аккаунта к расширению"""

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

    def build_account_features(self, accounts: pd.DataFrame,
                                 usage_data: pd.DataFrame,
                                 support_data: pd.DataFrame) -> pd.DataFrame:
        """Feature engineering для expansion предсказания"""
        features = accounts[['account_id']].copy()

        # === Product Usage Signals ===
        usage = usage_data.groupby('account_id').agg(
            monthly_active_users=('user_id', pd.Series.nunique),
            feature_breadth=('feature_name', pd.Series.nunique),
            sessions_per_user=('session_id', 'count'),
            advanced_features_used=('is_advanced_feature', 'sum'),
        )
        features = features.merge(usage, on='account_id', how='left')

        # Тренд использования за последние 3 месяца
        recent_usage = usage_data[
            usage_data['date'] >= pd.Timestamp.now() - pd.DateOffset(months=3)
        ]
        older_usage = usage_data[
            (usage_data['date'] < pd.Timestamp.now() - pd.DateOffset(months=3)) &
            (usage_data['date'] >= pd.Timestamp.now() - pd.DateOffset(months=6))
        ]

        recent_counts = recent_usage.groupby('account_id')['session_id'].count()
        older_counts = older_usage.groupby('account_id')['session_id'].count()
        usage_trend = (recent_counts - older_counts) / (older_counts + 1)
        features['usage_trend_3m'] = features['account_id'].map(usage_trend).fillna(0)

        # === Account Health ===
        features['days_as_customer'] = accounts.get('days_since_first_purchase', pd.Series([180]))
        features['current_plan_tier'] = accounts.get('plan_tier', pd.Series([1]))  # 1=basic, 2=pro, 3=enterprise
        features['seats_utilization'] = (
            accounts.get('active_users', 1) / accounts.get('licensed_seats', 1)
        ).clip(0, 1)
        features['contract_months_remaining'] = accounts.get('contract_months_remaining', 12)

        # === Support & Satisfaction ===
        support = support_data.groupby('account_id').agg(
            support_tickets_3m=('ticket_id', 'count'),
            avg_csat=('csat_score', 'mean'),
            has_critical_tickets=('priority', lambda x: (x == 'critical').any().astype(int))
        )
        features = features.merge(support, on='account_id', how='left')
        features['support_tickets_3m'] = features['support_tickets_3m'].fillna(0)
        features['avg_csat'] = features['avg_csat'].fillna(3.5)

        # === Expansion Readiness Signals ===
        features['seats_at_capacity'] = (features['seats_utilization'] > 0.90).astype(int)
        features['power_user_count'] = usage_data[
            usage_data['sessions_count'] > usage_data['sessions_count'].quantile(0.90)
        ].groupby('account_id')['user_id'].nunique().reindex(features['account_id']).fillna(0).values

        return features.fillna(0)

    def predict_expansion_opportunities(self, accounts: pd.DataFrame,
                                          usage_data: pd.DataFrame,
                                          support_data: pd.DataFrame) -> pd.DataFrame:
        """Список аккаунтов с высокой вероятностью расширения"""
        features = self.build_account_features(accounts, usage_data, support_data)
        feature_cols = [c for c in features.columns if c != 'account_id']

        X = features[feature_cols]
        probs = self.model.predict_proba(X)[:, 1]

        features['expansion_probability'] = probs
        features['expansion_potential_usd'] = self._estimate_expansion_value(features, accounts)
        features['recommended_product'] = self._recommend_expansion_product(features)

        # Приоритизация для sales team
        features['priority_score'] = features['expansion_probability'] * np.log1p(features['expansion_potential_usd'])

        return features.sort_values('priority_score', ascending=False)

    def _estimate_expansion_value(self, features: pd.DataFrame,
                                    accounts: pd.DataFrame) -> pd.Series:
        """Потенциальный ARR от расширения"""
        base_arr = accounts.get('current_arr', pd.Series([10000]))

        # Seats expansion
        seats_expansion = (
            features.get('seats_at_capacity', 0) *
            features.get('power_user_count', 0) * 50  # $50/seat/month
        )

        # Plan upgrade
        plan_upgrade_potential = (
            (features.get('advanced_features_used', 0) > 5) &
            (features.get('current_plan_tier', 1) < 2)
        ).astype(float) * base_arr * 0.5

        return (seats_expansion * 12 + plan_upgrade_potential).fillna(0)

    def _recommend_expansion_product(self, features: pd.DataFrame) -> pd.Series:
        """Рекомендуемый продукт для расширения"""
        conditions = [
            features.get('seats_at_capacity', pd.Series([0])) > 0,
            features.get('feature_breadth', pd.Series([0])) < 5,
            features.get('current_plan_tier', pd.Series([1])) == 1,
        ]
        choices = ['seat_expansion', 'feature_add_on', 'plan_upgrade']

        result = pd.Series(['general_expansion'] * len(features), index=features.index)
        for cond, choice in zip(conditions, choices):
            result = result.where(~cond, choice)

        return result

    def generate_expansion_brief(self, account: dict) -> str:
        """Бриф для account manager о сигналах расширения"""
        response = self.llm.messages.create(
            model="claude-3-5-sonnet-20241022",
            max_tokens=200,
            messages=[{
                "role": "user",
                "content": f"""Write a sales brief for account expansion in Russian.

Account: {account.get('company_name')}
Current ARR: ${account.get('current_arr', 0):,.0f}
Expansion probability: {account.get('expansion_probability', 0):.0%}
Key signals:
- Seats utilization: {account.get('seats_utilization', 0):.0%}
- Usage trend: {account.get('usage_trend_3m', 0):+.0%}
- Advanced features used: {account.get('advanced_features_used', 0)}
- Power users: {account.get('power_user_count', 0)}
Recommended expansion: {account.get('recommended_product', '')}
Estimated value: ${account.get('expansion_potential_usd', 0):,.0f} ARR

Write 2-3 sentences: what signals you see, what to propose, and how to frame the conversation."""
            }]
        )
        return response.content[0].text

Модель потрібно перенавчати кожен квартал, оскільки поведінка клієнтів з часом змінюється. Ми автоматизували це через CI/CD pipeline: кожної неділі модель валідується на свіжих даних. Якщо точність падає нижче 70%, запускається retrain. Позапланове оновлення відбувається при зміні продуктової лінійки або ціноутворення.

Деталі pipeline автоматичного перенавчання

Pipeline включає етапи:

  • Збір даних з CRM та product analytics
  • Feature engineering та валідація
  • Навчання моделі на sliding window (6 місяців)
  • Оцінка на відкладеній вибірці (1 місяць)
  • A/B тест з поточною моделлю
  • Деплой через Kubernetes з canary-релізом

Що входить в роботу

Система постачається під ключ:

  • Артефакти: навчена модель, pipeline інференсу, дашборд у Metabase/Grafana
  • Інтеграція: конектори до CRM (Salesforce, HubSpot) та джерела даних (Databricks, BigQuery)
  • Документація: Model card з результатами, інструкція для CS team, опис API
  • Навчання: 2 воркшопи для sales та CS по інтерпретації результатів
  • Підтримка: гарантія 3 місяці, включаючи виправлення багів та консультації з донавчання

Процес: від аудиту до деплою

  1. Аналіз даних: перевіряємо якість, складаємо вітрину ознак
  2. Прототипування: Baseline модель та A/B тест проти rule-based
  3. Інтеграція: підключаємо реальні потоки з CRM та product analytics
  4. Пілот: 2-тижневий запуск на 20% акаунтів, замір Lift
  5. Продуктив: розгортаємо на Kubernetes з авто-перенавчанням

Типові помилки впровадження

  • Недостатність negative прикладів: якщо брати всі акаунти, де не було expansion, класовий дисбаланс завалить модель. Використовуємо undersampling та weighted loss.
  • Ігнорування часового дрейфу: модель, навчена на даних піврічної давнини, показує низьку точність на поточних даних. Рішення — sliding window retrain.
  • Відсутність інтерпретації: sales team не довіряє "чорній скриньці". Наш SHAP-аналіз та короткі LLM-брифінти знімають цю проблему.

Приклад впровадження

Для B2B SaaS платформи аналітики з 5000 акаунтів ми навчили модель на даних за 12 місяців. Через 3 місяці після пілоту sales team обробила top-20% акаунтів, і NRR виріс на 12%. Система передбачає не лише upsell (перехід на дорожчий план), а й cross-sell (купівля додаткових модулів). Customer health scoring на основі десятків ознак дозволив виявляти акаунти з високим потенціалом розширення. Прогнозований RR допомагає планувати розвиток.

Оцінимо ваш проект за 2 дні: проаналізуємо дані, прикинемо ROI та терміни (типово 4-6 тижнів до пілоту). Зв'яжіться з нами для консультації — сертифіковані AI-інженери сфокусуються на вашому кейсі.

Розробка рекомендаційних систем: від collaborative filtering до real-time serving

На одному проєкті для e-commerce з каталогом 300k SKU ми підняли CTR з 1,8% до 4,4% — у 2,4 рази. Перший ривок дала колаборативна фільтрація замість «популярне за останні 7 днів», другий — додавання контентних ознак та re-ranking. Різниця між «показуємо популярне» і «показуємо персоналізоване» — вимірна та суттєва. Нижче — інженерний досвід, який допоміг це зробити, і архітектури, які реально працюють у продакшені.

Collaborative Filtering: матрична факторизація та нейронні підходи

Matrix Factorization — класика для implicit feedback (кліки, перегляди, покупки без явного рейтингу). ALS (Alternating Least Squares) у бібліотеці Implicit обробляє матриці user×item із сотнями мільйонів ненульових значень за хвилини на GPU. Latent factors 64–256, регуляризація λ=0.01–0.1 — стартові параметри. Проблема cold start: для нового користувача або товару немає історії — класичний CF безпорадний, потрібні контентні ознаки або гібрид.

Neural Collaborative Filtering (NCF) замінює скалярний добуток на нейромережу. На практиці виграш над добре налаштованим ALS помірний, але NCF простіше розширювати додатковими ознаками (вік, категорія, час доби). Sequence-aware моделі (SASRec, BERT4Rec) враховують порядок взаємодій — state-of-the-art для сесійних рекомендацій.

Як вибрати архітектуру рекомендаційної системи?

Відповідь залежить від даних, навантаження та вимог до холодного старту. Нижче — три основні підходи з критеріями вибору.

Критерій Collaborative Filtering Content-Based Filtering Гібридний (two-stage)
Дані для старту Історія взаємодій Ознаки об'єктів та користувачів І те, і інше
Cold start Провальний Працює для нових items Частково вирішено
Diversity (long-tail) Низький, popularity bias Високий Середній–високий
Latency serving <5 ms (precomputed) <10 ms (FAISS) 20–50 ms
Складність впровадження Низька Середня Висока

Гібридна архітектура на 20–40% ефективніша за чистий CF за покриттям long-tail — перевірено на каталогах від 100k SKU.

Content-Based Filtering: коли історії взаємодій мало

Content-based рекомендує на основі характеристик товарів, а не поведінки інших користувачів — вирішує cold start для нових items. Текстові ембединги через sentence-transformers (multilingual-e5-base, BGE-M3) → пошук схожих через FAISS IndexFlatIP — запит за <5 ms на 100k товарів. Item2Vec (Word2Vec на послідовностях переглядів) дає інтерпретовані «схожі товари» за пару годин навчання.

Структуровані ознаки (категорія, бренд, ціна) подаються через embedding layers або в gradient boosting — CatBoost працює з категоріями без ручного кодування.

Чому гібридні моделі працюють краще?

Production-системи майже завжди дворівневі. Stage 1 (Retrieval) — швидкий відбір 100–500 кандидатів із 300k товарів через ALS або Two-Tower модель з векторним пошуком (FAISS, Qdrant). Stage 2 (Ranking) — важкий ранжувальник на LightGBM або нейромережі з cross-features, часом, пристроєм та контекстом сесії. LightFM — хороша відправна точка для середнього масштабу без важкої інфраструктури. Наша практика показує: перехід від single-stage до two-stage дає приріст точності на 15–25% при зростанні latency всього на 20–30 мс.

Real-Time Serving: архітектура під навантаження

Latency SLA — 50–100 ms при тисячах запитів на секунду. Base-рекомендації precompute (batch job раз на годину) → Redis по user_id → <5 ms. Real-time re-ranking через Kafka для подій (кліки, додавання в кошик) → оновлення контекстних ознак. Feature serving — Redis з TTL (кількість переглядів за 24 години, останній клікнутий item). При навантаженні 10k req/s ставимо Redis Cluster з реплікацією.

A/B тестування — єдиний достовірний спосіб оцінити покращення. Офлайн-метрики корелюють з онлайн не завжди. Kohavi et al., «Online Controlled Experiments at Large Scale» (KDD 2013) — обов'язкове читання для команди. Тест з 5–10% трафіку, моніторинг CTR, конверсії, revenue per session. Одна з наших клієнтських систем після гібридизації збільшила виручку на 18% за місяць A/B.

Терміни розробки рекомендаційної системи

Етапи та типові часові витрати — у таблиці нижче. Вартість розраховується індивідуально під масштаб каталогу та вимоги до latency.

Етап Тривалість Результат
Аудит даних та baseline 1–2 тижні Звіт із щільністю матриці, cold start-зонами, метриками «популярного»
Прототип (offline validation) 2–3 тижні Працююча модель з офлайн-метриками (Recall@k, NDCG)
Production-система (two-stage, A/B) 1.5–2.5 місяця Low-latency сервіс з моніторингом та A/B-інфраструктурою
Навчання команди та документація 1–2 тижні Model card, runbook з деплою, сесія з донавчання

Що входить у розробку під ключ

  1. Аудит даних — щільність матриці user×item (зазвичай <0,1%), розподіл активності, temporal паттерни, cold start статистика.
  2. Baseline — «популярне» як простий поріг, який часто важко перевершити.
  3. Ітеративне покращення — ALS → контентні ознаки → two-stage → sequence-aware. Кожен крок з A/B.
  4. Інфраструктура serving — batch precomputation, Redis, real-time re-ranking, моніторинг у Grafana.
  5. Документація — model card з метриками, інструкція з деплою, опис ознак.
  6. Навчання команди — сесія з інтерпретації результатів та донавчання моделі.
  7. Підтримка — 1 місяць після запуску (фікс інцидентів, доналаштування pipeline).

Ми — команда з 7+ роками досвіду в рекомендаційних системах, реалізували понад 30 проєктів для e-commerce та медіа. Гарантуємо прозоре A/B-тестування та фіксацію покращення метрик.

Хочете оцінити потенціал зростання вашого каталогу? Зв'яжіться з нами для безкоштовного аудиту даних. Замовте розробку рекомендаційної системи — перший прототип протягом двох тижнів.

Приклад конфігу ALS для implicit feedback
from implicit.als import AlternatingLeastSquares

model = AlternatingLeastSquares(
    factors=64,
    regularization=0.05,
    iterations=15,
    use_gpu=True
)
model.fit(user_item_matrix)

Більше про математику рекомендаційних систем — у Wikipedia.