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

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

Як 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.

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

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

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