[{"data":1,"prerenderedAt":2280},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fen\u002Fdata\u002Fmarketing-mix-modeling-practical-setup-robyn":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":2274,"_id":2275,"_source":2276,"_file":2277,"_stem":2278,"_extension":2279},"\u002Fen\u002Fdata\u002Fmarketing-mix-modeling-practical-setup-robyn","data",false,"","Marketing Mix Modeling: Practical Setup with Robyn","Build attribution models with Meta's Robyn framework using saturation curves, adstock decay, and holdout validation. SQL, R, and production pipeline.","2026-06-21",[22,23,24,25,26],"marketing-mix-modeling","robyn","adstock","attribution","mmm",8,"Roibase",{"type":30,"children":31,"toc":2263},"root",[32,40,47,52,72,90,100,106,111,887,900,974,979,985,998,1188,1196,1231,1236,1242,1304,1315,1328,1492,1497,1544,1550,1555,1675,1680,1686,1699,1760,1765,1801,1806,1812,1828,1932,1937,1986,1991,1997,2010,2094,2099,2217,2222,2228,2233,2238,2252,2257],{"type":33,"tag":34,"props":35,"children":36},"element","p",{},[37],{"type":38,"value":39},"text","Cookie deprecation and privacy regulation are shifting attribution from deterministic methods to probabilistic modeling. Marketing Mix Modeling (MMM)—a statistical tool from the 1960s—is back at center stage. Meta's open-source Robyn framework provides the practical implementation: Bayesian inference, saturation curves, and adstock decay bind weekly marketing spend to sales through regression modeling, which you move to production. This article walks through setting up Robyn, fitting models to real data, running hyperparameter grid search, and preventing overfitting with holdout validation.",{"type":33,"tag":41,"props":42,"children":44},"h2",{"id":43},"what-is-robyn-and-how-it-differs-from-classical-regression",[45],{"type":38,"value":46},"What is Robyn and how it differs from classical regression",{"type":33,"tag":34,"props":48,"children":49},{},[50],{"type":38,"value":51},"Robyn is an open-source MMM framework written in R. Meta developed it for its own marketing team in 2020 and released it in 2021. Its differences from classical linear regression are:",{"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},"Adstock transformation",{"type":38,"value":62},": Marketing effect is not instantaneous—a TV ad carries mind share for weeks. Adstock models the contribution of past spending to current sales using exponential decay. Robyn supports geometric and Weibull adstock functions. Geometric is simple: ",{"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},", where θ is the decay parameter. Weibull is more flexible—you can position peak effect with a lag.",{"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},"Saturation (diminishing returns)",{"type":38,"value":81},": The spend-to-sales relationship is not linear. The first $100K may deliver 80% ROI, while the second $100K delivers 40%. Robyn applies Hill and S-curve saturation functions. The Hill equation is ",{"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},", where K is the half-maximum point and n is the slope. This non-linearity is critical for channel-level budget optimization.",{"type":33,"tag":34,"props":91,"children":92},{},[93,98],{"type":33,"tag":56,"props":94,"children":95},{},[96],{"type":38,"value":97},"Hyperparameter tuning",{"type":38,"value":99},": Adstock decay, saturation K, and n values are unknown—found through grid search. Robyn uses a genetic algorithm (NSGAII) to test thousands of model combinations and selects the best trade-off from the Pareto frontier.",{"type":33,"tag":41,"props":101,"children":103},{"id":102},"data-preparation-from-sql-to-weekly-granularity",[104],{"type":38,"value":105},"Data preparation: from SQL to weekly granularity",{"type":33,"tag":34,"props":107,"children":108},{},[109],{"type":38,"value":110},"Robyn works at weekly granularity. You aggregate daily transaction logs into weekly media spend and revenue. Example BigQuery query:",{"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},"This query produces one row per week, one revenue column, and N channel spend columns. Robyn can ingest it as CSV, but pulling directly from BigQuery to R in production is cleaner. With the ",{"type":33,"tag":64,"props":893,"children":895},{"className":894},[],[896],{"type":38,"value":897},"bigrquery",{"type":38,"value":899}," package:",{"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},"Minimum data requirement: 104 weeks (2 years). Less data carries overfitting risk. Robyn's Bayesian priors work with 52 weeks, but 104+ weeks better capture seasonality.",{"type":33,"tag":41,"props":980,"children":982},{"id":981},"model-setup-robyn_inputs-and-hyperparameter-grid",[983],{"type":38,"value":984},"Model setup: robyn_inputs and hyperparameter grid",{"type":33,"tag":34,"props":986,"children":987},{},[988,990,996],{"type":38,"value":989},"Robyn creates a config object using the ",{"type":33,"tag":64,"props":991,"children":993},{"className":992},[],[994],{"type":38,"value":995},"robyn_inputs()",{"type":38,"value":997}," function:",{"type":33,"tag":112,"props":999,"children":1001},{"className":902,"code":1000,"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",[1002],{"type":33,"tag":64,"props":1003,"children":1004},{"__ignoreMap":17},[1005,1013,1021,1029,1037,1045,1053,1061,1069,1077,1085,1093,1101,1109,1117,1125,1133,1141,1149,1157,1165,1173,1181],{"type":33,"tag":122,"props":1006,"children":1007},{"class":124,"line":125},[1008],{"type":33,"tag":122,"props":1009,"children":1010},{},[1011],{"type":38,"value":1012},"InputCollect \u003C- robyn_inputs(\n",{"type":33,"tag":122,"props":1014,"children":1015},{"class":124,"line":151},[1016],{"type":33,"tag":122,"props":1017,"children":1018},{},[1019],{"type":38,"value":1020},"  dt_input = df_input,\n",{"type":33,"tag":122,"props":1022,"children":1023},{"class":124,"line":160},[1024],{"type":33,"tag":122,"props":1025,"children":1026},{},[1027],{"type":38,"value":1028},"  date_var = \"week_start\",\n",{"type":33,"tag":122,"props":1030,"children":1031},{"class":124,"line":188},[1032],{"type":33,"tag":122,"props":1033,"children":1034},{},[1035],{"type":38,"value":1036},"  dep_var = \"revenue\",\n",{"type":33,"tag":122,"props":1038,"children":1039},{"class":124,"line":212},[1040],{"type":33,"tag":122,"props":1041,"children":1042},{},[1043],{"type":38,"value":1044},"  dep_var_type = \"revenue\",\n",{"type":33,"tag":122,"props":1046,"children":1047},{"class":124,"line":227},[1048],{"type":33,"tag":122,"props":1049,"children":1050},{},[1051],{"type":38,"value":1052},"  paid_media_spends = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n",{"type":33,"tag":122,"props":1054,"children":1055},{"class":124,"line":251},[1056],{"type":33,"tag":122,"props":1057,"children":1058},{},[1059],{"type":38,"value":1060},"  paid_media_vars = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n",{"type":33,"tag":122,"props":1062,"children":1063},{"class":124,"line":27},[1064],{"type":33,"tag":122,"props":1065,"children":1066},{},[1067],{"type":38,"value":1068},"  context_vars = c(\"competitor_index\", \"seasonality\"),\n",{"type":33,"tag":122,"props":1070,"children":1071},{"class":124,"line":273},[1072],{"type":33,"tag":122,"props":1073,"children":1074},{},[1075],{"type":38,"value":1076},"  window_start = \"2024-01-01\",\n",{"type":33,"tag":122,"props":1078,"children":1079},{"class":124,"line":290},[1080],{"type":33,"tag":122,"props":1081,"children":1082},{},[1083],{"type":38,"value":1084},"  window_end = \"2026-06-14\",\n",{"type":33,"tag":122,"props":1086,"children":1087},{"class":124,"line":298},[1088],{"type":33,"tag":122,"props":1089,"children":1090},{},[1091],{"type":38,"value":1092},"  adstock = \"geometric\",\n",{"type":33,"tag":122,"props":1094,"children":1095},{"class":124,"line":333},[1096],{"type":33,"tag":122,"props":1097,"children":1098},{},[1099],{"type":38,"value":1100},"  hyperparameters = list(\n",{"type":33,"tag":122,"props":1102,"children":1103},{"class":124,"line":342},[1104],{"type":33,"tag":122,"props":1105,"children":1106},{},[1107],{"type":38,"value":1108},"    google_search_spend_alphas = c(0.5, 3),\n",{"type":33,"tag":122,"props":1110,"children":1111},{"class":124,"line":364},[1112],{"type":33,"tag":122,"props":1113,"children":1114},{},[1115],{"type":38,"value":1116},"    google_search_spend_gammas = c(0.3, 1),\n",{"type":33,"tag":122,"props":1118,"children":1119},{"class":124,"line":377},[1120],{"type":33,"tag":122,"props":1121,"children":1122},{},[1123],{"type":38,"value":1124},"    google_search_spend_thetas = c(0, 0.3),\n",{"type":33,"tag":122,"props":1126,"children":1127},{"class":124,"line":399},[1128],{"type":33,"tag":122,"props":1129,"children":1130},{},[1131],{"type":38,"value":1132},"    meta_paid_social_spend_alphas = c(0.5, 3),\n",{"type":33,"tag":122,"props":1134,"children":1135},{"class":124,"line":421},[1136],{"type":33,"tag":122,"props":1137,"children":1138},{},[1139],{"type":38,"value":1140},"    meta_paid_social_spend_gammas = c(0.3, 1),\n",{"type":33,"tag":122,"props":1142,"children":1143},{"class":124,"line":430},[1144],{"type":33,"tag":122,"props":1145,"children":1146},{},[1147],{"type":38,"value":1148},"    meta_paid_social_spend_thetas = c(0, 0.5),\n",{"type":33,"tag":122,"props":1150,"children":1151},{"class":124,"line":439},[1152],{"type":33,"tag":122,"props":1153,"children":1154},{},[1155],{"type":38,"value":1156},"    tv_spend_alphas = c(0.5, 3),\n",{"type":33,"tag":122,"props":1158,"children":1159},{"class":124,"line":463},[1160],{"type":33,"tag":122,"props":1161,"children":1162},{},[1163],{"type":38,"value":1164},"    tv_spend_gammas = c(0.3, 1),\n",{"type":33,"tag":122,"props":1166,"children":1167},{"class":124,"line":484},[1168],{"type":33,"tag":122,"props":1169,"children":1170},{},[1171],{"type":38,"value":1172},"    tv_spend_thetas = c(0.1, 0.7)\n",{"type":33,"tag":122,"props":1174,"children":1175},{"class":124,"line":534},[1176],{"type":33,"tag":122,"props":1177,"children":1178},{},[1179],{"type":38,"value":1180},"  )\n",{"type":33,"tag":122,"props":1182,"children":1183},{"class":124,"line":580},[1184],{"type":33,"tag":122,"props":1185,"children":1186},{},[1187],{"type":38,"value":427},{"type":33,"tag":34,"props":1189,"children":1190},{},[1191],{"type":33,"tag":56,"props":1192,"children":1193},{},[1194],{"type":38,"value":1195},"Hyperparameter explanations:",{"type":33,"tag":1197,"props":1198,"children":1199},"ul",{},[1200,1211,1221],{"type":33,"tag":1201,"props":1202,"children":1203},"li",{},[1204,1209],{"type":33,"tag":56,"props":1205,"children":1206},{},[1207],{"type":38,"value":1208},"alpha",{"type":38,"value":1210},": The slope parameter (n) of the Hill saturation function. Higher alpha = delayed saturation.",{"type":33,"tag":1201,"props":1212,"children":1213},{},[1214,1219],{"type":33,"tag":56,"props":1215,"children":1216},{},[1217],{"type":38,"value":1218},"gamma",{"type":38,"value":1220},": The Hill K parameter—the half-maximum point. Lower gamma = earlier saturation.",{"type":33,"tag":1201,"props":1222,"children":1223},{},[1224,1229],{"type":33,"tag":56,"props":1225,"children":1226},{},[1227],{"type":38,"value":1228},"theta",{"type":38,"value":1230},": Geometric adstock decay. 0 = effect ends immediately, 0.7 = 70% carries to next week.",{"type":33,"tag":34,"props":1232,"children":1233},{},[1234],{"type":38,"value":1235},"You provide min-max ranges for each channel. Robyn runs grid search within those ranges. For TV, the theta upper bound is 0.7—mind share persists. For paid search, 0.3—conversions are short-term.",{"type":33,"tag":41,"props":1237,"children":1239},{"id":1238},"model-execution-robyn_run-and-pareto-optimization",[1240],{"type":38,"value":1241},"Model execution: robyn_run and Pareto optimization",{"type":33,"tag":112,"props":1243,"children":1245},{"className":902,"code":1244,"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",[1246],{"type":33,"tag":64,"props":1247,"children":1248},{"__ignoreMap":17},[1249,1257,1265,1273,1281,1289,1297],{"type":33,"tag":122,"props":1250,"children":1251},{"class":124,"line":125},[1252],{"type":33,"tag":122,"props":1253,"children":1254},{},[1255],{"type":38,"value":1256},"OutputModels \u003C- robyn_run(\n",{"type":33,"tag":122,"props":1258,"children":1259},{"class":124,"line":151},[1260],{"type":33,"tag":122,"props":1261,"children":1262},{},[1263],{"type":38,"value":1264},"  InputCollect = InputCollect,\n",{"type":33,"tag":122,"props":1266,"children":1267},{"class":124,"line":160},[1268],{"type":33,"tag":122,"props":1269,"children":1270},{},[1271],{"type":38,"value":1272},"  cores = 8,\n",{"type":33,"tag":122,"props":1274,"children":1275},{"class":124,"line":188},[1276],{"type":33,"tag":122,"props":1277,"children":1278},{},[1279],{"type":38,"value":1280},"  iterations = 2000,\n",{"type":33,"tag":122,"props":1282,"children":1283},{"class":124,"line":212},[1284],{"type":33,"tag":122,"props":1285,"children":1286},{},[1287],{"type":38,"value":1288},"  trials = 5,\n",{"type":33,"tag":122,"props":1290,"children":1291},{"class":124,"line":227},[1292],{"type":33,"tag":122,"props":1293,"children":1294},{},[1295],{"type":38,"value":1296},"  outputs = FALSE\n",{"type":33,"tag":122,"props":1298,"children":1299},{"class":124,"line":251},[1300],{"type":33,"tag":122,"props":1301,"children":1302},{},[1303],{"type":38,"value":427},{"type":33,"tag":34,"props":1305,"children":1306},{},[1307,1313],{"type":33,"tag":64,"props":1308,"children":1310},{"className":1309},[],[1311],{"type":38,"value":1312},"robyn_run()",{"type":38,"value":1314}," uses a genetic algorithm to test hyperparameter combinations across 2000 iterations. Each iteration minimizes NRMSE (normalized root mean squared error) and DECOMP.RSSD (decomposition residual sum of squares difference). Five models are selected from the Pareto frontier—trading off fit quality against business logic (for example, TV's ROI should not exceed search's).",{"type":33,"tag":34,"props":1316,"children":1317},{},[1318,1320,1326],{"type":38,"value":1319},"The output object contains a ",{"type":33,"tag":64,"props":1321,"children":1323},{"className":1322},[],[1324],{"type":38,"value":1325},"df_allpareto",{"type":38,"value":1327}," table—each model's channel-level ROI, ROAS, and CPA values. Row count = iterations × trials. It includes these columns:",{"type":33,"tag":1329,"props":1330,"children":1331},"table",{},[1332,1351],{"type":33,"tag":1333,"props":1334,"children":1335},"thead",{},[1336],{"type":33,"tag":1337,"props":1338,"children":1339},"tr",{},[1340,1346],{"type":33,"tag":1341,"props":1342,"children":1343},"th",{},[1344],{"type":38,"value":1345},"Column",{"type":33,"tag":1341,"props":1347,"children":1348},{},[1349],{"type":38,"value":1350},"Description",{"type":33,"tag":1352,"props":1353,"children":1354},"tbody",{},[1355,1373,1390,1407,1424,1441,1458,1475],{"type":33,"tag":1337,"props":1356,"children":1357},{},[1358,1368],{"type":33,"tag":1359,"props":1360,"children":1361},"td",{},[1362],{"type":33,"tag":64,"props":1363,"children":1365},{"className":1364},[],[1366],{"type":38,"value":1367},"solID",{"type":33,"tag":1359,"props":1369,"children":1370},{},[1371],{"type":38,"value":1372},"Model ID",{"type":33,"tag":1337,"props":1374,"children":1375},{},[1376,1385],{"type":33,"tag":1359,"props":1377,"children":1378},{},[1379],{"type":33,"tag":64,"props":1380,"children":1382},{"className":1381},[],[1383],{"type":38,"value":1384},"nrmse",{"type":33,"tag":1359,"props":1386,"children":1387},{},[1388],{"type":38,"value":1389},"Normalized RMSE—lower is better fit",{"type":33,"tag":1337,"props":1391,"children":1392},{},[1393,1402],{"type":33,"tag":1359,"props":1394,"children":1395},{},[1396],{"type":33,"tag":64,"props":1397,"children":1399},{"className":1398},[],[1400],{"type":38,"value":1401},"decomp.rssd",{"type":33,"tag":1359,"props":1403,"children":1404},{},[1405],{"type":38,"value":1406},"Decomposition RSSD—lower is more stable channel contributions",{"type":33,"tag":1337,"props":1408,"children":1409},{},[1410,1419],{"type":33,"tag":1359,"props":1411,"children":1412},{},[1413],{"type":33,"tag":64,"props":1414,"children":1416},{"className":1415},[],[1417],{"type":38,"value":1418},"mape",{"type":33,"tag":1359,"props":1420,"children":1421},{},[1422],{"type":38,"value":1423},"Mean absolute percentage error",{"type":33,"tag":1337,"props":1425,"children":1426},{},[1427,1436],{"type":33,"tag":1359,"props":1428,"children":1429},{},[1430],{"type":33,"tag":64,"props":1431,"children":1433},{"className":1432},[],[1434],{"type":38,"value":1435},"rsq_train",{"type":33,"tag":1359,"props":1437,"children":1438},{},[1439],{"type":38,"value":1440},"Training R²",{"type":33,"tag":1337,"props":1442,"children":1443},{},[1444,1453],{"type":33,"tag":1359,"props":1445,"children":1446},{},[1447],{"type":33,"tag":64,"props":1448,"children":1450},{"className":1449},[],[1451],{"type":38,"value":1452},"google_search_spend_roi",{"type":33,"tag":1359,"props":1454,"children":1455},{},[1456],{"type":38,"value":1457},"Google Search ROI (revenue\u002Fspend)",{"type":33,"tag":1337,"props":1459,"children":1460},{},[1461,1470],{"type":33,"tag":1359,"props":1462,"children":1463},{},[1464],{"type":33,"tag":64,"props":1465,"children":1467},{"className":1466},[],[1468],{"type":38,"value":1469},"meta_paid_social_spend_roi",{"type":33,"tag":1359,"props":1471,"children":1472},{},[1473],{"type":38,"value":1474},"Meta ROI",{"type":33,"tag":1337,"props":1476,"children":1477},{},[1478,1487],{"type":33,"tag":1359,"props":1479,"children":1480},{},[1481],{"type":33,"tag":64,"props":1482,"children":1484},{"className":1483},[],[1485],{"type":38,"value":1486},"tv_spend_roi",{"type":33,"tag":1359,"props":1488,"children":1489},{},[1490],{"type":38,"value":1491},"TV ROI",{"type":33,"tag":34,"props":1493,"children":1494},{},[1495],{"type":38,"value":1496},"Select the best model based on NRMSE + DECOMP.RSSD + business logic. Robyn offers a Shiny dashboard, but programmatic selection in production gives more control:",{"type":33,"tag":112,"props":1498,"children":1500},{"className":902,"code":1499,"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",[1501],{"type":33,"tag":64,"props":1502,"children":1503},{"__ignoreMap":17},[1504,1512,1520,1528,1536],{"type":33,"tag":122,"props":1505,"children":1506},{"class":124,"line":125},[1507],{"type":33,"tag":122,"props":1508,"children":1509},{},[1510],{"type":38,"value":1511},"best_model_id \u003C- OutputModels$allPareto %>%\n",{"type":33,"tag":122,"props":1513,"children":1514},{"class":124,"line":151},[1515],{"type":33,"tag":122,"props":1516,"children":1517},{},[1518],{"type":38,"value":1519},"  filter(nrmse \u003C 0.1, decomp.rssd \u003C 0.05) %>%\n",{"type":33,"tag":122,"props":1521,"children":1522},{"class":124,"line":160},[1523],{"type":33,"tag":122,"props":1524,"children":1525},{},[1526],{"type":38,"value":1527},"  arrange(nrmse) %>%\n",{"type":33,"tag":122,"props":1529,"children":1530},{"class":124,"line":188},[1531],{"type":33,"tag":122,"props":1532,"children":1533},{},[1534],{"type":38,"value":1535},"  slice(1) %>%\n",{"type":33,"tag":122,"props":1537,"children":1538},{"class":124,"line":212},[1539],{"type":33,"tag":122,"props":1540,"children":1541},{},[1542],{"type":38,"value":1543},"  pull(solID)\n",{"type":33,"tag":41,"props":1545,"children":1547},{"id":1546},"holdout-validation-preventing-overfitting",[1548],{"type":38,"value":1549},"Holdout validation: preventing overfitting",{"type":33,"tag":34,"props":1551,"children":1552},{},[1553],{"type":38,"value":1554},"A model fit to training data may not generalize to unseen data. Robyn uses holdout validation: you hold out the last 8–12 weeks from training and use them as a test set. The model is fit to training data, makes predictions on the test set. If MAPE (mean absolute percentage error) on the test set is under 15%, the model can move to production.",{"type":33,"tag":112,"props":1556,"children":1558},{"className":902,"code":1557,"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\",  # Hold out last 10 weeks\n  # ... other parameters same\n)\n\nOutputModels_train \u003C- robyn_run(InputCollect_train, iterations = 2000)\n\n# Prediction on holdout set\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",[1559],{"type":33,"tag":64,"props":1560,"children":1561},{"__ignoreMap":17},[1562,1570,1577,1584,1591,1598,1606,1614,1621,1628,1636,1643,1651,1659,1667],{"type":33,"tag":122,"props":1563,"children":1564},{"class":124,"line":125},[1565],{"type":33,"tag":122,"props":1566,"children":1567},{},[1568],{"type":38,"value":1569},"InputCollect_train \u003C- robyn_inputs(\n",{"type":33,"tag":122,"props":1571,"children":1572},{"class":124,"line":151},[1573],{"type":33,"tag":122,"props":1574,"children":1575},{},[1576],{"type":38,"value":1020},{"type":33,"tag":122,"props":1578,"children":1579},{"class":124,"line":160},[1580],{"type":33,"tag":122,"props":1581,"children":1582},{},[1583],{"type":38,"value":1028},{"type":33,"tag":122,"props":1585,"children":1586},{"class":124,"line":188},[1587],{"type":33,"tag":122,"props":1588,"children":1589},{},[1590],{"type":38,"value":1036},{"type":33,"tag":122,"props":1592,"children":1593},{"class":124,"line":212},[1594],{"type":33,"tag":122,"props":1595,"children":1596},{},[1597],{"type":38,"value":1076},{"type":33,"tag":122,"props":1599,"children":1600},{"class":124,"line":227},[1601],{"type":33,"tag":122,"props":1602,"children":1603},{},[1604],{"type":38,"value":1605},"  window_end = \"2026-04-12\",  # Hold out last 10 weeks\n",{"type":33,"tag":122,"props":1607,"children":1608},{"class":124,"line":251},[1609],{"type":33,"tag":122,"props":1610,"children":1611},{},[1612],{"type":38,"value":1613},"  # ... other parameters same\n",{"type":33,"tag":122,"props":1615,"children":1616},{"class":124,"line":27},[1617],{"type":33,"tag":122,"props":1618,"children":1619},{},[1620],{"type":38,"value":427},{"type":33,"tag":122,"props":1622,"children":1623},{"class":124,"line":273},[1624],{"type":33,"tag":122,"props":1625,"children":1626},{"emptyLinePlaceholder":930},[1627],{"type":38,"value":933},{"type":33,"tag":122,"props":1629,"children":1630},{"class":124,"line":290},[1631],{"type":33,"tag":122,"props":1632,"children":1633},{},[1634],{"type":38,"value":1635},"OutputModels_train \u003C- robyn_run(InputCollect_train, iterations = 2000)\n",{"type":33,"tag":122,"props":1637,"children":1638},{"class":124,"line":298},[1639],{"type":33,"tag":122,"props":1640,"children":1641},{"emptyLinePlaceholder":930},[1642],{"type":38,"value":933},{"type":33,"tag":122,"props":1644,"children":1645},{"class":124,"line":333},[1646],{"type":33,"tag":122,"props":1647,"children":1648},{},[1649],{"type":38,"value":1650},"# Prediction on holdout set\n",{"type":33,"tag":122,"props":1652,"children":1653},{"class":124,"line":342},[1654],{"type":33,"tag":122,"props":1655,"children":1656},{},[1657],{"type":38,"value":1658},"df_test \u003C- df_input %>% filter(week_start > \"2026-04-12\")\n",{"type":33,"tag":122,"props":1660,"children":1661},{"class":124,"line":364},[1662],{"type":33,"tag":122,"props":1663,"children":1664},{},[1665],{"type":38,"value":1666},"predictions \u003C- predict(OutputModels_train, newdata = df_test)\n",{"type":33,"tag":122,"props":1668,"children":1669},{"class":124,"line":377},[1670],{"type":33,"tag":122,"props":1671,"children":1672},{},[1673],{"type":38,"value":1674},"mape_test \u003C- mean(abs((df_test$revenue - predictions) \u002F df_test$revenue)) * 100\n",{"type":33,"tag":34,"props":1676,"children":1677},{},[1678],{"type":38,"value":1679},"MAPE > 20% signals overfitting. You need to narrow hyperparameter ranges or add context variables (e.g., economic index, weather). Robyn's Bayesian regularization (ridge penalty) reduces overfitting, but holdout validation is the ultimate safeguard.",{"type":33,"tag":41,"props":1681,"children":1683},{"id":1682},"visualizing-adstock-decay-and-saturation-curves",[1684],{"type":38,"value":1685},"Visualizing adstock decay and saturation curves",{"type":33,"tag":34,"props":1687,"children":1688},{},[1689,1691,1697],{"type":38,"value":1690},"Robyn's ",{"type":33,"tag":64,"props":1692,"children":1694},{"className":1693},[],[1695],{"type":38,"value":1696},"robyn_outputs()",{"type":38,"value":1698}," function plots adstock and saturation curves. In production, you export these as PNGs and embed them in BI dashboards:",{"type":33,"tag":112,"props":1700,"children":1702},{"className":902,"code":1701,"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",[1703],{"type":33,"tag":64,"props":1704,"children":1705},{"__ignoreMap":17},[1706,1714,1721,1729,1737,1745,1753],{"type":33,"tag":122,"props":1707,"children":1708},{"class":124,"line":125},[1709],{"type":33,"tag":122,"props":1710,"children":1711},{},[1712],{"type":38,"value":1713},"robyn_outputs(\n",{"type":33,"tag":122,"props":1715,"children":1716},{"class":124,"line":151},[1717],{"type":33,"tag":122,"props":1718,"children":1719},{},[1720],{"type":38,"value":1264},{"type":33,"tag":122,"props":1722,"children":1723},{"class":124,"line":160},[1724],{"type":33,"tag":122,"props":1725,"children":1726},{},[1727],{"type":38,"value":1728},"  OutputModels = OutputModels,\n",{"type":33,"tag":122,"props":1730,"children":1731},{"class":124,"line":188},[1732],{"type":33,"tag":122,"props":1733,"children":1734},{},[1735],{"type":38,"value":1736},"  select_model = best_model_id,\n",{"type":33,"tag":122,"props":1738,"children":1739},{"class":124,"line":212},[1740],{"type":33,"tag":122,"props":1741,"children":1742},{},[1743],{"type":38,"value":1744},"  export = TRUE,\n",{"type":33,"tag":122,"props":1746,"children":1747},{"class":124,"line":227},[1748],{"type":33,"tag":122,"props":1749,"children":1750},{},[1751],{"type":38,"value":1752},"  export_location = \"\u002Fdata\u002Fmmm_output\u002F\"\n",{"type":33,"tag":122,"props":1754,"children":1755},{"class":124,"line":251},[1756],{"type":33,"tag":122,"props":1757,"children":1758},{},[1759],{"type":38,"value":427},{"type":33,"tag":34,"props":1761,"children":1762},{},[1763],{"type":38,"value":1764},"Exported files include:",{"type":33,"tag":1197,"props":1766,"children":1767},{},[1768,1779,1790],{"type":33,"tag":1201,"props":1769,"children":1770},{},[1771,1777],{"type":33,"tag":64,"props":1772,"children":1774},{"className":1773},[],[1775],{"type":38,"value":1776},"saturate_curves.png",{"type":38,"value":1778},"—Spend vs. response for each channel. X-axis is spend, Y-axis is predicted revenue. The curve flattens at saturation.",{"type":33,"tag":1201,"props":1780,"children":1781},{},[1782,1788],{"type":33,"tag":64,"props":1783,"children":1785},{"className":1784},[],[1786],{"type":38,"value":1787},"adstock_curves.png",{"type":38,"value":1789},"—Decay profile. X-axis is weeks, Y-axis is adstock multiplier. TV shows 6–8 week decay.",{"type":33,"tag":1201,"props":1791,"children":1792},{},[1793,1799],{"type":33,"tag":64,"props":1794,"children":1796},{"className":1795},[],[1797],{"type":38,"value":1798},"waterfall.png",{"type":38,"value":1800},"—Revenue decomposition: base + seasonality + channel contribution.",{"type":33,"tag":34,"props":1802,"children":1803},{},[1804],{"type":38,"value":1805},"With these visuals, you can tell a CMO: \"Instead of raising TV spend by 30%, reallocate 20% to search. Total ROI rises 12%.\"",{"type":33,"tag":41,"props":1807,"children":1809},{"id":1808},"production-pipeline-dbt-robyn-looker-studio",[1810],{"type":38,"value":1811},"Production pipeline: dbt + Robyn + Looker Studio",{"type":33,"tag":34,"props":1813,"children":1814},{},[1815,1817,1826],{"type":38,"value":1816},"MMM is not a one-off analysis—weekly refreshes are required. Using Roibase's ",{"type":33,"tag":1818,"props":1819,"children":1823},"a",{"href":1820,"rel":1821},"https:\u002F\u002Fwww.roibase.com.tr\u002Fen\u002Ffirstparty",[1822],"nofollow",[1824],{"type":38,"value":1825},"First-Party Data & Measurement Architecture",{"type":38,"value":1827}," approach, the pipeline is:",{"type":33,"tag":1829,"props":1830,"children":1831},"ol",{},[1832,1850,1916],{"type":33,"tag":1201,"props":1833,"children":1834},{},[1835,1840,1842,1848],{"type":33,"tag":56,"props":1836,"children":1837},{},[1838],{"type":38,"value":1839},"dbt",{"type":38,"value":1841},": Creates the ",{"type":33,"tag":64,"props":1843,"children":1845},{"className":1844},[],[1846],{"type":38,"value":1847},"mmm_input",{"type":38,"value":1849}," table in BigQuery from raw events (using the SQL above). Scheduled dbt Cloud run every Monday at 00:00.",{"type":33,"tag":1201,"props":1851,"children":1852},{},[1853,1858,1860,1865,1867,1872,1874,1879,1881,1887,1889,1894,1895,1900,1901,1907,1908,1914],{"type":33,"tag":56,"props":1854,"children":1855},{},[1856],{"type":38,"value":1857},"Robyn R script",{"type":38,"value":1859},": Runs in a Cloud Run container. Pulls ",{"type":33,"tag":64,"props":1861,"children":1863},{"className":1862},[],[1864],{"type":38,"value":1847},{"type":38,"value":1866}," with ",{"type":33,"tag":64,"props":1868,"children":1870},{"className":1869},[],[1871],{"type":38,"value":897},{"type":38,"value":1873},", calls ",{"type":33,"tag":64,"props":1875,"children":1877},{"className":1876},[],[1878],{"type":38,"value":1312},{"type":38,"value":1880},", writes output to BigQuery (",{"type":33,"tag":64,"props":1882,"children":1884},{"className":1883},[],[1885],{"type":38,"value":1886},"mmm_output",{"type":38,"value":1888}," table: ",{"type":33,"tag":64,"props":1890,"children":1892},{"className":1891},[],[1893],{"type":38,"value":455},{"type":38,"value":314},{"type":33,"tag":64,"props":1896,"children":1898},{"className":1897},[],[1899],{"type":38,"value":709},{"type":38,"value":314},{"type":33,"tag":64,"props":1902,"children":1904},{"className":1903},[],[1905],{"type":38,"value":1906},"roi",{"type":38,"value":314},{"type":33,"tag":64,"props":1909,"children":1911},{"className":1910},[],[1912],{"type":38,"value":1913},"predicted_revenue",{"type":38,"value":1915},").",{"type":33,"tag":1201,"props":1917,"children":1918},{},[1919,1924,1926,1931],{"type":33,"tag":56,"props":1920,"children":1921},{},[1922],{"type":38,"value":1923},"Looker Studio",{"type":38,"value":1925},": Feeds channel ROI trends, saturation curves, and budget recommendation dashboard from ",{"type":33,"tag":64,"props":1927,"children":1929},{"className":1928},[],[1930],{"type":38,"value":1886},{"type":38,"value":450},{"type":33,"tag":34,"props":1933,"children":1934},{},[1935],{"type":38,"value":1936},"Package the container with a 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.R\nCMD [\"Rscript\", \"\u002Fapp\u002Frun_mmm.R\"]\n","dockerfile",[1943],{"type":33,"tag":64,"props":1944,"children":1945},{"__ignoreMap":17},[1946,1954,1962,1970,1978],{"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.R\n",{"type":33,"tag":122,"props":1979,"children":1980},{"class":124,"line":212},[1981],{"type":33,"tag":122,"props":1982,"children":1983},{},[1984],{"type":38,"value":1985},"CMD [\"Rscript\", \"\u002Fapp\u002Frun_mmm.R\"]\n",{"type":33,"tag":34,"props":1987,"children":1988},{},[1989],{"type":38,"value":1990},"Trigger every Monday at 06:00 with Cloud Scheduler. Robyn with 2000 iterations takes ~20 minutes on an 8-core machine.",{"type":33,"tag":41,"props":1992,"children":1994},{"id":1993},"budget-reallocation-deriving-decisions-from-the-pareto-frontier",[1995],{"type":38,"value":1996},"Budget reallocation: deriving decisions from the Pareto frontier",{"type":33,"tag":34,"props":1998,"children":1999},{},[2000,2002,2008],{"type":38,"value":2001},"Robyn's most powerful output is the budget optimizer. The ",{"type":33,"tag":64,"props":2003,"children":2005},{"className":2004},[],[2006],{"type":38,"value":2007},"robyn_allocator()",{"type":38,"value":2009}," function reallocates existing budget across channels to maximize total revenue:",{"type":33,"tag":112,"props":2011,"children":2013},{"className":902,"code":2012,"language":904,"meta":17,"style":17},"AllocatorCollect \u003C- robyn_allocator(\n  InputCollect = InputCollect,\n  OutputCollect = OutputModels,\n  select_model = best_model_id,\n  scenario = \"max_response\",\n  channel_constr_low = c(0.7, 0.7, 0.5),  # Google, Meta, TV protected at 70%, 70%, 50%\n  channel_constr_up = c(1.5, 1.5, 2),     # Max 150%, 150%, 200%\n  expected_spend = 500000,                # Total budget\n  expected_spend_days = 90\n)\n",[2014],{"type":33,"tag":64,"props":2015,"children":2016},{"__ignoreMap":17},[2017,2025,2032,2040,2047,2055,2063,2071,2079,2087],{"type":33,"tag":122,"props":2018,"children":2019},{"class":124,"line":125},[2020],{"type":33,"tag":122,"props":2021,"children":2022},{},[2023],{"type":38,"value":2024},"AllocatorCollect \u003C- robyn_allocator(\n",{"type":33,"tag":122,"props":2026,"children":2027},{"class":124,"line":151},[2028],{"type":33,"tag":122,"props":2029,"children":2030},{},[2031],{"type":38,"value":1264},{"type":33,"tag":122,"props":2033,"children":2034},{"class":124,"line":160},[2035],{"type":33,"tag":122,"props":2036,"children":2037},{},[2038],{"type":38,"value":2039},"  OutputCollect = OutputModels,\n",{"type":33,"tag":122,"props":2041,"children":2042},{"class":124,"line":188},[2043],{"type":33,"tag":122,"props":2044,"children":2045},{},[2046],{"type":38,"value":1736},{"type":33,"tag":122,"props":2048,"children":2049},{"class":124,"line":212},[2050],{"type":33,"tag":122,"props":2051,"children":2052},{},[2053],{"type":38,"value":2054},"  scenario = \"max_response\",\n",{"type":33,"tag":122,"props":2056,"children":2057},{"class":124,"line":227},[2058],{"type":33,"tag":122,"props":2059,"children":2060},{},[2061],{"type":38,"value":2062},"  channel_constr_low = c(0.7, 0.7, 0.5),  # Google, Meta, TV protected at 70%, 70%, 50%\n",{"type":33,"tag":122,"props":2064,"children":2065},{"class":124,"line":251},[2066],{"type":33,"tag":122,"props":2067,"children":2068},{},[2069],{"type":38,"value":2070},"  channel_constr_up = c(1.5, 1.5, 2),     # Max 150%, 150%, 200%\n",{"type":33,"tag":122,"props":2072,"children":2073},{"class":124,"line":27},[2074],{"type":33,"tag":122,"props":2075,"children":2076},{},[2077],{"type":38,"value":2078},"  expected_spend = 500000,                # Total budget\n",{"type":33,"tag":122,"props":2080,"children":2081},{"class":124,"line":273},[2082],{"type":33,"tag":122,"props":2083,"children":2084},{},[2085],{"type":38,"value":2086},"  expected_spend_days = 90\n",{"type":33,"tag":122,"props":2088,"children":2089},{"class":124,"line":290},[2090],{"type":33,"tag":122,"props":2091,"children":2092},{},[2093],{"type":38,"value":427},{"type":33,"tag":34,"props":2095,"children":2096},{},[2097],{"type":38,"value":2098},"Output table:",{"type":33,"tag":1329,"props":2100,"children":2101},{},[2102,2133],{"type":33,"tag":1333,"props":2103,"children":2104},{},[2105],{"type":33,"tag":1337,"props":2106,"children":2107},{},[2108,2113,2118,2123,2128],{"type":33,"tag":1341,"props":2109,"children":2110},{},[2111],{"type":38,"value":2112},"Channel",{"type":33,"tag":1341,"props":2114,"children":2115},{},[2116],{"type":38,"value":2117},"Current Spend",{"type":33,"tag":1341,"props":2119,"children":2120},{},[2121],{"type":38,"value":2122},"Optimized Spend",{"type":33,"tag":1341,"props":2124,"children":2125},{},[2126],{"type":38,"value":2127},"Delta",{"type":33,"tag":1341,"props":2129,"children":2130},{},[2131],{"type":38,"value":2132},"Expected Revenue Lift",{"type":33,"tag":1352,"props":2134,"children":2135},{},[2136,2164,2191],{"type":33,"tag":1337,"props":2137,"children":2138},{},[2139,2144,2149,2154,2159],{"type":33,"tag":1359,"props":2140,"children":2141},{},[2142],{"type":38,"value":2143},"Google Search",{"type":33,"tag":1359,"props":2145,"children":2146},{},[2147],{"type":38,"value":2148},"200,000",{"type":33,"tag":1359,"props":2150,"children":2151},{},[2152],{"type":38,"value":2153},"180,000",{"type":33,"tag":1359,"props":2155,"children":2156},{},[2157],{"type":38,"value":2158},"–10%",{"type":33,"tag":1359,"props":2160,"children":2161},{},[2162],{"type":38,"value":2163},"–2%",{"type":33,"tag":1337,"props":2165,"children":2166},{},[2167,2172,2176,2181,2186],{"type":33,"tag":1359,"props":2168,"children":2169},{},[2170],{"type":38,"value":2171},"Meta Paid Social",{"type":33,"tag":1359,"props":2173,"children":2174},{},[2175],{"type":38,"value":2148},{"type":33,"tag":1359,"props":2177,"children":2178},{},[2179],{"type":38,"value":2180},"220,000",{"type":33,"tag":1359,"props":2182,"children":2183},{},[2184],{"type":38,"value":2185},"+10%",{"type":33,"tag":1359,"props":2187,"children":2188},{},[2189],{"type":38,"value":2190},"+8%",{"type":33,"tag":1337,"props":2192,"children":2193},{},[2194,2199,2204,2208,2213],{"type":33,"tag":1359,"props":2195,"children":2196},{},[2197],{"type":38,"value":2198},"TV",{"type":33,"tag":1359,"props":2200,"children":2201},{},[2202],{"type":38,"value":2203},"100,000",{"type":33,"tag":1359,"props":2205,"children":2206},{},[2207],{"type":38,"value":2203},{"type":33,"tag":1359,"props":2209,"children":2210},{},[2211],{"type":38,"value":2212},"0%",{"type":33,"tag":1359,"props":2214,"children":2215},{},[2216],{"type":38,"value":2212},{"type":33,"tag":34,"props":2218,"children":2219},{},[2220],{"type":38,"value":2221},"With this table, you can say: \"Shift 10% to Meta, total revenue rises 6%.\" Constraints (0.7–1.5 multipliers) reflect business limits—for example, TV contract locked for 3 months; only digital is flexible.",{"type":33,"tag":41,"props":2223,"children":2225},{"id":2224},"robyns-limits-and-combining-with-incrementality-tests",[2226],{"type":38,"value":2227},"Robyn's limits and combining with incrementality tests",{"type":33,"tag":34,"props":2229,"children":2230},{},[2231],{"type":38,"value":2232},"MMM is correlation-based, not causation. If TV spend and sales both rise at the same time, Robyn shows positive ROI, but sales might rise for another reason (economic improvement). Incrementality testing—geo-experiment, holdout group—proves causality. Robyn + incrementality: Robyn provides weekly allocation guidance; incrementality tests validate 2–3 times per year.",{"type":33,"tag":34,"props":2234,"children":2235},{},[2236],{"type":38,"value":2237},"Another limitation: new channels. You cannot draw a saturation curve for a channel with no historical data (e.g., podcasts). You accumulate data over 8–12 weeks with a test budget, then add it to the model.",{"type":33,"tag":34,"props":2239,"children":2240},{},[2241,2243,2250],{"type":38,"value":2242},"A final constraint: granularity. Robyn works weekly—you cannot make daily or hourly decisions. For that, the ",{"type":33,"tag":1818,"props":2244,"children":2247},{"href":2245,"rel":2246},"https:\u002F\u002Fwww.roibase.com.tr\u002Fen\u002Fverianalizi",[1822],[2248],{"type":38,"value":2249},"Data Analytics & Insight Engineering",{"type":38,"value":2251}," domain brings in real-time bidding models (XGBoost, LightGBM).",{"type":33,"tag":34,"props":2253,"children":2254},{},[2255],{"type":38,"value":2256},"Marketing Mix Modeling in 2026 is the backbone of attribution. The Robyn framework moves that backbone into a production pipeline: weekly data from BigQuery, hyperparameter tuning via genetic algorithm, overfitting control through holdout validation, and decision-making via budget allocator. Saturation curves and adstock decay bind marketing spend to engineering discipline—prediction over promise, regression over intuition, confidence intervals over claims. Your next step: consolidate 2 years of weekly spend and revenue into BigQuery, deploy the Robyn container to Cloud Run, and present the first Pareto frontier to your CMO.",{"type":33,"tag":2258,"props":2259,"children":2260},"style",{},[2261],{"type":38,"value":2262},"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":2264},[2265,2266,2267,2268,2269,2270,2271,2272,2273],{"id":43,"depth":151,"text":46},{"id":102,"depth":151,"text":105},{"id":981,"depth":151,"text":984},{"id":1238,"depth":151,"text":1241},{"id":1546,"depth":151,"text":1549},{"id":1682,"depth":151,"text":1685},{"id":1808,"depth":151,"text":1811},{"id":1993,"depth":151,"text":1996},{"id":2224,"depth":151,"text":2227},"markdown","content:en:data:marketing-mix-modeling-practical-setup-robyn.md","content","en\u002Fdata\u002Fmarketing-mix-modeling-practical-setup-robyn.md","en\u002Fdata\u002Fmarketing-mix-modeling-practical-setup-robyn","md",1782079487367]