[{"data":1,"prerenderedAt":1038},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fru\u002Fdata\u002Fmarketing-mix-modeling-robyn-practical-setup":13},{"i18nKey":4,"paths":5},"data-005-2026-07",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11,"tr":12},"\u002Fde\u002Fdata\u002Fmarketing-mix-modeling-robyn-praktische-einrichtung","\u002Fen\u002Fdata\u002Fmarketing-mix-modeling-robyn-practical-setup","\u002Fes\u002Fdata\u002Fmarketing-mix-modeling-robyn-configuracion-practica","\u002Ffr\u002Fdata\u002Fmodelisation-mix-marketing-configuration-pratique-robyn","\u002Fit\u002Fdata\u002Fmarketing-mix-modeling-robyn-kurulum","\u002Fru\u002Fdata\u002Fmarketing-mix-modeling-robyn-prakticheskaia-nastroika","\u002Ftr\u002Fdata\u002Fmarketing-mix-modeling-robyn-ile-pratik-kurulum",{"_path":14,"_dir":15,"_draft":16,"_partial":16,"_locale":17,"title":18,"description":19,"publishedAt":20,"modifiedAt":20,"category":15,"i18nKey":4,"tags":21,"readingTime":27,"author":28,"body":29,"_type":1032,"_id":1033,"_source":1034,"_file":1035,"_stem":1036,"_extension":1037},"\u002Fru\u002Fdata\u002Fmarketing-mix-modeling-robyn-practical-setup","data",false,"","Marketing Mix Modeling: Практическая настройка с Robyn","Показываем настройку кривой насыщения, адсток-декей и holdout-валидации на примере open-source MMM-библиотеки Meta Robyn с реальными production-данными.","2026-07-07",[22,23,24,25,26],"marketing-mix-modeling","robyn","adstock","saturation-curve","media-attribution",8,"Roibase",{"type":30,"children":31,"toc":1021},"root",[32,40,47,52,57,73,79,84,186,205,222,230,250,272,278,283,290,311,319,327,340,350,360,366,371,379,404,409,419,425,430,453,458,544,554,600,605,659,664,690,696,701,777,790,874,884,894,908,914,933,941,1010,1015],{"type":33,"tag":34,"props":35,"children":36},"element","p",{},[37],{"type":38,"value":39},"text","Multi-touch атрибуционные модели теряют надёжность в post-cookie эпохе, а marketing mix modeling возвращается на передний план. Open-source MMM-инструменты Google и Meta (LightweightMMM, Robyn) дают маркетологу возможность измерять эффективность каналов на агрегированном уровне. В начале 2025 года Meta выпустила Robyn 3.11 с Bayesian-оптимизацией и параллельным поиском гиперпараметров — инструмент стал production-ready. В этой статье разбираем настройку Robyn через три ключевые концепции: кривая насыщения (diminishing returns), адсток-декей (отложенный эффект) и holdout-валидация (надёжность модели).",{"type":33,"tag":41,"props":42,"children":44},"h2",{"id":43},"что-такое-robyn-и-почему-он-важен-сейчас",[45],{"type":38,"value":46},"Что такое Robyn и почему он важен сейчас",{"type":33,"tag":34,"props":48,"children":49},{},[50],{"type":38,"value":51},"Robyn — R-пакет, выпущенный Meta в 2021 году как open-source решение. Модель на основе ridge-регрессии принимает данные о расходах по каналам и конверсиях на недельной\u002Fдневной агрегации, затем вычисляет incremental-вклад каждого канала в общие конверсии. В крупном обновлении 2024 года модель интегрировала компоненты временных рядов Prophet и добавила поддержку JSON-экспорта — это позволило подключать Robyn к Python workflow'ам.",{"type":33,"tag":34,"props":53,"children":54},{},[55],{"type":38,"value":56},"Три характеристики выделяют Robyn среди других MMM-подходов: во-первых, моделирование связи расход-конверсия не линейным способом, а через Hill-Adstock-трансформацию (реалистичное насыщение); во-вторых, оптимизация гиперпараметров через генетический алгоритм и gradient-free Nevergrad-оптимизатор (ручная настройка не нужна); в-третьих, автоматическое формирование метрик качества модели (NRMSE, DECOMP.RSSD, MAPE). В production, для проверки надёжности модели критична встроенная функция holdout-валидации — покажем её ниже.",{"type":33,"tag":34,"props":58,"children":59},{},[60,62,71],{"type":38,"value":61},"Преимущество marketing mix modeling перед attribution в том, что работа с агрегированными данными не подвержена ограничениям GDPR\u002FCCPA и избегает сложности cross-device journey. Недостаток — модель остаётся на уровне недельной гранулярности: она подходит для квартального распределения бюджета, но не для intraday-оптимизации кампаний. В архитектуре ",{"type":33,"tag":63,"props":64,"children":68},"a",{"href":65,"rel":66},"https:\u002F\u002Fwww.roibase.com.tr\u002Fru\u002Ffirstparty",[67],"nofollow",[69],{"type":38,"value":70},"first-party данных",{"type":38,"value":72}," компании Roibase MMM работает рядом с результатами incrementality-тестов: высокий ROAS в MMM недостаточен — требуется валидация через geo-split-тест или synthetic control.",{"type":33,"tag":41,"props":74,"children":76},{"id":75},"подготовка-данных-расходы-по-каналам-макро-переменные",[77],{"type":38,"value":78},"Подготовка данных: расходы по каналам + макро-переменные",{"type":33,"tag":34,"props":80,"children":81},{},[82],{"type":38,"value":83},"Robyn принимает на вход временной ряд с минимальным набором колонок в недельной гранулярности:",{"type":33,"tag":85,"props":86,"children":90},"pre",{"code":87,"language":88,"meta":17,"className":89,"style":17},"# Пример структуры данных (104 недели = ~2 года)\ndata \u003C- data.frame(\n  date = seq(as.Date(\"2024-01-01\"), by = \"week\", length.out = 104),\n  revenue = rnorm(104, 50000, 8000),\n  facebook_spend = rnorm(104, 5000, 1000),\n  google_search_spend = rnorm(104, 7000, 1500),\n  display_spend = rnorm(104, 3000, 800),\n  competitor_index = rnorm(104, 100, 15),  # макро-переменная\n  holiday_flag = sample(0:1, 104, replace = TRUE)\n)\n","r","language-r shiki shiki-themes github-dark",[91],{"type":33,"tag":92,"props":93,"children":94},"code",{"__ignoreMap":17},[95,106,115,124,133,142,151,160,168,177],{"type":33,"tag":96,"props":97,"children":100},"span",{"class":98,"line":99},"line",1,[101],{"type":33,"tag":96,"props":102,"children":103},{},[104],{"type":38,"value":105},"# Пример структуры данных (104 недели = ~2 года)\n",{"type":33,"tag":96,"props":107,"children":109},{"class":98,"line":108},2,[110],{"type":33,"tag":96,"props":111,"children":112},{},[113],{"type":38,"value":114},"data \u003C- data.frame(\n",{"type":33,"tag":96,"props":116,"children":118},{"class":98,"line":117},3,[119],{"type":33,"tag":96,"props":120,"children":121},{},[122],{"type":38,"value":123},"  date = seq(as.Date(\"2024-01-01\"), by = \"week\", length.out = 104),\n",{"type":33,"tag":96,"props":125,"children":127},{"class":98,"line":126},4,[128],{"type":33,"tag":96,"props":129,"children":130},{},[131],{"type":38,"value":132},"  revenue = rnorm(104, 50000, 8000),\n",{"type":33,"tag":96,"props":134,"children":136},{"class":98,"line":135},5,[137],{"type":33,"tag":96,"props":138,"children":139},{},[140],{"type":38,"value":141},"  facebook_spend = rnorm(104, 5000, 1000),\n",{"type":33,"tag":96,"props":143,"children":145},{"class":98,"line":144},6,[146],{"type":33,"tag":96,"props":147,"children":148},{},[149],{"type":38,"value":150},"  google_search_spend = rnorm(104, 7000, 1500),\n",{"type":33,"tag":96,"props":152,"children":154},{"class":98,"line":153},7,[155],{"type":33,"tag":96,"props":156,"children":157},{},[158],{"type":38,"value":159},"  display_spend = rnorm(104, 3000, 800),\n",{"type":33,"tag":96,"props":161,"children":162},{"class":98,"line":27},[163],{"type":33,"tag":96,"props":164,"children":165},{},[166],{"type":38,"value":167},"  competitor_index = rnorm(104, 100, 15),  # макро-переменная\n",{"type":33,"tag":96,"props":169,"children":171},{"class":98,"line":170},9,[172],{"type":33,"tag":96,"props":173,"children":174},{},[175],{"type":38,"value":176},"  holiday_flag = sample(0:1, 104, replace = TRUE)\n",{"type":33,"tag":96,"props":178,"children":180},{"class":98,"line":179},10,[181],{"type":33,"tag":96,"props":182,"children":183},{},[184],{"type":38,"value":185},")\n",{"type":33,"tag":34,"props":187,"children":188},{},[189,195,197,203],{"type":33,"tag":190,"props":191,"children":192},"strong",{},[193],{"type":38,"value":194},"Количество каналов:",{"type":38,"value":196}," Рекомендуется 2–15 каналов. Свыше 20 повышается риск переобучения (overfitting), снижается стабильность коэффициентов. Если есть long-tail каналы (affiliate, influencer, podcast), их лучше объединить в одну колонку типа ",{"type":33,"tag":92,"props":198,"children":200},{"className":199},[],[201],{"type":38,"value":202},"other_digital",{"type":38,"value":204},".",{"type":33,"tag":34,"props":206,"children":207},{},[208,213,215,221],{"type":33,"tag":190,"props":209,"children":210},{},[211],{"type":38,"value":212},"Макро-переменные:",{"type":38,"value":214}," Сезонность, праздники, индекс конкурентов, макроэкономические показатели должны быть включены как контрольные переменные — иначе модель припишет весь рост конверсий медиа-каналам. Встроенная интеграция Robyn с Prophet автоматически захватывает тренд и праздники, но если в секторе произойдёт специфический шок (Black Friday, Ramadan), нужен флаг ",{"type":33,"tag":92,"props":216,"children":218},{"className":217},[],[219],{"type":38,"value":220},"holiday_flag",{"type":38,"value":204},{"type":33,"tag":34,"props":223,"children":224},{},[225],{"type":33,"tag":190,"props":226,"children":227},{},[228],{"type":38,"value":229},"Проверки качества данных:",{"type":33,"tag":231,"props":232,"children":233},"ul",{},[234,240,245],{"type":33,"tag":235,"props":236,"children":237},"li",{},[238],{"type":38,"value":239},"Ни одна колонка не должна иметь нулевую вариацию (постоянные расходы = бесполезна)",{"type":33,"tag":235,"props":241,"children":242},{},[243],{"type":38,"value":244},"Пропуски (missing values) — допуск ~5%; Robyn автоматической импутации не делает",{"type":33,"tag":235,"props":246,"children":247},{},[248],{"type":38,"value":249},"Недельная гранулярность предпочтительна — дневные данные добавляют шум, месячные означают недостаток наблюдений",{"type":33,"tag":34,"props":251,"children":252},{},[253,255,262,264,270],{"type":38,"value":254},"Если расходные данные приходят из разных источников (Google Ads API, Meta Marketing API, внутренняя бухгалтерия), в ETL-pipeline следует построить процесс ",{"type":33,"tag":63,"props":256,"children":259},{"href":257,"rel":258},"https:\u002F\u002Fwww.roibase.com.tr\u002Fru\u002Fverianalizi",[67],[260],{"type":38,"value":261},"данных-анализа",{"type":38,"value":263},". В нашем production workflow таблица ",{"type":33,"tag":92,"props":265,"children":267},{"className":266},[],[268],{"type":38,"value":269},"marketing_spend_weekly",{"type":38,"value":271}," в BigQuery обновляется каждый понедельник; dbt-модель синхронизирует агрегацию, R-скрипт читает из неё и запускает Robyn.",{"type":33,"tag":41,"props":273,"children":275},{"id":274},"насыщение-и-адсток-hill-adstock-трансформация",[276],{"type":38,"value":277},"Насыщение и адсток: Hill-Adstock трансформация",{"type":33,"tag":34,"props":279,"children":280},{},[281],{"type":38,"value":282},"Robyn пропускает расходы по каждому каналу через двухэтапное преобразование: сначала адсток (отложенный эффект), затем насыщение (убывающая отдача).",{"type":33,"tag":284,"props":285,"children":287},"h3",{"id":286},"адсток-декей-geometric-или-weibull",[288],{"type":38,"value":289},"Адсток-декей (geometric или Weibull)",{"type":33,"tag":34,"props":291,"children":292},{},[293,295,301,303,309],{"type":38,"value":294},"Эффект TV-рекламы не прекращается мгновенно — память зрителя удерживает впечатление несколько недель. Адсток моделирует это явление. Robyn поддерживает два типа: ",{"type":33,"tag":92,"props":296,"children":298},{"className":297},[],[299],{"type":38,"value":300},"geometric",{"type":38,"value":302}," (простая экспоненциальная убыль) и ",{"type":33,"tag":92,"props":304,"children":306},{"className":305},[],[307],{"type":38,"value":308},"weibull",{"type":38,"value":310}," (гибкая, S-образная кривая).",{"type":33,"tag":34,"props":312,"children":313},{},[314],{"type":33,"tag":190,"props":315,"children":316},{},[317],{"type":38,"value":318},"Geometric adstock:",{"type":33,"tag":85,"props":320,"children":322},{"code":321},"adstocked_spend[t] = spend[t] + θ × adstocked_spend[t-1]\n",[323],{"type":33,"tag":92,"props":324,"children":325},{"__ignoreMap":17},[326],{"type":38,"value":321},{"type":33,"tag":34,"props":328,"children":329},{},[330,332,338],{"type":38,"value":331},"Здесь ",{"type":33,"tag":92,"props":333,"children":335},{"className":334},[],[336],{"type":38,"value":337},"θ",{"type":38,"value":339}," (theta) — коэффициент декея. Значение 0.5 означает, что эффект предыдущей недели наполовину переходит в текущую. Robyn автоматически ищет оптимальный θ в диапазоне 0–0.9.",{"type":33,"tag":34,"props":341,"children":342},{},[343,348],{"type":33,"tag":190,"props":344,"children":345},{},[346],{"type":38,"value":347},"Weibull adstock:",{"type":38,"value":349}," Более сложный — имеет параметры shape и scale. Для awareness-каналов (TV, outdoor, influencer) Weibull часто даёт лучшую подгонку, так как эффект может медленно начинаться, достигать пика и затем быстро спадать.",{"type":33,"tag":34,"props":351,"children":352},{},[353,358],{"type":33,"tag":190,"props":354,"children":355},{},[356],{"type":38,"value":357},"Практический совет:",{"type":38,"value":359}," На первой итерации используйте geometric — сходимость быстрее. Если качество модели низко (NRMSE > 0.15) и микс содержит awareness-каналы, попробуйте Weibull.",{"type":33,"tag":284,"props":361,"children":363},{"id":362},"насыщение-hill-функция",[364],{"type":38,"value":365},"Насыщение: Hill-функция",{"type":33,"tag":34,"props":367,"children":368},{},[369],{"type":38,"value":370},"Удвоение расходов не даёт удвоения конверсий — есть убывающая отдача. Robyn моделирует это через Hill-уравнение:",{"type":33,"tag":85,"props":372,"children":374},{"code":373},"effect = spend^α \u002F (K^α + spend^α)\n",[375],{"type":33,"tag":92,"props":376,"children":377},{"__ignoreMap":17},[378],{"type":38,"value":373},{"type":33,"tag":231,"props":380,"children":381},{},[382,393],{"type":33,"tag":235,"props":383,"children":384},{},[385,391],{"type":33,"tag":92,"props":386,"children":388},{"className":387},[],[389],{"type":38,"value":390},"α",{"type":38,"value":392}," (alpha): крутизна кривой — маленькое значение означает медленное насыщение, большое — быстрое",{"type":33,"tag":235,"props":394,"children":395},{},[396,402],{"type":33,"tag":92,"props":397,"children":399},{"className":398},[],[400],{"type":38,"value":401},"K",{"type":38,"value":403},": точка полусатурации — при расходе на этом уровне достигается половина максимального эффекта",{"type":33,"tag":34,"props":405,"children":406},{},[407],{"type":38,"value":408},"Robyn находит оба параметра для каждого канала во время поиска гиперпараметров. Результат — response curve для каждого канала: например, Facebook Ads показывает plateau после 10K€ расходов, а Google Search продолжает линейный рост до 20K€.",{"type":33,"tag":34,"props":410,"children":411},{},[412,417],{"type":33,"tag":190,"props":413,"children":414},{},[415],{"type":38,"value":416},"Практическое применение кривых насыщения:",{"type":38,"value":418}," В сценариях перераспределения бюджета. Если канал уже находится в плоской зоне (низкий slope), перевод бюджета оттуда в канал с крутым slope повысит общий ROAS.",{"type":33,"tag":41,"props":420,"children":422},{"id":421},"запуск-модели-и-поиск-гиперпараметров",[423],{"type":38,"value":424},"Запуск модели и поиск гиперпараметров",{"type":33,"tag":34,"props":426,"children":427},{},[428],{"type":38,"value":429},"Установка Robyn занимает две строки:",{"type":33,"tag":85,"props":431,"children":433},{"code":432,"language":88,"meta":17,"className":89,"style":17},"install.packages(\"Robyn\")\nlibrary(Robyn)\n",[434],{"type":33,"tag":92,"props":435,"children":436},{"__ignoreMap":17},[437,445],{"type":33,"tag":96,"props":438,"children":439},{"class":98,"line":99},[440],{"type":33,"tag":96,"props":441,"children":442},{},[443],{"type":38,"value":444},"install.packages(\"Robyn\")\n",{"type":33,"tag":96,"props":446,"children":447},{"class":98,"line":108},[448],{"type":33,"tag":96,"props":449,"children":450},{},[451],{"type":38,"value":452},"library(Robyn)\n",{"type":33,"tag":34,"props":454,"children":455},{},[456],{"type":38,"value":457},"В функции InputCollect определяется структура данных:",{"type":33,"tag":85,"props":459,"children":461},{"code":460,"language":88,"meta":17,"className":89,"style":17},"InputCollect \u003C- robyn_inputs(\n  dt_input = data,\n  date_var = \"date\",\n  dep_var = \"revenue\",\n  paid_media_spends = c(\"facebook_spend\", \"google_search_spend\", \"display_spend\"),\n  context_vars = c(\"competitor_index\", \"holiday_flag\"),\n  window_start = \"2024-01-01\",\n  window_end = \"2025-12-31\",\n  adstock = \"geometric\"  # или \"weibull\"\n)\n",[462],{"type":33,"tag":92,"props":463,"children":464},{"__ignoreMap":17},[465,473,481,489,497,505,513,521,529,537],{"type":33,"tag":96,"props":466,"children":467},{"class":98,"line":99},[468],{"type":33,"tag":96,"props":469,"children":470},{},[471],{"type":38,"value":472},"InputCollect \u003C- robyn_inputs(\n",{"type":33,"tag":96,"props":474,"children":475},{"class":98,"line":108},[476],{"type":33,"tag":96,"props":477,"children":478},{},[479],{"type":38,"value":480},"  dt_input = data,\n",{"type":33,"tag":96,"props":482,"children":483},{"class":98,"line":117},[484],{"type":33,"tag":96,"props":485,"children":486},{},[487],{"type":38,"value":488},"  date_var = \"date\",\n",{"type":33,"tag":96,"props":490,"children":491},{"class":98,"line":126},[492],{"type":33,"tag":96,"props":493,"children":494},{},[495],{"type":38,"value":496},"  dep_var = \"revenue\",\n",{"type":33,"tag":96,"props":498,"children":499},{"class":98,"line":135},[500],{"type":33,"tag":96,"props":501,"children":502},{},[503],{"type":38,"value":504},"  paid_media_spends = c(\"facebook_spend\", \"google_search_spend\", \"display_spend\"),\n",{"type":33,"tag":96,"props":506,"children":507},{"class":98,"line":144},[508],{"type":33,"tag":96,"props":509,"children":510},{},[511],{"type":38,"value":512},"  context_vars = c(\"competitor_index\", \"holiday_flag\"),\n",{"type":33,"tag":96,"props":514,"children":515},{"class":98,"line":153},[516],{"type":33,"tag":96,"props":517,"children":518},{},[519],{"type":38,"value":520},"  window_start = \"2024-01-01\",\n",{"type":33,"tag":96,"props":522,"children":523},{"class":98,"line":27},[524],{"type":33,"tag":96,"props":525,"children":526},{},[527],{"type":38,"value":528},"  window_end = \"2025-12-31\",\n",{"type":33,"tag":96,"props":530,"children":531},{"class":98,"line":170},[532],{"type":33,"tag":96,"props":533,"children":534},{},[535],{"type":38,"value":536},"  adstock = \"geometric\"  # или \"weibull\"\n",{"type":33,"tag":96,"props":538,"children":539},{"class":98,"line":179},[540],{"type":33,"tag":96,"props":541,"children":542},{},[543],{"type":38,"value":185},{"type":33,"tag":34,"props":545,"children":546},{},[547,552],{"type":33,"tag":190,"props":548,"children":549},{},[550],{"type":38,"value":551},"Диапазоны гиперпараметров:",{"type":38,"value":553},"\nRobyn ищет для каждого канала значения theta адстока и alpha\u002FK насыщения в заданном диапазоне. Default ranges обычно достаточны, но при наличии domain-knowledge можно добавить ограничения:",{"type":33,"tag":85,"props":555,"children":557},{"code":556,"language":88,"meta":17,"className":89,"style":17},"hyperparameters \u003C- list(\n  facebook_spend_alphas = c(0.5, 3),   # крутизна насыщения\n  facebook_spend_gammas = c(0.3, 1),   # inflection point насыщения\n  facebook_spend_thetas = c(0, 0.5)    # адсток-декей (geometric)\n)\n",[558],{"type":33,"tag":92,"props":559,"children":560},{"__ignoreMap":17},[561,569,577,585,593],{"type":33,"tag":96,"props":562,"children":563},{"class":98,"line":99},[564],{"type":33,"tag":96,"props":565,"children":566},{},[567],{"type":38,"value":568},"hyperparameters \u003C- list(\n",{"type":33,"tag":96,"props":570,"children":571},{"class":98,"line":108},[572],{"type":33,"tag":96,"props":573,"children":574},{},[575],{"type":38,"value":576},"  facebook_spend_alphas = c(0.5, 3),   # крутизна насыщения\n",{"type":33,"tag":96,"props":578,"children":579},{"class":98,"line":117},[580],{"type":33,"tag":96,"props":581,"children":582},{},[583],{"type":38,"value":584},"  facebook_spend_gammas = c(0.3, 1),   # inflection point насыщения\n",{"type":33,"tag":96,"props":586,"children":587},{"class":98,"line":126},[588],{"type":33,"tag":96,"props":589,"children":590},{},[591],{"type":38,"value":592},"  facebook_spend_thetas = c(0, 0.5)    # адсток-декей (geometric)\n",{"type":33,"tag":96,"props":594,"children":595},{"class":98,"line":135},[596],{"type":33,"tag":96,"props":597,"children":598},{},[599],{"type":38,"value":185},{"type":33,"tag":34,"props":601,"children":602},{},[603],{"type":38,"value":604},"Запуск модели:",{"type":33,"tag":85,"props":606,"children":608},{"code":607,"language":88,"meta":17,"className":89,"style":17},"OutputModels \u003C- robyn_run(\n  InputCollect = InputCollect,\n  iterations = 2000,     # iterations генетического алгоритма\n  trials = 5,            # количество random seeds\n  cores = 4\n)\n",[609],{"type":33,"tag":92,"props":610,"children":611},{"__ignoreMap":17},[612,620,628,636,644,652],{"type":33,"tag":96,"props":613,"children":614},{"class":98,"line":99},[615],{"type":33,"tag":96,"props":616,"children":617},{},[618],{"type":38,"value":619},"OutputModels \u003C- robyn_run(\n",{"type":33,"tag":96,"props":621,"children":622},{"class":98,"line":108},[623],{"type":33,"tag":96,"props":624,"children":625},{},[626],{"type":38,"value":627},"  InputCollect = InputCollect,\n",{"type":33,"tag":96,"props":629,"children":630},{"class":98,"line":117},[631],{"type":33,"tag":96,"props":632,"children":633},{},[634],{"type":38,"value":635},"  iterations = 2000,     # iterations генетического алгоритма\n",{"type":33,"tag":96,"props":637,"children":638},{"class":98,"line":126},[639],{"type":33,"tag":96,"props":640,"children":641},{},[642],{"type":38,"value":643},"  trials = 5,            # количество random seeds\n",{"type":33,"tag":96,"props":645,"children":646},{"class":98,"line":135},[647],{"type":33,"tag":96,"props":648,"children":649},{},[650],{"type":38,"value":651},"  cores = 4\n",{"type":33,"tag":96,"props":653,"children":654},{"class":98,"line":144},[655],{"type":33,"tag":96,"props":656,"children":657},{},[658],{"type":38,"value":185},{"type":33,"tag":34,"props":660,"children":661},{},[662],{"type":38,"value":663},"Этот шаг занимает 10–30 минут (зависит от объёма данных). На выходе — набор Pareto-оптимальных моделей, сбалансированных по NRMSE (качество подгонки) и DECOMP.RSSD (гладкость распределения вклада каналов).",{"type":33,"tag":34,"props":665,"children":666},{},[667,672,674,680,682,688],{"type":33,"tag":190,"props":668,"children":669},{},[670],{"type":38,"value":671},"Выбор модели:",{"type":38,"value":673}," Robyn предлагает 10–20 Pareto-моделей. Выбор модели с минимальным NRMSE не всегда правилен — некоторые могут переучиться. Функция ",{"type":33,"tag":92,"props":675,"children":677},{"className":676},[],[678],{"type":38,"value":679},"robyn_outputs()",{"type":38,"value":681}," с параметром ",{"type":33,"tag":92,"props":683,"children":685},{"className":684},[],[686],{"type":38,"value":687},"robyn_clusters",{"type":38,"value":689}," позволяет кластеризовать модели и выбрать центр наиболее стабильного кластера.",{"type":33,"tag":41,"props":691,"children":693},{"id":692},"holdout-валидация-измерение-надёжности-модели",[694],{"type":38,"value":695},"Holdout-валидация: измерение надёжности модели",{"type":33,"tag":34,"props":697,"children":698},{},[699],{"type":38,"value":700},"Одна из ключевых возможностей Robyn — встроенная holdout-валидация. Во время обучения последние N недель сохраняются как тестовый набор; затем модель делает прогноз на эти недели и сравнивает с фактическими значениями.",{"type":33,"tag":85,"props":702,"children":704},{"code":703,"language":88,"meta":17,"className":89,"style":17},"# Holdout последние 8 недель\nOutputModels \u003C- robyn_run(\n  InputCollect = InputCollect,\n  iterations = 2000,\n  trials = 5,\n  cores = 4,\n  calibration_input = NULL,\n  holdout_periods = 8  # последние 8 недель как тестовый набор\n)\n",[705],{"type":33,"tag":92,"props":706,"children":707},{"__ignoreMap":17},[708,716,723,730,738,746,754,762,770],{"type":33,"tag":96,"props":709,"children":710},{"class":98,"line":99},[711],{"type":33,"tag":96,"props":712,"children":713},{},[714],{"type":38,"value":715},"# Holdout последние 8 недель\n",{"type":33,"tag":96,"props":717,"children":718},{"class":98,"line":108},[719],{"type":33,"tag":96,"props":720,"children":721},{},[722],{"type":38,"value":619},{"type":33,"tag":96,"props":724,"children":725},{"class":98,"line":117},[726],{"type":33,"tag":96,"props":727,"children":728},{},[729],{"type":38,"value":627},{"type":33,"tag":96,"props":731,"children":732},{"class":98,"line":126},[733],{"type":33,"tag":96,"props":734,"children":735},{},[736],{"type":38,"value":737},"  iterations = 2000,\n",{"type":33,"tag":96,"props":739,"children":740},{"class":98,"line":135},[741],{"type":33,"tag":96,"props":742,"children":743},{},[744],{"type":38,"value":745},"  trials = 5,\n",{"type":33,"tag":96,"props":747,"children":748},{"class":98,"line":144},[749],{"type":33,"tag":96,"props":750,"children":751},{},[752],{"type":38,"value":753},"  cores = 4,\n",{"type":33,"tag":96,"props":755,"children":756},{"class":98,"line":153},[757],{"type":33,"tag":96,"props":758,"children":759},{},[760],{"type":38,"value":761},"  calibration_input = NULL,\n",{"type":33,"tag":96,"props":763,"children":764},{"class":98,"line":27},[765],{"type":33,"tag":96,"props":766,"children":767},{},[768],{"type":38,"value":769},"  holdout_periods = 8  # последние 8 недель как тестовый набор\n",{"type":33,"tag":96,"props":771,"children":772},{"class":98,"line":170},[773],{"type":33,"tag":96,"props":774,"children":775},{},[776],{"type":38,"value":185},{"type":33,"tag":34,"props":778,"children":779},{},[780,782,788],{"type":38,"value":781},"Результаты holdout-валидации в ",{"type":33,"tag":92,"props":783,"children":785},{"className":784},[],[786],{"type":38,"value":787},"OutputModels$resultHypParam",{"type":38,"value":789},":",{"type":33,"tag":791,"props":792,"children":793},"table",{},[794,823],{"type":33,"tag":795,"props":796,"children":797},"thead",{},[798],{"type":33,"tag":799,"props":800,"children":801},"tr",{},[802,808,813,818],{"type":33,"tag":803,"props":804,"children":805},"th",{},[806],{"type":38,"value":807},"Model ID",{"type":33,"tag":803,"props":809,"children":810},{},[811],{"type":38,"value":812},"Train NRMSE",{"type":33,"tag":803,"props":814,"children":815},{},[816],{"type":38,"value":817},"Holdout MAPE",{"type":33,"tag":803,"props":819,"children":820},{},[821],{"type":38,"value":822},"Holdout NRMSE",{"type":33,"tag":824,"props":825,"children":826},"tbody",{},[827,851],{"type":33,"tag":799,"props":828,"children":829},{},[830,836,841,846],{"type":33,"tag":831,"props":832,"children":833},"td",{},[834],{"type":38,"value":835},"1_123_4",{"type":33,"tag":831,"props":837,"children":838},{},[839],{"type":38,"value":840},"0.08",{"type":33,"tag":831,"props":842,"children":843},{},[844],{"type":38,"value":845},"12.3%",{"type":33,"tag":831,"props":847,"children":848},{},[849],{"type":38,"value":850},"0.14",{"type":33,"tag":799,"props":852,"children":853},{},[854,859,864,869],{"type":33,"tag":831,"props":855,"children":856},{},[857],{"type":38,"value":858},"2_456_1",{"type":33,"tag":831,"props":860,"children":861},{},[862],{"type":38,"value":863},"0.07",{"type":33,"tag":831,"props":865,"children":866},{},[867],{"type":38,"value":868},"18.5%",{"type":33,"tag":831,"props":870,"children":871},{},[872],{"type":38,"value":873},"0.21",{"type":33,"tag":34,"props":875,"children":876},{},[877,882],{"type":33,"tag":190,"props":878,"children":879},{},[880],{"type":38,"value":881},"Holdout MAPE \u003C 15%",{"type":38,"value":883}," обычно считается production-ready. Значения выше 20% указывают на слабую предсказательную способность модели — либо проблемы с качеством данных, либо слишком широкие диапазоны гиперпараметров.",{"type":33,"tag":34,"props":885,"children":886},{},[887,892],{"type":33,"tag":190,"props":888,"children":889},{},[890],{"type":38,"value":891},"Практическая ловушка:",{"type":38,"value":893}," Если в holdout-периоде произошло аномальное событие (outage платформы, вирусная кампания), модель не сможет его предсказать и MAPE резко возрастёт. В таких случаях сдвиньте holdout-период или пометьте неделю как аномалию.",{"type":33,"tag":34,"props":895,"children":896},{},[897,899,906],{"type":38,"value":898},"Holdout-валидация имеет дополнительное применение: cross-check с результатами incrementality-тестов. Если MMM показывает 30% ROAS для Facebook, а прошлый geo-split-тест дал 15%, это сигнал, что MMM припишет Facebook часть макроэффекта (сезонность, органический тренд). Обнаружение таких несостыковок — часть процесса в ",{"type":33,"tag":63,"props":900,"children":903},{"href":901,"rel":902},"https:\u002F\u002Fwww.roibase.com.tr\u002Fru\u002Fretention-engineering-cdp",[67],[904],{"type":38,"value":905},"CDP & retention engineering",{"type":38,"value":907},", где MMM-output подключается к dashboard'у экспериментов.",{"type":33,"tag":41,"props":909,"children":911},{"id":910},"оптимизация-бюджета-и-планирование-сценариев",[912],{"type":38,"value":913},"Оптимизация бюджета и планирование сценариев",{"type":33,"tag":34,"props":915,"children":916},{},[917,919,924,926,931],{"type":38,"value":918},"После построения Robyn-модели открываются два основных применения: ",{"type":33,"tag":190,"props":920,"children":921},{},[922],{"type":38,"value":923},"перераспределение бюджета",{"type":38,"value":925}," (оптимальное распределение по каналам) и ",{"type":33,"tag":190,"props":927,"children":928},{},[929],{"type":38,"value":930},"what-if сценарии",{"type":38,"value":932}," (что если увеличить бюджет на 20%).",{"type":33,"tag":34,"props":934,"children":935},{},[936],{"type":33,"tag":190,"props":937,"children":938},{},[939],{"type":38,"value":940},"Budget allocator:",{"type":33,"tag":85,"props":942,"children":944},{"code":943,"language":88,"meta":17,"className":89,"style":17},"AllocatorCollect \u003C- robyn_allocator(\n  InputCollect = InputCollect,\n  OutputCollect = OutputModels,\n  select_model = \"1_123_4\",  # выбранная Pareto-модель\n  scenario = \"max_response\",  # или \"target_efficiency\"\n  channel_constr_low = 0.7,   # минимум 70% текущего бюджета на канал\n  channel_constr_up = 1.5     # максимум 150%\n)\n",[945],{"type":33,"tag":92,"props":946,"children":947},{"__ignoreMap":17},[948,956,963,971,979,987,995,1003],{"type":33,"tag":96,"props":949,"children":950},{"class":98,"line":99},[951],{"type":33,"tag":96,"props":952,"children":953},{},[954],{"type":38,"value":955},"AllocatorCollect \u003C- robyn_allocator(\n",{"type":33,"tag":96,"props":957,"children":958},{"class":98,"line":108},[959],{"type":33,"tag":96,"props":960,"children":961},{},[962],{"type":38,"value":627},{"type":33,"tag":96,"props":964,"children":965},{"class":98,"line":117},[966],{"type":33,"tag":96,"props":967,"children":968},{},[969],{"type":38,"value":970},"  OutputCollect = OutputModels,\n",{"type":33,"tag":96,"props":972,"children":973},{"class":98,"line":126},[974],{"type":33,"tag":96,"props":975,"children":976},{},[977],{"type":38,"value":978},"  select_model = \"1_123_4\",  # выбранная Pareto-модель\n",{"type":33,"tag":96,"props":980,"children":981},{"class":98,"line":135},[982],{"type":33,"tag":96,"props":983,"children":984},{},[985],{"type":38,"value":986},"  scenario = \"max_response\",  # или \"target_efficiency\"\n",{"type":33,"tag":96,"props":988,"children":989},{"class":98,"line":144},[990],{"type":33,"tag":96,"props":991,"children":992},{},[993],{"type":38,"value":994},"  channel_constr_low = 0.7,   # минимум 70% текущего бюджета на канал\n",{"type":33,"tag":96,"props":996,"children":997},{"class":98,"line":153},[998],{"type":33,"tag":96,"props":999,"children":1000},{},[1001],{"type":38,"value":1002},"  channel_constr_up = 1.5     # максимум 150%\n",{"type":33,"tag":96,"props":1004,"children":1005},{"class":98,"line":27},[1006],{"type":33,"tag":96,"props":1007,"children":1008},{},[1009],{"type":38,"value":185},{"type":33,"tag":34,"props":1011,"children":1012},{},[1013],{"type":38,"value":1014},"Результат — рекомендованные новые расходы и ожидаемый incremental-до",{"type":33,"tag":1016,"props":1017,"children":1018},"style",{},[1019],{"type":38,"value":1020},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":17,"searchDepth":117,"depth":117,"links":1022},[1023,1024,1025,1029,1030,1031],{"id":43,"depth":108,"text":46},{"id":75,"depth":108,"text":78},{"id":274,"depth":108,"text":277,"children":1026},[1027,1028],{"id":286,"depth":117,"text":289},{"id":362,"depth":117,"text":365},{"id":421,"depth":108,"text":424},{"id":692,"depth":108,"text":695},{"id":910,"depth":108,"text":913},"markdown","content:ru:data:marketing-mix-modeling-robyn-practical-setup.md","content","ru\u002Fdata\u002Fmarketing-mix-modeling-robyn-practical-setup.md","ru\u002Fdata\u002Fmarketing-mix-modeling-robyn-practical-setup","md",1785276306896]