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

Как AI меняет подход к Real-Time Bidding? Ошибка типичная: рекламодатель выставляет фиксированную ставку CPM $5 на first-price аукционе и удивляется, почему eCPA растет, а бюджет улетает за час. Без предсказательных моделей и bid shading RTB-кампания — это игра вслепую. AI-оптимизация Real-Time B

Направления AI-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1440
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    997
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1264
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    712
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1002

Как 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.