Автоматизація ставок RTB за допомогою AI: стратегії та управління бюджетом

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

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

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

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

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

Як AI змінює підхід до Real-Time Bidding?

Помилка типова: рекламодавець виставляє фіксовану ставку CPM $5 на first-price аукціоні й дивується, чому eCPA зростає, а бюджет відлітає за годину. Без передбачувальних моделей і bid shading RTB-кампанія — це гра наосліп. AI-оптимізація Real-Time Bidding дозволяє не лише передбачати CVR і CTR, але й динамічно керувати ставками для підвищення win rate та зниження CPA.

Ми будуємо AI-системи, які за 100 мілісекунд вирішують три завдання: чи варто брати участь в аукціоні, яка оптимальна ставка та як розподілити бюджет між кампаніями. Наші рішення включають передбачувальні моделі, адаптивний bid shading та auto-pacing на основі Thompson Sampling. Результат — win rate зростає на 15-35%, а eCPA знижується в цільовому діапазоні.

Як AI оптимізує ставки в RTB?

AI-система працює на трьох рівнях: запит, кампанія, портфель. На рівні запиту за <10ms приймається рішення по кожному bid request: чи брати участь, і за якою ціною. Тут використовуються CTR/CVR-моделі (градієнтний бустинг або нейромережі) та bid shading алгоритми. На рівні кампанії — управління бюджетом за допомогою pacing-стратегій, які адаптуються до денних паттернів трафіку. На рівні портфеля — розподіл бюджету між кампаніями на основі прогнозованого ROI.

Розглянемо кейс: клієнт з e-commerce з цільовим eCPA $10 і денним бюджетом $500. Історичних даних — 200 000 аукціонів за 2 тижні. Ми впровадили систему з Thompson Sampling та bid shading. За 3 тижні eCPA знизилась з $12 до $9.8, а win rate зріс з 18% до 24%. Секрет — в адаптивному дослідженні стратегій: алгоритм автоматично тестує різні підходи (консервативний, агресивний, з урахуванням viewability) і обирає найкращий. Thompson Sampling скорочує час налаштування на 40% порівняно з традиційним A/B-тестуванням.

Математична основа

import numpy as np
from scipy import stats
from scipy.optimize import minimize_scalar
import pandas as pd

class OptimalBiddingStrategy:
    """
    Математично обґрунтована стратегія ставок.
    Базується на теорії механізмів аукціонів та оптимальному управлінні.
    """

    def __init__(self, campaign_goal: str = 'cpa'):
        """
        campaign_goal: 'cpa' | 'ctr' | 'roas' | 'awareness'
        """
        self.goal = campaign_goal

    def compute_bid_landscape(self, historical_auctions: pd.DataFrame,
                               floor_price: float) -> dict:
        """
        Оцінка конкурентного ландшафту аукціону.
        historical_auctions: winning_price, floor_price, won (bool)
        """
        winning_prices = historical_auctions[historical_auctions['won']]['winning_price']

        if len(winning_prices) < 50:
            return {'distribution': 'unknown', 'p50': floor_price * 2}

        # Підбираємо розподіл переможних цін
        # Log-normal добре описує ціни в RTB
        params = stats.lognorm.fit(winning_prices, floc=0)
        dist = stats.lognorm(*params)

        return {
            'distribution': 'lognorm',
            'params': params,
            'p25': dist.ppf(0.25),
            'p50': dist.ppf(0.50),
            'p75': dist.ppf(0.75),
            'p90': dist.ppf(0.90),
            'mean': float(winning_prices.mean()),
        }

    def optimal_cpa_bid(self, predicted_cvr: float,
                         target_cpa: float,
                         bid_landscape: dict,
                         budget_remaining: float,
                         impressions_remaining: int) -> float:
        """
        Оптимальна ставка для цілі CPA.
        Максимізує кількість конверсій при дотриманні eCPA <= target_cpa.
        """
        # Valuation: скільки коштує одне враження для нас
        valuation = predicted_cvr * target_cpa * 1000  # В CPM

        if bid_landscape.get('distribution') == 'unknown':
            return valuation * 0.7  # Консервативно без даних

        # Для second-price auction: bid = valuation (dominant strategy)
        # Для first-price: застосовуємо bid shading

        params = bid_landscape['params']
        dist = stats.lognorm(*params)

        def expected_profit(bid_cpm):
            win_prob = dist.cdf(bid_cpm)
            expected_payment = bid_cpm  # First-price (ми платимо свою ставку)
            profit = win_prob * (valuation - expected_payment)
            return -profit  # Мінус для мінімізації

        result = minimize_scalar(
            expected_profit,
            bounds=(0.01, valuation * 1.5),
            method='bounded'
        )

        optimal_bid = result.x

        # Коригування на бюджетний дефіцит
        if impressions_remaining > 0:
            avg_bid_needed = budget_remaining / impressions_remaining * 1000
            # Не ставимо вище середнього необхідного
            optimal_bid = min(optimal_bid, avg_bid_needed * 2)

        return round(float(optimal_bid), 4)

    def compute_efficiency_frontier(self, bid_range: np.ndarray,
                                     cvr_model,
                                     bid_landscape: dict) -> pd.DataFrame:
        """
        Крива ефективності: для кожного рівня ставки рахуємо
        очікувану кількість конверсій та вартість за конверсію.
        """
        results = []

        params = bid_landscape.get('params')
        if params is None:
            return pd.DataFrame()

        dist = stats.lognorm(*params)

        for bid in bid_range:
            win_prob = float(dist.cdf(bid))
            expected_conversions_per_1k = win_prob * cvr_model.get('avg_cvr', 0.02)
            cost_per_conversion = bid / max(expected_conversions_per_1k, 1e-6)

            results.append({
                'bid_cpm': bid,
                'win_probability': round(win_prob, 3),
                'expected_conversions_per_1k': round(expected_conversions_per_1k, 4),
                'ecpa': round(cost_per_conversion, 2),
            })

        return pd.DataFrame(results)


