[{"data":1,"prerenderedAt":1999},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fru\u002Fdata\u002Fmarketing-mix-modeling-robyn-prakticheskaya-realizacija":13},{"i18nKey":4,"paths":5},"data-005-2026-06",{"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-practical-setup-with-robyn","\u002Fes\u002Fdata\u002Fmarketing-mix-modeling-robyn-setup-practico","\u002Ffr\u002Fdata\u002Frobyn-marketing-mix-modeling-guide","\u002Fit\u002Fdata\u002Frobyn-marketing-mix-modeling-setup-pratico","\u002Fru\u002Fdata\u002Fmarketing-mix-modeling-robyn-prakticheskaya-setup","\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":1993,"_id":1994,"_source":1995,"_file":1996,"_stem":1997,"_extension":1998},"\u002Fru\u002Fdata\u002Fmarketing-mix-modeling-robyn-prakticheskaya-realizacija","data",false,"","Marketing Mix Modeling: практическая реализация с Robyn","Строим модель атрибуции с кривыми насыщения, decay адстока и holdout валидацией на фреймворке Robyn от Meta. SQL, R и production pipeline.","2026-06-21",[22,23,24,25,26],"marketing-mix-modeling","robyn","adstock","attribution","mmm",8,"Roibase",{"type":30,"children":31,"toc":1984},"root",[32,40,47,52,72,90,100,106,111,887,900,974,979,985,997,1187,1195,1230,1235,1241,1303,1314,1327,1491,1496,1543,1549,1554,1674,1679,1685,1698,1759,1764,1800,1805,1811,1827,1932,1937,1978],{"type":33,"tag":34,"props":35,"children":36},"element","p",{},[37],{"type":38,"value":39},"text","Deprecation cookies и нормативно-правовые требования сдвигают атрибуцию от детерминированных методов к вероятностному моделированию. Marketing Mix Modeling (MMM) — статистический инструмент 1960-х годов — вновь становится центральным звеном. Фреймворк Robyn от Meta обеспечивает практическую реализацию этого перехода: байесовский вывод, кривые насыщения и decay адстока связывают еженедельные маркетинговые расходы с продажами и переносят регрессионную модель в production. Статья показывает, как развернуть Robyn, применить модель к реальным данным, провести grid search гиперпараметров и использовать 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 — это фреймворк MMM с открытым исходным кодом, написанный на R. Meta разработала его для собственной маркетинговой команды в 2020 году и выпустила в 2021-м. Основные отличия от классической линейной регрессии:",{"type":33,"tag":34,"props":53,"children":54},{},[55,61,63,70],{"type":33,"tag":56,"props":57,"children":58},"strong",{},[59],{"type":38,"value":60},"Трансформация адстока",{"type":38,"value":62},": маркетинговый эффект не проявляется мгновенно — ТВ-реклама формирует узнаваемость бренда в течение недель. Адсток моделирует вклад прошлых расходов в текущие продажи через экспоненциальный decay. Robyn поддерживает геометрический и Weibull адсток. Геометрический вариант проще: ",{"type":33,"tag":64,"props":65,"children":67},"code",{"className":66},[],[68],{"type":38,"value":69},"adstock_t = spend_t + θ × adstock_(t-1)",{"type":38,"value":71},", где θ — параметр затухания. Weibull дает большую гибкость — можно смещать пиковый эффект.",{"type":33,"tag":34,"props":73,"children":74},{},[75,80,82,88],{"type":33,"tag":56,"props":76,"children":77},{},[78],{"type":38,"value":79},"Насыщение (diminishing returns)",{"type":38,"value":81},": связь расходов и продаж нелинейна. Первые 100 тыс. руб. могут дать 80% ROI, а следующие 100 тыс. — только 40%. Robyn применяет Hill и S-кривые насыщения. Уравнение Hill: ",{"type":33,"tag":64,"props":83,"children":85},{"className":84},[],[86],{"type":38,"value":87},"y = V_max × x^n \u002F (K^n + x^n)",{"type":38,"value":89},", где K — точка полунасыщения, n — крутизна. Эта нелинейность критична для оптимизации бюджета по каналам.",{"type":33,"tag":34,"props":91,"children":92},{},[93,98],{"type":33,"tag":56,"props":94,"children":95},{},[96],{"type":38,"value":97},"Настройка гиперпараметров",{"type":38,"value":99},": значения decay адстока, K и n насыщения неизвестны — их ищут через grid search. Robyn использует генетический алгоритм (NSGAII), проверяя тысячи комбинаций параметров и выбирая лучший компромисс на парето-фронтье.",{"type":33,"tag":41,"props":101,"children":103},{"id":102},"подготовка-данных-от-sql-к-еженедельной-гранулярности",[104],{"type":38,"value":105},"Подготовка данных: от SQL к еженедельной гранулярности",{"type":33,"tag":34,"props":107,"children":108},{},[109],{"type":38,"value":110},"Robyn работает с еженедельной гранулярностью. Из логов дневных транзакций агрегируются еженедельные доход и медиа-расходы. Пример запроса в BigQuery:",{"type":33,"tag":112,"props":113,"children":117},"pre",{"className":114,"code":115,"language":116,"meta":17,"style":17},"language-sql shiki shiki-themes github-dark","WITH weekly_revenue AS (\n  SELECT\n    DATE_TRUNC(order_date, WEEK) AS week_start,\n    SUM(revenue) AS revenue\n  FROM `project.dataset.orders`\n  WHERE order_date >= '2024-01-01'\n  GROUP BY 1\n),\nweekly_spend AS (\n  SELECT\n    DATE_TRUNC(date, WEEK) AS week_start,\n    channel,\n    SUM(cost) AS spend\n  FROM `project.dataset.marketing_costs`\n  WHERE date >= '2024-01-01'\n  GROUP BY 1, 2\n)\nSELECT\n  r.week_start,\n  r.revenue,\n  COALESCE(s_google.spend, 0) AS google_search_spend,\n  COALESCE(s_meta.spend, 0) AS meta_paid_social_spend,\n  COALESCE(s_tv.spend, 0) AS tv_spend\nFROM weekly_revenue r\nLEFT JOIN weekly_spend s_google\n  ON r.week_start = s_google.week_start AND s_google.channel = 'google_search'\nLEFT JOIN weekly_spend s_meta\n  ON r.week_start = s_meta.week_start AND s_meta.channel = 'meta'\nLEFT JOIN weekly_spend s_tv\n  ON r.week_start = s_tv.week_start AND s_tv.channel = 'tv'\nORDER BY 1;\n","sql",[118],{"type":33,"tag":64,"props":119,"children":120},{"__ignoreMap":17},[121,149,158,186,210,225,249,263,271,288,296,331,340,362,375,397,419,428,437,461,482,532,578,624,638,652,719,732,794,807,869],{"type":33,"tag":122,"props":123,"children":126},"span",{"class":124,"line":125},"line",1,[127,133,139,144],{"type":33,"tag":122,"props":128,"children":130},{"style":129},"--shiki-default:#F97583",[131],{"type":38,"value":132},"WITH",{"type":33,"tag":122,"props":134,"children":136},{"style":135},"--shiki-default:#E1E4E8",[137],{"type":38,"value":138}," weekly_revenue ",{"type":33,"tag":122,"props":140,"children":141},{"style":129},[142],{"type":38,"value":143},"AS",{"type":33,"tag":122,"props":145,"children":146},{"style":135},[147],{"type":38,"value":148}," (\n",{"type":33,"tag":122,"props":150,"children":152},{"class":124,"line":151},2,[153],{"type":33,"tag":122,"props":154,"children":155},{"style":129},[156],{"type":38,"value":157},"  SELECT\n",{"type":33,"tag":122,"props":159,"children":161},{"class":124,"line":160},3,[162,167,172,177,181],{"type":33,"tag":122,"props":163,"children":164},{"style":135},[165],{"type":38,"value":166},"    DATE_TRUNC(order_date, ",{"type":33,"tag":122,"props":168,"children":169},{"style":129},[170],{"type":38,"value":171},"WEEK",{"type":33,"tag":122,"props":173,"children":174},{"style":135},[175],{"type":38,"value":176},") ",{"type":33,"tag":122,"props":178,"children":179},{"style":129},[180],{"type":38,"value":143},{"type":33,"tag":122,"props":182,"children":183},{"style":135},[184],{"type":38,"value":185}," week_start,\n",{"type":33,"tag":122,"props":187,"children":189},{"class":124,"line":188},4,[190,196,201,205],{"type":33,"tag":122,"props":191,"children":193},{"style":192},"--shiki-default:#79B8FF",[194],{"type":38,"value":195},"    SUM",{"type":33,"tag":122,"props":197,"children":198},{"style":135},[199],{"type":38,"value":200},"(revenue) ",{"type":33,"tag":122,"props":202,"children":203},{"style":129},[204],{"type":38,"value":143},{"type":33,"tag":122,"props":206,"children":207},{"style":135},[208],{"type":38,"value":209}," revenue\n",{"type":33,"tag":122,"props":211,"children":213},{"class":124,"line":212},5,[214,219],{"type":33,"tag":122,"props":215,"children":216},{"style":129},[217],{"type":38,"value":218},"  FROM",{"type":33,"tag":122,"props":220,"children":222},{"style":221},"--shiki-default:#9ECBFF",[223],{"type":38,"value":224}," `project.dataset.orders`\n",{"type":33,"tag":122,"props":226,"children":228},{"class":124,"line":227},6,[229,234,239,244],{"type":33,"tag":122,"props":230,"children":231},{"style":129},[232],{"type":38,"value":233},"  WHERE",{"type":33,"tag":122,"props":235,"children":236},{"style":135},[237],{"type":38,"value":238}," order_date ",{"type":33,"tag":122,"props":240,"children":241},{"style":129},[242],{"type":38,"value":243},">=",{"type":33,"tag":122,"props":245,"children":246},{"style":221},[247],{"type":38,"value":248}," '2024-01-01'\n",{"type":33,"tag":122,"props":250,"children":252},{"class":124,"line":251},7,[253,258],{"type":33,"tag":122,"props":254,"children":255},{"style":129},[256],{"type":38,"value":257},"  GROUP BY",{"type":33,"tag":122,"props":259,"children":260},{"style":192},[261],{"type":38,"value":262}," 1\n",{"type":33,"tag":122,"props":264,"children":265},{"class":124,"line":27},[266],{"type":33,"tag":122,"props":267,"children":268},{"style":135},[269],{"type":38,"value":270},"),\n",{"type":33,"tag":122,"props":272,"children":274},{"class":124,"line":273},9,[275,280,284],{"type":33,"tag":122,"props":276,"children":277},{"style":135},[278],{"type":38,"value":279},"weekly_spend ",{"type":33,"tag":122,"props":281,"children":282},{"style":129},[283],{"type":38,"value":143},{"type":33,"tag":122,"props":285,"children":286},{"style":135},[287],{"type":38,"value":148},{"type":33,"tag":122,"props":289,"children":291},{"class":124,"line":290},10,[292],{"type":33,"tag":122,"props":293,"children":294},{"style":129},[295],{"type":38,"value":157},{"type":33,"tag":122,"props":297,"children":299},{"class":124,"line":298},11,[300,305,310,315,319,323,327],{"type":33,"tag":122,"props":301,"children":302},{"style":135},[303],{"type":38,"value":304},"    DATE_TRUNC(",{"type":33,"tag":122,"props":306,"children":307},{"style":129},[308],{"type":38,"value":309},"date",{"type":33,"tag":122,"props":311,"children":312},{"style":135},[313],{"type":38,"value":314},", ",{"type":33,"tag":122,"props":316,"children":317},{"style":129},[318],{"type":38,"value":171},{"type":33,"tag":122,"props":320,"children":321},{"style":135},[322],{"type":38,"value":176},{"type":33,"tag":122,"props":324,"children":325},{"style":129},[326],{"type":38,"value":143},{"type":33,"tag":122,"props":328,"children":329},{"style":135},[330],{"type":38,"value":185},{"type":33,"tag":122,"props":332,"children":334},{"class":124,"line":333},12,[335],{"type":33,"tag":122,"props":336,"children":337},{"style":135},[338],{"type":38,"value":339},"    channel,\n",{"type":33,"tag":122,"props":341,"children":343},{"class":124,"line":342},13,[344,348,353,357],{"type":33,"tag":122,"props":345,"children":346},{"style":192},[347],{"type":38,"value":195},{"type":33,"tag":122,"props":349,"children":350},{"style":135},[351],{"type":38,"value":352},"(cost) ",{"type":33,"tag":122,"props":354,"children":355},{"style":129},[356],{"type":38,"value":143},{"type":33,"tag":122,"props":358,"children":359},{"style":135},[360],{"type":38,"value":361}," spend\n",{"type":33,"tag":122,"props":363,"children":365},{"class":124,"line":364},14,[366,370],{"type":33,"tag":122,"props":367,"children":368},{"style":129},[369],{"type":38,"value":218},{"type":33,"tag":122,"props":371,"children":372},{"style":221},[373],{"type":38,"value":374}," `project.dataset.marketing_costs`\n",{"type":33,"tag":122,"props":376,"children":378},{"class":124,"line":377},15,[379,383,388,393],{"type":33,"tag":122,"props":380,"children":381},{"style":129},[382],{"type":38,"value":233},{"type":33,"tag":122,"props":384,"children":385},{"style":129},[386],{"type":38,"value":387}," date",{"type":33,"tag":122,"props":389,"children":390},{"style":129},[391],{"type":38,"value":392}," >=",{"type":33,"tag":122,"props":394,"children":395},{"style":221},[396],{"type":38,"value":248},{"type":33,"tag":122,"props":398,"children":400},{"class":124,"line":399},16,[401,405,410,414],{"type":33,"tag":122,"props":402,"children":403},{"style":129},[404],{"type":38,"value":257},{"type":33,"tag":122,"props":406,"children":407},{"style":192},[408],{"type":38,"value":409}," 1",{"type":33,"tag":122,"props":411,"children":412},{"style":135},[413],{"type":38,"value":314},{"type":33,"tag":122,"props":415,"children":416},{"style":192},[417],{"type":38,"value":418},"2\n",{"type":33,"tag":122,"props":420,"children":422},{"class":124,"line":421},17,[423],{"type":33,"tag":122,"props":424,"children":425},{"style":135},[426],{"type":38,"value":427},")\n",{"type":33,"tag":122,"props":429,"children":431},{"class":124,"line":430},18,[432],{"type":33,"tag":122,"props":433,"children":434},{"style":129},[435],{"type":38,"value":436},"SELECT\n",{"type":33,"tag":122,"props":438,"children":440},{"class":124,"line":439},19,[441,446,451,456],{"type":33,"tag":122,"props":442,"children":443},{"style":192},[444],{"type":38,"value":445},"  r",{"type":33,"tag":122,"props":447,"children":448},{"style":135},[449],{"type":38,"value":450},".",{"type":33,"tag":122,"props":452,"children":453},{"style":192},[454],{"type":38,"value":455},"week_start",{"type":33,"tag":122,"props":457,"children":458},{"style":135},[459],{"type":38,"value":460},",\n",{"type":33,"tag":122,"props":462,"children":464},{"class":124,"line":463},20,[465,469,473,478],{"type":33,"tag":122,"props":466,"children":467},{"style":192},[468],{"type":38,"value":445},{"type":33,"tag":122,"props":470,"children":471},{"style":135},[472],{"type":38,"value":450},{"type":33,"tag":122,"props":474,"children":475},{"style":192},[476],{"type":38,"value":477},"revenue",{"type":33,"tag":122,"props":479,"children":480},{"style":135},[481],{"type":38,"value":460},{"type":33,"tag":122,"props":483,"children":485},{"class":124,"line":484},21,[486,491,496,501,505,510,514,519,523,527],{"type":33,"tag":122,"props":487,"children":488},{"style":192},[489],{"type":38,"value":490},"  COALESCE",{"type":33,"tag":122,"props":492,"children":493},{"style":135},[494],{"type":38,"value":495},"(",{"type":33,"tag":122,"props":497,"children":498},{"style":192},[499],{"type":38,"value":500},"s_google",{"type":33,"tag":122,"props":502,"children":503},{"style":135},[504],{"type":38,"value":450},{"type":33,"tag":122,"props":506,"children":507},{"style":192},[508],{"type":38,"value":509},"spend",{"type":33,"tag":122,"props":511,"children":512},{"style":135},[513],{"type":38,"value":314},{"type":33,"tag":122,"props":515,"children":516},{"style":192},[517],{"type":38,"value":518},"0",{"type":33,"tag":122,"props":520,"children":521},{"style":135},[522],{"type":38,"value":176},{"type":33,"tag":122,"props":524,"children":525},{"style":129},[526],{"type":38,"value":143},{"type":33,"tag":122,"props":528,"children":529},{"style":135},[530],{"type":38,"value":531}," google_search_spend,\n",{"type":33,"tag":122,"props":533,"children":535},{"class":124,"line":534},22,[536,540,544,549,553,557,561,565,569,573],{"type":33,"tag":122,"props":537,"children":538},{"style":192},[539],{"type":38,"value":490},{"type":33,"tag":122,"props":541,"children":542},{"style":135},[543],{"type":38,"value":495},{"type":33,"tag":122,"props":545,"children":546},{"style":192},[547],{"type":38,"value":548},"s_meta",{"type":33,"tag":122,"props":550,"children":551},{"style":135},[552],{"type":38,"value":450},{"type":33,"tag":122,"props":554,"children":555},{"style":192},[556],{"type":38,"value":509},{"type":33,"tag":122,"props":558,"children":559},{"style":135},[560],{"type":38,"value":314},{"type":33,"tag":122,"props":562,"children":563},{"style":192},[564],{"type":38,"value":518},{"type":33,"tag":122,"props":566,"children":567},{"style":135},[568],{"type":38,"value":176},{"type":33,"tag":122,"props":570,"children":571},{"style":129},[572],{"type":38,"value":143},{"type":33,"tag":122,"props":574,"children":575},{"style":135},[576],{"type":38,"value":577}," meta_paid_social_spend,\n",{"type":33,"tag":122,"props":579,"children":581},{"class":124,"line":580},23,[582,586,590,595,599,603,607,611,615,619],{"type":33,"tag":122,"props":583,"children":584},{"style":192},[585],{"type":38,"value":490},{"type":33,"tag":122,"props":587,"children":588},{"style":135},[589],{"type":38,"value":495},{"type":33,"tag":122,"props":591,"children":592},{"style":192},[593],{"type":38,"value":594},"s_tv",{"type":33,"tag":122,"props":596,"children":597},{"style":135},[598],{"type":38,"value":450},{"type":33,"tag":122,"props":600,"children":601},{"style":192},[602],{"type":38,"value":509},{"type":33,"tag":122,"props":604,"children":605},{"style":135},[606],{"type":38,"value":314},{"type":33,"tag":122,"props":608,"children":609},{"style":192},[610],{"type":38,"value":518},{"type":33,"tag":122,"props":612,"children":613},{"style":135},[614],{"type":38,"value":176},{"type":33,"tag":122,"props":616,"children":617},{"style":129},[618],{"type":38,"value":143},{"type":33,"tag":122,"props":620,"children":621},{"style":135},[622],{"type":38,"value":623}," tv_spend\n",{"type":33,"tag":122,"props":625,"children":627},{"class":124,"line":626},24,[628,633],{"type":33,"tag":122,"props":629,"children":630},{"style":129},[631],{"type":38,"value":632},"FROM",{"type":33,"tag":122,"props":634,"children":635},{"style":135},[636],{"type":38,"value":637}," weekly_revenue r\n",{"type":33,"tag":122,"props":639,"children":641},{"class":124,"line":640},25,[642,647],{"type":33,"tag":122,"props":643,"children":644},{"style":129},[645],{"type":38,"value":646},"LEFT JOIN",{"type":33,"tag":122,"props":648,"children":649},{"style":135},[650],{"type":38,"value":651}," weekly_spend s_google\n",{"type":33,"tag":122,"props":653,"children":655},{"class":124,"line":654},26,[656,661,666,670,674,679,684,688,692,697,701,705,710,714],{"type":33,"tag":122,"props":657,"children":658},{"style":129},[659],{"type":38,"value":660},"  ON",{"type":33,"tag":122,"props":662,"children":663},{"style":192},[664],{"type":38,"value":665}," r",{"type":33,"tag":122,"props":667,"children":668},{"style":135},[669],{"type":38,"value":450},{"type":33,"tag":122,"props":671,"children":672},{"style":192},[673],{"type":38,"value":455},{"type":33,"tag":122,"props":675,"children":676},{"style":129},[677],{"type":38,"value":678}," =",{"type":33,"tag":122,"props":680,"children":681},{"style":192},[682],{"type":38,"value":683}," s_google",{"type":33,"tag":122,"props":685,"children":686},{"style":135},[687],{"type":38,"value":450},{"type":33,"tag":122,"props":689,"children":690},{"style":192},[691],{"type":38,"value":455},{"type":33,"tag":122,"props":693,"children":694},{"style":129},[695],{"type":38,"value":696}," AND",{"type":33,"tag":122,"props":698,"children":699},{"style":192},[700],{"type":38,"value":683},{"type":33,"tag":122,"props":702,"children":703},{"style":135},[704],{"type":38,"value":450},{"type":33,"tag":122,"props":706,"children":707},{"style":192},[708],{"type":38,"value":709},"channel",{"type":33,"tag":122,"props":711,"children":712},{"style":129},[713],{"type":38,"value":678},{"type":33,"tag":122,"props":715,"children":716},{"style":221},[717],{"type":38,"value":718}," 'google_search'\n",{"type":33,"tag":122,"props":720,"children":722},{"class":124,"line":721},27,[723,727],{"type":33,"tag":122,"props":724,"children":725},{"style":129},[726],{"type":38,"value":646},{"type":33,"tag":122,"props":728,"children":729},{"style":135},[730],{"type":38,"value":731}," weekly_spend s_meta\n",{"type":33,"tag":122,"props":733,"children":735},{"class":124,"line":734},28,[736,740,744,748,752,756,761,765,769,773,777,781,785,789],{"type":33,"tag":122,"props":737,"children":738},{"style":129},[739],{"type":38,"value":660},{"type":33,"tag":122,"props":741,"children":742},{"style":192},[743],{"type":38,"value":665},{"type":33,"tag":122,"props":745,"children":746},{"style":135},[747],{"type":38,"value":450},{"type":33,"tag":122,"props":749,"children":750},{"style":192},[751],{"type":38,"value":455},{"type":33,"tag":122,"props":753,"children":754},{"style":129},[755],{"type":38,"value":678},{"type":33,"tag":122,"props":757,"children":758},{"style":192},[759],{"type":38,"value":760}," s_meta",{"type":33,"tag":122,"props":762,"children":763},{"style":135},[764],{"type":38,"value":450},{"type":33,"tag":122,"props":766,"children":767},{"style":192},[768],{"type":38,"value":455},{"type":33,"tag":122,"props":770,"children":771},{"style":129},[772],{"type":38,"value":696},{"type":33,"tag":122,"props":774,"children":775},{"style":192},[776],{"type":38,"value":760},{"type":33,"tag":122,"props":778,"children":779},{"style":135},[780],{"type":38,"value":450},{"type":33,"tag":122,"props":782,"children":783},{"style":192},[784],{"type":38,"value":709},{"type":33,"tag":122,"props":786,"children":787},{"style":129},[788],{"type":38,"value":678},{"type":33,"tag":122,"props":790,"children":791},{"style":221},[792],{"type":38,"value":793}," 'meta'\n",{"type":33,"tag":122,"props":795,"children":797},{"class":124,"line":796},29,[798,802],{"type":33,"tag":122,"props":799,"children":800},{"style":129},[801],{"type":38,"value":646},{"type":33,"tag":122,"props":803,"children":804},{"style":135},[805],{"type":38,"value":806}," weekly_spend s_tv\n",{"type":33,"tag":122,"props":808,"children":810},{"class":124,"line":809},30,[811,815,819,823,827,831,836,840,844,848,852,856,860,864],{"type":33,"tag":122,"props":812,"children":813},{"style":129},[814],{"type":38,"value":660},{"type":33,"tag":122,"props":816,"children":817},{"style":192},[818],{"type":38,"value":665},{"type":33,"tag":122,"props":820,"children":821},{"style":135},[822],{"type":38,"value":450},{"type":33,"tag":122,"props":824,"children":825},{"style":192},[826],{"type":38,"value":455},{"type":33,"tag":122,"props":828,"children":829},{"style":129},[830],{"type":38,"value":678},{"type":33,"tag":122,"props":832,"children":833},{"style":192},[834],{"type":38,"value":835}," s_tv",{"type":33,"tag":122,"props":837,"children":838},{"style":135},[839],{"type":38,"value":450},{"type":33,"tag":122,"props":841,"children":842},{"style":192},[843],{"type":38,"value":455},{"type":33,"tag":122,"props":845,"children":846},{"style":129},[847],{"type":38,"value":696},{"type":33,"tag":122,"props":849,"children":850},{"style":192},[851],{"type":38,"value":835},{"type":33,"tag":122,"props":853,"children":854},{"style":135},[855],{"type":38,"value":450},{"type":33,"tag":122,"props":857,"children":858},{"style":192},[859],{"type":38,"value":709},{"type":33,"tag":122,"props":861,"children":862},{"style":129},[863],{"type":38,"value":678},{"type":33,"tag":122,"props":865,"children":866},{"style":221},[867],{"type":38,"value":868}," 'tv'\n",{"type":33,"tag":122,"props":870,"children":872},{"class":124,"line":871},31,[873,878,882],{"type":33,"tag":122,"props":874,"children":875},{"style":129},[876],{"type":38,"value":877},"ORDER BY",{"type":33,"tag":122,"props":879,"children":880},{"style":192},[881],{"type":38,"value":409},{"type":33,"tag":122,"props":883,"children":884},{"style":135},[885],{"type":38,"value":886},";\n",{"type":33,"tag":34,"props":888,"children":889},{},[890,892,898],{"type":38,"value":891},"Запрос создает таблицу с одной строкой за неделю, одним доходом и N колонками расходов по каналам. В production лучше читать данные напрямую из BigQuery в R через пакет ",{"type":33,"tag":64,"props":893,"children":895},{"className":894},[],[896],{"type":38,"value":897},"bigrquery",{"type":38,"value":899},":",{"type":33,"tag":112,"props":901,"children":905},{"className":902,"code":903,"language":904,"meta":17,"style":17},"language-r shiki shiki-themes github-dark","library(bigrquery)\nlibrary(Robyn)\n\nbq_auth()\ndf_input \u003C- bq_project_query(\n  \"project-id\",\n  \"SELECT week_start, revenue, google_search_spend, meta_paid_social_spend, tv_spend FROM `project.dataset.mmm_input`\"\n) %>% bq_table_download()\n","r",[906],{"type":33,"tag":64,"props":907,"children":908},{"__ignoreMap":17},[909,917,925,934,942,950,958,966],{"type":33,"tag":122,"props":910,"children":911},{"class":124,"line":125},[912],{"type":33,"tag":122,"props":913,"children":914},{},[915],{"type":38,"value":916},"library(bigrquery)\n",{"type":33,"tag":122,"props":918,"children":919},{"class":124,"line":151},[920],{"type":33,"tag":122,"props":921,"children":922},{},[923],{"type":38,"value":924},"library(Robyn)\n",{"type":33,"tag":122,"props":926,"children":927},{"class":124,"line":160},[928],{"type":33,"tag":122,"props":929,"children":931},{"emptyLinePlaceholder":930},true,[932],{"type":38,"value":933},"\n",{"type":33,"tag":122,"props":935,"children":936},{"class":124,"line":188},[937],{"type":33,"tag":122,"props":938,"children":939},{},[940],{"type":38,"value":941},"bq_auth()\n",{"type":33,"tag":122,"props":943,"children":944},{"class":124,"line":212},[945],{"type":33,"tag":122,"props":946,"children":947},{},[948],{"type":38,"value":949},"df_input \u003C- bq_project_query(\n",{"type":33,"tag":122,"props":951,"children":952},{"class":124,"line":227},[953],{"type":33,"tag":122,"props":954,"children":955},{},[956],{"type":38,"value":957},"  \"project-id\",\n",{"type":33,"tag":122,"props":959,"children":960},{"class":124,"line":251},[961],{"type":33,"tag":122,"props":962,"children":963},{},[964],{"type":38,"value":965},"  \"SELECT week_start, revenue, google_search_spend, meta_paid_social_spend, tv_spend FROM `project.dataset.mmm_input`\"\n",{"type":33,"tag":122,"props":967,"children":968},{"class":124,"line":27},[969],{"type":33,"tag":122,"props":970,"children":971},{},[972],{"type":38,"value":973},") %>% bq_table_download()\n",{"type":33,"tag":34,"props":975,"children":976},{},[977],{"type":38,"value":978},"Минимальный объем данных: 104 недели (2 года). Меньший объем создает риск переобучения. Байесовские приоры Robyn рассчитаны на 52+ недели, но 104+ недели лучше захватывают сезонность.",{"type":33,"tag":41,"props":980,"children":982},{"id":981},"настройка-модели-robyn_inputs-и-сетка-гиперпараметров",[983],{"type":38,"value":984},"Настройка модели: robyn_inputs и сетка гиперпараметров",{"type":33,"tag":34,"props":986,"children":987},{},[988,990,996],{"type":38,"value":989},"Robyn создает конфигурационный объект функцией ",{"type":33,"tag":64,"props":991,"children":993},{"className":992},[],[994],{"type":38,"value":995},"robyn_inputs()",{"type":38,"value":899},{"type":33,"tag":112,"props":998,"children":1000},{"className":902,"code":999,"language":904,"meta":17,"style":17},"InputCollect \u003C- robyn_inputs(\n  dt_input = df_input,\n  date_var = \"week_start\",\n  dep_var = \"revenue\",\n  dep_var_type = \"revenue\",\n  paid_media_spends = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n  paid_media_vars = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n  context_vars = c(\"competitor_index\", \"seasonality\"),\n  window_start = \"2024-01-01\",\n  window_end = \"2026-06-14\",\n  adstock = \"geometric\",\n  hyperparameters = list(\n    google_search_spend_alphas = c(0.5, 3),\n    google_search_spend_gammas = c(0.3, 1),\n    google_search_spend_thetas = c(0, 0.3),\n    meta_paid_social_spend_alphas = c(0.5, 3),\n    meta_paid_social_spend_gammas = c(0.3, 1),\n    meta_paid_social_spend_thetas = c(0, 0.5),\n    tv_spend_alphas = c(0.5, 3),\n    tv_spend_gammas = c(0.3, 1),\n    tv_spend_thetas = c(0.1, 0.7)\n  )\n)\n",[1001],{"type":33,"tag":64,"props":1002,"children":1003},{"__ignoreMap":17},[1004,1012,1020,1028,1036,1044,1052,1060,1068,1076,1084,1092,1100,1108,1116,1124,1132,1140,1148,1156,1164,1172,1180],{"type":33,"tag":122,"props":1005,"children":1006},{"class":124,"line":125},[1007],{"type":33,"tag":122,"props":1008,"children":1009},{},[1010],{"type":38,"value":1011},"InputCollect \u003C- robyn_inputs(\n",{"type":33,"tag":122,"props":1013,"children":1014},{"class":124,"line":151},[1015],{"type":33,"tag":122,"props":1016,"children":1017},{},[1018],{"type":38,"value":1019},"  dt_input = df_input,\n",{"type":33,"tag":122,"props":1021,"children":1022},{"class":124,"line":160},[1023],{"type":33,"tag":122,"props":1024,"children":1025},{},[1026],{"type":38,"value":1027},"  date_var = \"week_start\",\n",{"type":33,"tag":122,"props":1029,"children":1030},{"class":124,"line":188},[1031],{"type":33,"tag":122,"props":1032,"children":1033},{},[1034],{"type":38,"value":1035},"  dep_var = \"revenue\",\n",{"type":33,"tag":122,"props":1037,"children":1038},{"class":124,"line":212},[1039],{"type":33,"tag":122,"props":1040,"children":1041},{},[1042],{"type":38,"value":1043},"  dep_var_type = \"revenue\",\n",{"type":33,"tag":122,"props":1045,"children":1046},{"class":124,"line":227},[1047],{"type":33,"tag":122,"props":1048,"children":1049},{},[1050],{"type":38,"value":1051},"  paid_media_spends = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n",{"type":33,"tag":122,"props":1053,"children":1054},{"class":124,"line":251},[1055],{"type":33,"tag":122,"props":1056,"children":1057},{},[1058],{"type":38,"value":1059},"  paid_media_vars = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n",{"type":33,"tag":122,"props":1061,"children":1062},{"class":124,"line":27},[1063],{"type":33,"tag":122,"props":1064,"children":1065},{},[1066],{"type":38,"value":1067},"  context_vars = c(\"competitor_index\", \"seasonality\"),\n",{"type":33,"tag":122,"props":1069,"children":1070},{"class":124,"line":273},[1071],{"type":33,"tag":122,"props":1072,"children":1073},{},[1074],{"type":38,"value":1075},"  window_start = \"2024-01-01\",\n",{"type":33,"tag":122,"props":1077,"children":1078},{"class":124,"line":290},[1079],{"type":33,"tag":122,"props":1080,"children":1081},{},[1082],{"type":38,"value":1083},"  window_end = \"2026-06-14\",\n",{"type":33,"tag":122,"props":1085,"children":1086},{"class":124,"line":298},[1087],{"type":33,"tag":122,"props":1088,"children":1089},{},[1090],{"type":38,"value":1091},"  adstock = \"geometric\",\n",{"type":33,"tag":122,"props":1093,"children":1094},{"class":124,"line":333},[1095],{"type":33,"tag":122,"props":1096,"children":1097},{},[1098],{"type":38,"value":1099},"  hyperparameters = list(\n",{"type":33,"tag":122,"props":1101,"children":1102},{"class":124,"line":342},[1103],{"type":33,"tag":122,"props":1104,"children":1105},{},[1106],{"type":38,"value":1107},"    google_search_spend_alphas = c(0.5, 3),\n",{"type":33,"tag":122,"props":1109,"children":1110},{"class":124,"line":364},[1111],{"type":33,"tag":122,"props":1112,"children":1113},{},[1114],{"type":38,"value":1115},"    google_search_spend_gammas = c(0.3, 1),\n",{"type":33,"tag":122,"props":1117,"children":1118},{"class":124,"line":377},[1119],{"type":33,"tag":122,"props":1120,"children":1121},{},[1122],{"type":38,"value":1123},"    google_search_spend_thetas = c(0, 0.3),\n",{"type":33,"tag":122,"props":1125,"children":1126},{"class":124,"line":399},[1127],{"type":33,"tag":122,"props":1128,"children":1129},{},[1130],{"type":38,"value":1131},"    meta_paid_social_spend_alphas = c(0.5, 3),\n",{"type":33,"tag":122,"props":1133,"children":1134},{"class":124,"line":421},[1135],{"type":33,"tag":122,"props":1136,"children":1137},{},[1138],{"type":38,"value":1139},"    meta_paid_social_spend_gammas = c(0.3, 1),\n",{"type":33,"tag":122,"props":1141,"children":1142},{"class":124,"line":430},[1143],{"type":33,"tag":122,"props":1144,"children":1145},{},[1146],{"type":38,"value":1147},"    meta_paid_social_spend_thetas = c(0, 0.5),\n",{"type":33,"tag":122,"props":1149,"children":1150},{"class":124,"line":439},[1151],{"type":33,"tag":122,"props":1152,"children":1153},{},[1154],{"type":38,"value":1155},"    tv_spend_alphas = c(0.5, 3),\n",{"type":33,"tag":122,"props":1157,"children":1158},{"class":124,"line":463},[1159],{"type":33,"tag":122,"props":1160,"children":1161},{},[1162],{"type":38,"value":1163},"    tv_spend_gammas = c(0.3, 1),\n",{"type":33,"tag":122,"props":1165,"children":1166},{"class":124,"line":484},[1167],{"type":33,"tag":122,"props":1168,"children":1169},{},[1170],{"type":38,"value":1171},"    tv_spend_thetas = c(0.1, 0.7)\n",{"type":33,"tag":122,"props":1173,"children":1174},{"class":124,"line":534},[1175],{"type":33,"tag":122,"props":1176,"children":1177},{},[1178],{"type":38,"value":1179},"  )\n",{"type":33,"tag":122,"props":1181,"children":1182},{"class":124,"line":580},[1183],{"type":33,"tag":122,"props":1184,"children":1185},{},[1186],{"type":38,"value":427},{"type":33,"tag":34,"props":1188,"children":1189},{},[1190],{"type":33,"tag":56,"props":1191,"children":1192},{},[1193],{"type":38,"value":1194},"Расшифровка гиперпараметров:",{"type":33,"tag":1196,"props":1197,"children":1198},"ul",{},[1199,1210,1220],{"type":33,"tag":1200,"props":1201,"children":1202},"li",{},[1203,1208],{"type":33,"tag":56,"props":1204,"children":1205},{},[1206],{"type":38,"value":1207},"alpha",{"type":38,"value":1209},": параметр наклона (n) функции насыщения Hill. Высокий alpha = позднее насыщение.",{"type":33,"tag":1200,"props":1211,"children":1212},{},[1213,1218],{"type":33,"tag":56,"props":1214,"children":1215},{},[1216],{"type":38,"value":1217},"gamma",{"type":38,"value":1219},": параметр K Hill — точка полунасыщения. Низкий gamma = раннее насыщение.",{"type":33,"tag":1200,"props":1221,"children":1222},{},[1223,1228],{"type":33,"tag":56,"props":1224,"children":1225},{},[1226],{"type":38,"value":1227},"theta",{"type":38,"value":1229},": геометрический decay адстока. 0 = эффект исчезает мгновенно, 0.7 = 70% эффекта переносится на следующую неделю.",{"type":33,"tag":34,"props":1231,"children":1232},{},[1233],{"type":38,"value":1234},"Для каждого канала задаются диапазоны. Robyn выполняет grid search в этих пределах. Для ТВ верхний предел theta — 0.7 (долгоживущий эффект осведомленности), для поиска — 0.3 (быстрая конверсия).",{"type":33,"tag":41,"props":1236,"children":1238},{"id":1237},"запуск-модели-robyn_run-и-парето-оптимизация",[1239],{"type":38,"value":1240},"Запуск модели: robyn_run и парето-оптимизация",{"type":33,"tag":112,"props":1242,"children":1244},{"className":902,"code":1243,"language":904,"meta":17,"style":17},"OutputModels \u003C- robyn_run(\n  InputCollect = InputCollect,\n  cores = 8,\n  iterations = 2000,\n  trials = 5,\n  outputs = FALSE\n)\n",[1245],{"type":33,"tag":64,"props":1246,"children":1247},{"__ignoreMap":17},[1248,1256,1264,1272,1280,1288,1296],{"type":33,"tag":122,"props":1249,"children":1250},{"class":124,"line":125},[1251],{"type":33,"tag":122,"props":1252,"children":1253},{},[1254],{"type":38,"value":1255},"OutputModels \u003C- robyn_run(\n",{"type":33,"tag":122,"props":1257,"children":1258},{"class":124,"line":151},[1259],{"type":33,"tag":122,"props":1260,"children":1261},{},[1262],{"type":38,"value":1263},"  InputCollect = InputCollect,\n",{"type":33,"tag":122,"props":1265,"children":1266},{"class":124,"line":160},[1267],{"type":33,"tag":122,"props":1268,"children":1269},{},[1270],{"type":38,"value":1271},"  cores = 8,\n",{"type":33,"tag":122,"props":1273,"children":1274},{"class":124,"line":188},[1275],{"type":33,"tag":122,"props":1276,"children":1277},{},[1278],{"type":38,"value":1279},"  iterations = 2000,\n",{"type":33,"tag":122,"props":1281,"children":1282},{"class":124,"line":212},[1283],{"type":33,"tag":122,"props":1284,"children":1285},{},[1286],{"type":38,"value":1287},"  trials = 5,\n",{"type":33,"tag":122,"props":1289,"children":1290},{"class":124,"line":227},[1291],{"type":33,"tag":122,"props":1292,"children":1293},{},[1294],{"type":38,"value":1295},"  outputs = FALSE\n",{"type":33,"tag":122,"props":1297,"children":1298},{"class":124,"line":251},[1299],{"type":33,"tag":122,"props":1300,"children":1301},{},[1302],{"type":38,"value":427},{"type":33,"tag":34,"props":1304,"children":1305},{},[1306,1312],{"type":33,"tag":64,"props":1307,"children":1309},{"className":1308},[],[1310],{"type":38,"value":1311},"robyn_run()",{"type":38,"value":1313}," запускает генетический алгоритм на 2000 итераций, тестируя комбинации гиперпараметров. На каждой итерации минимизируются NRMSE (нормированная среднеквадратичная ошибка) и DECOMP.RSSD (остаточная сумма квадратов декомпозиции). Из парето-фронтья выбираются 5 моделей — оптимальный компромисс между качеством подгонки и бизнес-логикой (например, ROI ТВ не должен превышать ROI поиска).",{"type":33,"tag":34,"props":1315,"children":1316},{},[1317,1319,1325],{"type":38,"value":1318},"Объект-результат содержит таблицу ",{"type":33,"tag":64,"props":1320,"children":1322},{"className":1321},[],[1323],{"type":38,"value":1324},"df_allpareto",{"type":38,"value":1326}," со значениями ROI, ROAS и CPA по каналам для каждой модели. Количество строк = iterations × trials. Ключевые колонки:",{"type":33,"tag":1328,"props":1329,"children":1330},"table",{},[1331,1350],{"type":33,"tag":1332,"props":1333,"children":1334},"thead",{},[1335],{"type":33,"tag":1336,"props":1337,"children":1338},"tr",{},[1339,1345],{"type":33,"tag":1340,"props":1341,"children":1342},"th",{},[1343],{"type":38,"value":1344},"Колона",{"type":33,"tag":1340,"props":1346,"children":1347},{},[1348],{"type":38,"value":1349},"Описание",{"type":33,"tag":1351,"props":1352,"children":1353},"tbody",{},[1354,1372,1389,1406,1423,1440,1457,1474],{"type":33,"tag":1336,"props":1355,"children":1356},{},[1357,1367],{"type":33,"tag":1358,"props":1359,"children":1360},"td",{},[1361],{"type":33,"tag":64,"props":1362,"children":1364},{"className":1363},[],[1365],{"type":38,"value":1366},"solID",{"type":33,"tag":1358,"props":1368,"children":1369},{},[1370],{"type":38,"value":1371},"ID модели",{"type":33,"tag":1336,"props":1373,"children":1374},{},[1375,1384],{"type":33,"tag":1358,"props":1376,"children":1377},{},[1378],{"type":33,"tag":64,"props":1379,"children":1381},{"className":1380},[],[1382],{"type":38,"value":1383},"nrmse",{"type":33,"tag":1358,"props":1385,"children":1386},{},[1387],{"type":38,"value":1388},"Нормированная RMSE — ниже = лучше",{"type":33,"tag":1336,"props":1390,"children":1391},{},[1392,1401],{"type":33,"tag":1358,"props":1393,"children":1394},{},[1395],{"type":33,"tag":64,"props":1396,"children":1398},{"className":1397},[],[1399],{"type":38,"value":1400},"decomp.rssd",{"type":33,"tag":1358,"props":1402,"children":1403},{},[1404],{"type":38,"value":1405},"DECOMP.RSSD — ниже = стабильнее вклады",{"type":33,"tag":1336,"props":1407,"children":1408},{},[1409,1418],{"type":33,"tag":1358,"props":1410,"children":1411},{},[1412],{"type":33,"tag":64,"props":1413,"children":1415},{"className":1414},[],[1416],{"type":38,"value":1417},"mape",{"type":33,"tag":1358,"props":1419,"children":1420},{},[1421],{"type":38,"value":1422},"Средняя абсолютная процентная ошибка",{"type":33,"tag":1336,"props":1424,"children":1425},{},[1426,1435],{"type":33,"tag":1358,"props":1427,"children":1428},{},[1429],{"type":33,"tag":64,"props":1430,"children":1432},{"className":1431},[],[1433],{"type":38,"value":1434},"rsq_train",{"type":33,"tag":1358,"props":1436,"children":1437},{},[1438],{"type":38,"value":1439},"R² на тренировочной выборке",{"type":33,"tag":1336,"props":1441,"children":1442},{},[1443,1452],{"type":33,"tag":1358,"props":1444,"children":1445},{},[1446],{"type":33,"tag":64,"props":1447,"children":1449},{"className":1448},[],[1450],{"type":38,"value":1451},"google_search_spend_roi",{"type":33,"tag":1358,"props":1453,"children":1454},{},[1455],{"type":38,"value":1456},"ROI Google Search",{"type":33,"tag":1336,"props":1458,"children":1459},{},[1460,1469],{"type":33,"tag":1358,"props":1461,"children":1462},{},[1463],{"type":33,"tag":64,"props":1464,"children":1466},{"className":1465},[],[1467],{"type":38,"value":1468},"meta_paid_social_spend_roi",{"type":33,"tag":1358,"props":1470,"children":1471},{},[1472],{"type":38,"value":1473},"ROI Meta",{"type":33,"tag":1336,"props":1475,"children":1476},{},[1477,1486],{"type":33,"tag":1358,"props":1478,"children":1479},{},[1480],{"type":33,"tag":64,"props":1481,"children":1483},{"className":1482},[],[1484],{"type":38,"value":1485},"tv_spend_roi",{"type":33,"tag":1358,"props":1487,"children":1488},{},[1489],{"type":38,"value":1490},"ROI ТВ",{"type":33,"tag":34,"props":1492,"children":1493},{},[1494],{"type":38,"value":1495},"Лучшую модель выбираешь по NRMSE + DECOMP.RSSD + бизнес-логике. Хотя Robyn предоставляет Shiny-панель, в production лучше программный выбор:",{"type":33,"tag":112,"props":1497,"children":1499},{"className":902,"code":1498,"language":904,"meta":17,"style":17},"best_model_id \u003C- OutputModels$allPareto %>%\n  filter(nrmse \u003C 0.1, decomp.rssd \u003C 0.05) %>%\n  arrange(nrmse) %>%\n  slice(1) %>%\n  pull(solID)\n",[1500],{"type":33,"tag":64,"props":1501,"children":1502},{"__ignoreMap":17},[1503,1511,1519,1527,1535],{"type":33,"tag":122,"props":1504,"children":1505},{"class":124,"line":125},[1506],{"type":33,"tag":122,"props":1507,"children":1508},{},[1509],{"type":38,"value":1510},"best_model_id \u003C- OutputModels$allPareto %>%\n",{"type":33,"tag":122,"props":1512,"children":1513},{"class":124,"line":151},[1514],{"type":33,"tag":122,"props":1515,"children":1516},{},[1517],{"type":38,"value":1518},"  filter(nrmse \u003C 0.1, decomp.rssd \u003C 0.05) %>%\n",{"type":33,"tag":122,"props":1520,"children":1521},{"class":124,"line":160},[1522],{"type":33,"tag":122,"props":1523,"children":1524},{},[1525],{"type":38,"value":1526},"  arrange(nrmse) %>%\n",{"type":33,"tag":122,"props":1528,"children":1529},{"class":124,"line":188},[1530],{"type":33,"tag":122,"props":1531,"children":1532},{},[1533],{"type":38,"value":1534},"  slice(1) %>%\n",{"type":33,"tag":122,"props":1536,"children":1537},{"class":124,"line":212},[1538],{"type":33,"tag":122,"props":1539,"children":1540},{},[1541],{"type":38,"value":1542},"  pull(solID)\n",{"type":33,"tag":41,"props":1544,"children":1546},{"id":1545},"holdout-валидация-предотвращение-переобучения",[1547],{"type":38,"value":1548},"Holdout валидация: предотвращение переобучения",{"type":33,"tag":34,"props":1550,"children":1551},{},[1552],{"type":38,"value":1553},"Модель, подогнанная под тренировочные данные, может не обобщаться на новые. Holdout валидация в Robyn: последние 8–12 недель исключаются из тренировки и используются как тестовый набор. Модель обучается на остальных данных, затем делает прогнозы на тесте. Если MAPE (средняя абсолютная процентная ошибка) на тесте \u003C 15%, модель годна для production.",{"type":33,"tag":112,"props":1555,"children":1557},{"className":902,"code":1556,"language":904,"meta":17,"style":17},"InputCollect_train \u003C- robyn_inputs(\n  dt_input = df_input,\n  date_var = \"week_start\",\n  dep_var = \"revenue\",\n  window_start = \"2024-01-01\",\n  window_end = \"2026-04-12\",  # Последние 10 недель в holdout\n  # ... остальные параметры как выше\n)\n\nOutputModels_train \u003C- robyn_run(InputCollect_train, iterations = 2000)\n\n# Прогноз на holdout-наборе\ndf_test \u003C- df_input %>% filter(week_start > \"2026-04-12\")\npredictions \u003C- predict(OutputModels_train, newdata = df_test)\nmape_test \u003C- mean(abs((df_test$revenue - predictions) \u002F df_test$revenue)) * 100\n",[1558],{"type":33,"tag":64,"props":1559,"children":1560},{"__ignoreMap":17},[1561,1569,1576,1583,1590,1597,1605,1613,1620,1627,1635,1642,1650,1658,1666],{"type":33,"tag":122,"props":1562,"children":1563},{"class":124,"line":125},[1564],{"type":33,"tag":122,"props":1565,"children":1566},{},[1567],{"type":38,"value":1568},"InputCollect_train \u003C- robyn_inputs(\n",{"type":33,"tag":122,"props":1570,"children":1571},{"class":124,"line":151},[1572],{"type":33,"tag":122,"props":1573,"children":1574},{},[1575],{"type":38,"value":1019},{"type":33,"tag":122,"props":1577,"children":1578},{"class":124,"line":160},[1579],{"type":33,"tag":122,"props":1580,"children":1581},{},[1582],{"type":38,"value":1027},{"type":33,"tag":122,"props":1584,"children":1585},{"class":124,"line":188},[1586],{"type":33,"tag":122,"props":1587,"children":1588},{},[1589],{"type":38,"value":1035},{"type":33,"tag":122,"props":1591,"children":1592},{"class":124,"line":212},[1593],{"type":33,"tag":122,"props":1594,"children":1595},{},[1596],{"type":38,"value":1075},{"type":33,"tag":122,"props":1598,"children":1599},{"class":124,"line":227},[1600],{"type":33,"tag":122,"props":1601,"children":1602},{},[1603],{"type":38,"value":1604},"  window_end = \"2026-04-12\",  # Последние 10 недель в holdout\n",{"type":33,"tag":122,"props":1606,"children":1607},{"class":124,"line":251},[1608],{"type":33,"tag":122,"props":1609,"children":1610},{},[1611],{"type":38,"value":1612},"  # ... остальные параметры как выше\n",{"type":33,"tag":122,"props":1614,"children":1615},{"class":124,"line":27},[1616],{"type":33,"tag":122,"props":1617,"children":1618},{},[1619],{"type":38,"value":427},{"type":33,"tag":122,"props":1621,"children":1622},{"class":124,"line":273},[1623],{"type":33,"tag":122,"props":1624,"children":1625},{"emptyLinePlaceholder":930},[1626],{"type":38,"value":933},{"type":33,"tag":122,"props":1628,"children":1629},{"class":124,"line":290},[1630],{"type":33,"tag":122,"props":1631,"children":1632},{},[1633],{"type":38,"value":1634},"OutputModels_train \u003C- robyn_run(InputCollect_train, iterations = 2000)\n",{"type":33,"tag":122,"props":1636,"children":1637},{"class":124,"line":298},[1638],{"type":33,"tag":122,"props":1639,"children":1640},{"emptyLinePlaceholder":930},[1641],{"type":38,"value":933},{"type":33,"tag":122,"props":1643,"children":1644},{"class":124,"line":333},[1645],{"type":33,"tag":122,"props":1646,"children":1647},{},[1648],{"type":38,"value":1649},"# Прогноз на holdout-наборе\n",{"type":33,"tag":122,"props":1651,"children":1652},{"class":124,"line":342},[1653],{"type":33,"tag":122,"props":1654,"children":1655},{},[1656],{"type":38,"value":1657},"df_test \u003C- df_input %>% filter(week_start > \"2026-04-12\")\n",{"type":33,"tag":122,"props":1659,"children":1660},{"class":124,"line":364},[1661],{"type":33,"tag":122,"props":1662,"children":1663},{},[1664],{"type":38,"value":1665},"predictions \u003C- predict(OutputModels_train, newdata = df_test)\n",{"type":33,"tag":122,"props":1667,"children":1668},{"class":124,"line":377},[1669],{"type":33,"tag":122,"props":1670,"children":1671},{},[1672],{"type":38,"value":1673},"mape_test \u003C- mean(abs((df_test$revenue - predictions) \u002F df_test$revenue)) * 100\n",{"type":33,"tag":34,"props":1675,"children":1676},{},[1677],{"type":38,"value":1678},"Если MAPE > 20%, модель переобучена. Нужно сузить диапазоны гиперпараметров или добавить переменные контекста (например, макроэкономические индексы). Байесова регуляризация Robyn (ridge penalty) снижает переобучение, но holdout валидация — финальная гарантия.",{"type":33,"tag":41,"props":1680,"children":1682},{"id":1681},"визуализация-кривых-адстока-и-насыщения",[1683],{"type":38,"value":1684},"Визуализация кривых адстока и насыщения",{"type":33,"tag":34,"props":1686,"children":1687},{},[1688,1690,1696],{"type":38,"value":1689},"Robyn выводит кривые адстока и насыщения через ",{"type":33,"tag":64,"props":1691,"children":1693},{"className":1692},[],[1694],{"type":38,"value":1695},"robyn_outputs()",{"type":38,"value":1697},". В production экспортируешь графики в PNG и встраиваешь в BI-панель:",{"type":33,"tag":112,"props":1699,"children":1701},{"className":902,"code":1700,"language":904,"meta":17,"style":17},"robyn_outputs(\n  InputCollect = InputCollect,\n  OutputModels = OutputModels,\n  select_model = best_model_id,\n  export = TRUE,\n  export_location = \"\u002Fdata\u002Fmmm_output\u002F\"\n)\n",[1702],{"type":33,"tag":64,"props":1703,"children":1704},{"__ignoreMap":17},[1705,1713,1720,1728,1736,1744,1752],{"type":33,"tag":122,"props":1706,"children":1707},{"class":124,"line":125},[1708],{"type":33,"tag":122,"props":1709,"children":1710},{},[1711],{"type":38,"value":1712},"robyn_outputs(\n",{"type":33,"tag":122,"props":1714,"children":1715},{"class":124,"line":151},[1716],{"type":33,"tag":122,"props":1717,"children":1718},{},[1719],{"type":38,"value":1263},{"type":33,"tag":122,"props":1721,"children":1722},{"class":124,"line":160},[1723],{"type":33,"tag":122,"props":1724,"children":1725},{},[1726],{"type":38,"value":1727},"  OutputModels = OutputModels,\n",{"type":33,"tag":122,"props":1729,"children":1730},{"class":124,"line":188},[1731],{"type":33,"tag":122,"props":1732,"children":1733},{},[1734],{"type":38,"value":1735},"  select_model = best_model_id,\n",{"type":33,"tag":122,"props":1737,"children":1738},{"class":124,"line":212},[1739],{"type":33,"tag":122,"props":1740,"children":1741},{},[1742],{"type":38,"value":1743},"  export = TRUE,\n",{"type":33,"tag":122,"props":1745,"children":1746},{"class":124,"line":227},[1747],{"type":33,"tag":122,"props":1748,"children":1749},{},[1750],{"type":38,"value":1751},"  export_location = \"\u002Fdata\u002Fmmm_output\u002F\"\n",{"type":33,"tag":122,"props":1753,"children":1754},{"class":124,"line":251},[1755],{"type":33,"tag":122,"props":1756,"children":1757},{},[1758],{"type":38,"value":427},{"type":33,"tag":34,"props":1760,"children":1761},{},[1762],{"type":38,"value":1763},"Экспортируемые файлы:",{"type":33,"tag":1196,"props":1765,"children":1766},{},[1767,1778,1789],{"type":33,"tag":1200,"props":1768,"children":1769},{},[1770,1776],{"type":33,"tag":64,"props":1771,"children":1773},{"className":1772},[],[1774],{"type":38,"value":1775},"saturate_curves.png",{"type":38,"value":1777}," — для каждого канала зависимость расходов от response. Ось X — расходы, Y — прогнозируемый доход. Кривая выравнивается в точке насыщения.",{"type":33,"tag":1200,"props":1779,"children":1780},{},[1781,1787],{"type":33,"tag":64,"props":1782,"children":1784},{"className":1783},[],[1785],{"type":38,"value":1786},"adstock_curves.png",{"type":38,"value":1788}," — профиль затухания. X — недели, Y — мультипликатор адстока. Для ТВ видно затухание в течение 6–8 недель.",{"type":33,"tag":1200,"props":1790,"children":1791},{},[1792,1798],{"type":33,"tag":64,"props":1793,"children":1795},{"className":1794},[],[1796],{"type":38,"value":1797},"waterfall.png",{"type":38,"value":1799}," — декомпозиция дохода: база + сезонность + вклад каждого канала.",{"type":33,"tag":34,"props":1801,"children":1802},{},[1803],{"type":38,"value":1804},"На основе этих графиков вместо \"увеличь расходы ТВ на 30%\" говоришь \"ТВ в точке насыщения; перенос 20% в поиск поднимет общий ROI на 12%\".",{"type":33,"tag":41,"props":1806,"children":1808},{"id":1807},"production-pipeline-dbt-robyn-looker-studio",[1809],{"type":38,"value":1810},"Production pipeline: dbt + Robyn + Looker Studio",{"type":33,"tag":34,"props":1812,"children":1813},{},[1814,1816,1825],{"type":38,"value":1815},"MMM — не одноразовый анализ, а еженедельный refresh. Согласно ",{"type":33,"tag":1817,"props":1818,"children":1822},"a",{"href":1819,"rel":1820},"https:\u002F\u002Fwww.roibase.com.tr\u002Fru\u002Ffirstparty",[1821],"nofollow",[1823],{"type":38,"value":1824},"подходу Roibase к First-Party Data & Measurement",{"type":38,"value":1826},", pipeline выглядит так:",{"type":33,"tag":1828,"props":1829,"children":1830},"ol",{},[1831,1849,1915],{"type":33,"tag":1200,"props":1832,"children":1833},{},[1834,1839,1841,1847],{"type":33,"tag":56,"props":1835,"children":1836},{},[1837],{"type":38,"value":1838},"dbt",{"type":38,"value":1840},": из raw event'ов в BigQuery строится таблица ",{"type":33,"tag":64,"props":1842,"children":1844},{"className":1843},[],[1845],{"type":38,"value":1846},"mmm_input",{"type":38,"value":1848}," (SQL выше). Запуск каждый понедельник в 00:00 через dbt Cloud.",{"type":33,"tag":1200,"props":1850,"children":1851},{},[1852,1857,1859,1864,1866,1871,1873,1878,1880,1886,1888,1893,1894,1899,1900,1906,1907,1913],{"type":33,"tag":56,"props":1853,"children":1854},{},[1855],{"type":38,"value":1856},"Robyn R-скрипт",{"type":38,"value":1858},": работает в контейнере Cloud Run. Скрипт читает ",{"type":33,"tag":64,"props":1860,"children":1862},{"className":1861},[],[1863],{"type":38,"value":1846},{"type":38,"value":1865}," через ",{"type":33,"tag":64,"props":1867,"children":1869},{"className":1868},[],[1870],{"type":38,"value":897},{"type":38,"value":1872},", вызывает ",{"type":33,"tag":64,"props":1874,"children":1876},{"className":1875},[],[1877],{"type":38,"value":1311},{"type":38,"value":1879},", пишет результаты в BigQuery (",{"type":33,"tag":64,"props":1881,"children":1883},{"className":1882},[],[1884],{"type":38,"value":1885},"mmm_output",{"type":38,"value":1887},": ",{"type":33,"tag":64,"props":1889,"children":1891},{"className":1890},[],[1892],{"type":38,"value":455},{"type":38,"value":314},{"type":33,"tag":64,"props":1895,"children":1897},{"className":1896},[],[1898],{"type":38,"value":709},{"type":38,"value":314},{"type":33,"tag":64,"props":1901,"children":1903},{"className":1902},[],[1904],{"type":38,"value":1905},"roi",{"type":38,"value":314},{"type":33,"tag":64,"props":1908,"children":1910},{"className":1909},[],[1911],{"type":38,"value":1912},"predicted_revenue",{"type":38,"value":1914},").",{"type":33,"tag":1200,"props":1916,"children":1917},{},[1918,1923,1925,1930],{"type":33,"tag":56,"props":1919,"children":1920},{},[1921],{"type":38,"value":1922},"Looker Studio",{"type":38,"value":1924},": питается из ",{"type":33,"tag":64,"props":1926,"children":1928},{"className":1927},[],[1929],{"type":38,"value":1885},{"type":38,"value":1931},", визуализирует тренд ROI по каналам, кривые насыщения и рекомендации по бюджету.",{"type":33,"tag":34,"props":1933,"children":1934},{},[1935],{"type":38,"value":1936},"Контейнер описывается Dockerfile:",{"type":33,"tag":112,"props":1938,"children":1942},{"className":1939,"code":1940,"language":1941,"meta":17,"style":17},"language-dockerfile shiki shiki-themes github-dark","FROM rocker\u002Ftidyverse:4.2.0\nRUN R -e \"install.packages('Robyn', repos='https:\u002F\u002Fcloud.r-project.org')\"\nRUN R -e \"install.packages('bigrquery')\"\nCOPY run_mmm.R \u002Fapp\u002Frun_mmm\n","dockerfile",[1943],{"type":33,"tag":64,"props":1944,"children":1945},{"__ignoreMap":17},[1946,1954,1962,1970],{"type":33,"tag":122,"props":1947,"children":1948},{"class":124,"line":125},[1949],{"type":33,"tag":122,"props":1950,"children":1951},{},[1952],{"type":38,"value":1953},"FROM rocker\u002Ftidyverse:4.2.0\n",{"type":33,"tag":122,"props":1955,"children":1956},{"class":124,"line":151},[1957],{"type":33,"tag":122,"props":1958,"children":1959},{},[1960],{"type":38,"value":1961},"RUN R -e \"install.packages('Robyn', repos='https:\u002F\u002Fcloud.r-project.org')\"\n",{"type":33,"tag":122,"props":1963,"children":1964},{"class":124,"line":160},[1965],{"type":33,"tag":122,"props":1966,"children":1967},{},[1968],{"type":38,"value":1969},"RUN R -e \"install.packages('bigrquery')\"\n",{"type":33,"tag":122,"props":1971,"children":1972},{"class":124,"line":188},[1973],{"type":33,"tag":122,"props":1974,"children":1975},{},[1976],{"type":38,"value":1977},"COPY run_mmm.R \u002Fapp\u002Frun_mmm\n",{"type":33,"tag":1979,"props":1980,"children":1981},"style",{},[1982],{"type":38,"value":1983},"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":160,"depth":160,"links":1985},[1986,1987,1988,1989,1990,1991,1992],{"id":43,"depth":151,"text":46},{"id":102,"depth":151,"text":105},{"id":981,"depth":151,"text":984},{"id":1237,"depth":151,"text":1240},{"id":1545,"depth":151,"text":1548},{"id":1681,"depth":151,"text":1684},{"id":1807,"depth":151,"text":1810},"markdown","content:ru:data:marketing-mix-modeling-robyn-prakticheskaya-realizacija.md","content","ru\u002Fdata\u002Fmarketing-mix-modeling-robyn-prakticheskaya-realizacija.md","ru\u002Fdata\u002Fmarketing-mix-modeling-robyn-prakticheskaya-realizacija","md",1782079494632]