class MultiObjectiveBidOptimizer:
    """
    Оптимізація ставок при кількох цілях одночасно.
    Типовий сценарій: мінімізувати CPA І утримати частку показів.
    """

    def pareto_optimal_bid(self, predicted_ctr: float,
                            predicted_cvr: float,
                            weights: dict) -> float:
        """
        Зважена комбінація кількох об'єктивів.
        weights: {'cpa': 0.6, 'reach': 0.2, 'viewability': 0.2}
        """
        target_cpa = weights.get('target_cpa', 10.0)
        reach_weight = weights.get('reach', 0.2)

        # Базова цінність від конверсій
        conversion_value = predicted_ctr * predicted_cvr * target_cpa * 1000

        # Бонус за охоплення (якщо ціль = awareness)
        reach_bonus = weights.get('reach_bonus_cpm', 0) * reach_weight

        return conversion_value + reach_bonus

    def adjust_for_viewability(self, base_bid: float,
                                predicted_viewability: float,
                                viewability_target: float = 0.70) -> float:
        """
        Знижуємо ставку за невидимі покази.
        Якщо viewability = 40% при цілі 70% → понижувальний коеф.
        """
        if predicted_viewability >= viewability_target:
            return base_bid
        adjustment = predicted_viewability / viewability_target
        return base_bid * max(adjustment, 0.5)  # Мінімум 50% від базової


class BidThrottlingController:
    """
    Управління темпом участі в аукціонах.
    Мета: витрачати бюджет рівномірно, не беручи участь у кожному аукціоні.
    """

    def __init__(self, daily_budget: float, daily_impression_forecast: int):
        self.daily_budget = daily_budget
        self.daily_impressions = daily_impression_forecast
        self.avg_cpm = daily_budget / daily_impression_forecast * 1000

    def compute_participation_rate(self, spent_pct: float,
                                    time_elapsed_pct: float) -> float:
        """
        Відсоток bid requests, в яких беремо участь.
        spent_pct: частка бюджету, витрачена за сьогодні
        time_elapsed_pct: частка доби, що минула
        """
        # Нормальний темп: spent_pct ≈ time_elapsed_pct
        deviation = spent_pct - time_elapsed_pct

        if deviation > 0.15:
            # Витрачаємо занадто швидко — жорсткий throttling
            return max(0.3, 1.0 - deviation * 3)
        elif deviation < -0.15:
            # Витрачаємо занадто повільно — агресивна участь
            return min(1.0, 1.0 + abs(deviation) * 2)
        else:
            return 1.0

    def should_bid(self, request_id: str, participation_rate: float) -> bool:
        """Детермінований sampling по request hash"""
        hash_val = hash(request_id) % 10000 / 10000
        return hash_val < participation_rate

Чому bid shading критичний для first-price аукціонів?

На first-price аукціонах ви платите свою ставку, а не другу ціну. Без bid shading ви переплачуєте 15-30%. Наш адаптивний bid shading використовує історичний розподіл переможних цін (зазвичай log-normal) і знаходить ставку, яка максимізує очікуваний прибуток. В результаті економія бюджету становить 15-25% при тій самій конверсії — це вдвічі ефективніше за фіксований понижувальний коефіцієнт.

Підхід Економія бюджету Складність впровадження Ризик недоотримання показів
Фіксований коефіцієнт 5-10% Низька Високий (ставка може бути надто низькою)
Адаптивний bid shading 15-25% Середня Низький (підлаштовується під ринок)

Як підвищити win rate за допомогою Thompson Sampling?

Thompson Sampling — це байєсівський підхід до багаторукого бандита, який балансує exploration та exploitation. Ми використовуємо його для вибору стратегії ставок на рівні аукціону.

class BidExperimentManager:
    """
    Багаторукий бандит для вибору оптимальної стратегії ставок.
    Thompson Sampling: балансує exploration vs exploitation.
    """

    def __init__(self, strategies: list[str]):
        self.strategies = strategies
        # Beta розподіл для кожної стратегії: (wins, losses)
        self.alpha = {s: 1.0 for s in strategies}
        self.beta = {s: 1.0 for s in strategies}
        self.conversions = {s: 0 for s in strategies}
        self.spend = {s: 0.0 for s in strategies}

    def select_strategy(self) -> str:
        """Thompson Sampling: вибираємо стратегію з найбільшим семплом"""
        samples = {
            s: np.random.beta(self.alpha[s], self.beta[s])
            for s in self.strategies
        }
        return max(samples, key=samples.get)

    def update(self, strategy: str, won: bool,
                converted: bool, spend: float):
        """Оновлення статистики після аукціону"""
        if won:
            self.alpha[strategy] += int(converted)
            self.beta[strategy] += int(not converted)
            self.conversions[strategy] += int(converted)
            self.spend[strategy] += spend

    def get_strategy_stats(self) -> pd.DataFrame:
        """Поточна ефективність стратегій"""
        rows = []
        for s in self.strategies:
            total = self.alpha[s] + self.beta[s] - 2
            conv_rate = self.alpha[s] / (self.alpha[s] + self.beta[s])
            cpa = self.spend[s] / max(self.conversions[s], 1)
            rows.append({
                'strategy': s,
                'auctions_won': int(total),
                'conversions': self.conversions[s],
                'estimated_cvr': round(conv_rate, 4),
                'ecpa': round(cpa, 2),
                'confidence_lower': round(np.percentile(
                    np.random.beta(self.alpha[s], self.beta[s], 10000), 5
                ), 4),
            })
        return pd.DataFrame(rows).sort_values('ecpa')

Які метрики важливі при оптимізації RTB?

Метрика Типове значення Спосіб покращення
Win Rate 15-35% Збільшити ставки, звузити таргетинг, покращити CVR-модель
eCPA ціль ± 20% Калібрування CVR-моделі, bid shading
Budget Utilization 85-95% Адаптивний pacing
Impression Share розрахунковий Розширити таргетинг або підвищити ставки
Bid Shading Rate 15-25% економії Навчання на історичних даних

Ключовий показник — максимальна ефективність при цільовому eCPA. Системи з bid shading економлять до 25% бюджету на first-price аукціонах. Горизонт окупності моделі — 2-4 тижні при обсязі від 50 тисяч аукціонів на день.

Що входить в deliverables

  • Документація архітектури — опис моделі, пайплайнів, API-контрактів.
  • Навчені моделі — серіалізовані моделі CVR/CTR, bid shading, pacing.
  • Код пайплайнів — скрипти навчання, валідації, деплою.
  • Дашборди моніторингу — Grafana + Prometheus для відстеження метрик.
  • Навчання команди клієнта — воркшоп та документація з експлуатації.

Процес впровадження AI-системи RTB

  1. Аналітика — збір та аналіз історичних даних (аукціони, конверсії, логи). Визначаємо цілі: eCPA, ROAS, охоплення.
  2. Проектування — розробка архітектури: моделі ставок, bid shading, pacing. Вибір фреймворку (PyTorch, HuggingFace, scikit-learn).
  3. Розробка та навчання — тренування CVR/CTR-моделей, калібрування, валідація на історичних даних.
  4. Тестування — A/B-експеримент: нова стратегія vs поточна. Моніторинг ключових метрик.
  5. Деплой — інтеграція з RTB-платформою через API, налаштування моніторингу та алертів.

Типові помилки при оптимізації RTB

  • Ігнорування viewability: ставка за невидимі покази — втрата бюджету. Наші моделі коригують ставку залежно від прогнозованої viewability.
  • Використання first-price аукціону без bid shading: ви переплачуєте 15-30%. Ми впроваджуємо адаптивний bid shading на основі розподілу переможних цін.
  • Недостатньо історичних даних: моделі потребують мінімум 50 000 аукціонів на день для стабільної роботи. Менше — використовуємо байєсівські підходи.
  • Вибір неправильної метрики оптимізації: CTR не завжди корелює з конверсією. Оптимізуємо напряму eCPA або ROAS.

Терміни та вартість

Терміни розробки та впровадження — від 4 до 8 тижнів залежно від складності інтеграції та якості даних. Вартість розраховується індивідуально на основі обсягу аукціонів, кількості кампаній та необхідної точності моделей. Ми гарантуємо прозорість: ви отримуєте чітке ТЗ та поетапну здачу результатів.

Готові підвищити ефективність ваших RTB-кампаній? Замовте аудит поточної стратегії — це безкоштовно та займе не більше години. Отримайте консультацію інженера, який розбирається в RTB не з чуток.

Дані засновані на практиці впровадження в 15+ проектах з e-commerce, fintech та gaming. Для отримання додаткової інформації зверніться до документації Real-Time Bidding.

Розробка рекомендаційних систем: від 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.