[{"data":1,"prerenderedAt":2134},["ShallowReactive",2],{"article-alternates":3,"article-\u002Ffr\u002Fdata\u002Fmarketing-mix-modeling-robyn-pratik-kurulum":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":2128,"_id":2129,"_source":2130,"_file":2131,"_stem":2132,"_extension":2133},"\u002Ffr\u002Fdata\u002Fmarketing-mix-modeling-robyn-pratik-kurulum","data",false,"","Marketing Mix Modeling: Configuration Pratique avec Robyn","Framework Robyn de Meta pour configurer un modèle d'attribution : courbes de saturation, adstock decay et validation holdout. SQL, R et pipeline production.","2026-06-21",[22,23,24,25,26],"marketing-mix-modeling","robyn","adstock","attribution","mmm",8,"Roibase",{"type":30,"children":31,"toc":2118},"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,1986,1991,1997,2018,2102,2107,2112],{"type":33,"tag":34,"props":35,"children":36},"element","p",{},[37],{"type":38,"value":39},"text","La dépréciation des cookies et les régulations de confidentialité déplacent l'attribution des méthodes déterministes vers la modélisation probabiliste. Le Marketing Mix Modeling (MMM) — outil statistique des années 1960 — retrouve une pertinence centrale. Le framework open-source Robyn de Meta fournit le volet pratique de cette transformation : via l'inférence bayésienne, les courbes de saturation et l'adstock decay, tu lies la dépense marketing hebdomadaire aux ventes par régression, puis tu déploies ce modèle en production. Cet article montre comment installer Robyn, ajuster le modèle à des données réelles, exécuter une recherche grid d'hyperparamètres et prévenir l'overfitting avec une validation holdout.",{"type":33,"tag":41,"props":42,"children":44},"h2",{"id":43},"quest-ce-que-robyn-et-sa-différence-avec-la-régression-classique",[45],{"type":38,"value":46},"Qu'est-ce que Robyn et sa différence avec la régression classique",{"type":33,"tag":34,"props":48,"children":49},{},[50],{"type":38,"value":51},"Robyn est un framework MMM open-source écrit en R. Meta l'a développé pour son équipe marketing en 2020 et l'a publié en 2021. Ses différences avec la régression linéaire classique :",{"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},"Transformation d'adstock",{"type":38,"value":62}," : L'effet marketing n'est pas instantané — une publicité TV entretient la notoriété pendant des semaines. L'adstock modélise la contribution des dépenses passées sur les ventes actuelles via une décroissance exponentielle. Robyn supporte les fonctions adstock géométrique et Weibull. La géométrique est 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},", où θ est le paramètre de décroissance. La Weibull est plus flexible — tu peux positionner l'effet maximal avec un délai.",{"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 (rendements décroissants)",{"type":38,"value":81}," : La relation dépense-ventes n'est pas linéaire. Les premiers 100k € générent 80 % de ROI, les 100k € suivants seulement 40 %. Robyn applique les fonctions de saturation Hill et S-curve. L'équation de 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},", où K est le point de demi-maximum et n la pente. Cette non-linéarité est critique pour l'optimisation budgétaire par canal.",{"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}," : Les paramètres adstock decay, saturation K et n sont inconnus — une recherche grid les découvre. Robyn utilise un algorithme génétique (NSGAII) pour tester des milliers de combinaisons de paramètres et sélectionner les meilleurs compromis sur la frontière de Pareto.",{"type":33,"tag":41,"props":101,"children":103},{"id":102},"préparation-des-données-de-sql-à-la-granularité-hebdomadaire",[104],{"type":38,"value":105},"Préparation des données : de SQL à la granularité hebdomadaire",{"type":33,"tag":34,"props":107,"children":108},{},[109],{"type":38,"value":110},"Robyn fonctionne à granularité hebdomadaire. Tu agrèges les logs transactionnels quotidiens en dépense média et revenu hebdomadaires. Exemple de requête 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},"Cette requête produit une ligne par semaine, une colonne revenue et N colonnes de dépense par canal. Robyn peut consommer un CSV, mais extraire directement depuis BigQuery en production est plus propre. Avec le package ",{"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},"Minimum requis : 104 semaines (2 ans). Moins de données risquent l'overfitting. Les prior bayésiens de Robyn fonctionnent avec 52 semaines, mais 104+ semaines capturent mieux la saisonnalité.",{"type":33,"tag":41,"props":980,"children":982},{"id":981},"configuration-du-modèle-robyn_inputs-et-grid-dhyperparamètres",[983],{"type":38,"value":984},"Configuration du modèle : robyn_inputs et grid d'hyperparamètres",{"type":33,"tag":34,"props":986,"children":987},{},[988,990,996],{"type":38,"value":989},"Robyn crée un objet config via ",{"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},"Explication des hyperparamètres :",{"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}," : Paramètre slope (n) de la fonction de saturation Hill. Alpha élevé = saturation tardive.",{"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}," : Paramètre K de Hill — point de demi-maximum. Gamma bas = saturation précoce.",{"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}," : Adstock decay géométrique. 0 = effet immédiat, 0.7 = 70 % reportés à la semaine suivante.",{"type":33,"tag":34,"props":1231,"children":1232},{},[1233],{"type":38,"value":1234},"Tu fournis un intervalle min-max par canal. Robyn effectue une recherche grid dans ces intervalles. Pour TV, le plafond theta est 0.7 — la notoriété persiste longtemps. Pour paid search, 0.3 — la conversion est à court terme.",{"type":33,"tag":41,"props":1236,"children":1238},{"id":1237},"exécution-du-modèle-robyn_run-et-optimisation-pareto",[1239],{"type":38,"value":1240},"Exécution du modèle : robyn_run et optimisation Pareto",{"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}," exécute un algorithme génétique sur 2000 itérations testant des combinaisons d'hyperparamètres. À chaque itération, il minimise NRMSE (erreur quadratique moyenne normalisée) et DECOMP.RSSD (différence de somme des résidus carrés de décomposition). Cinq modèles sont sélectionnés à partir de la frontière de Pareto — tu choisis le meilleur compromis : qualité d'ajustement vs. logique métier (p.ex. le ROI TV ne doit pas dépasser le search).",{"type":33,"tag":34,"props":1315,"children":1316},{},[1317,1319,1325],{"type":38,"value":1318},"L'objet output contient une table ",{"type":33,"tag":64,"props":1320,"children":1322},{"className":1321},[],[1323],{"type":38,"value":1324},"df_allpareto",{"type":38,"value":1326}," — chaque modèle y figure avec ses ROI par canal, ROAS et CPA. Nombre de lignes = itérations × trials. Colonnes clés :",{"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},"Colonne",{"type":33,"tag":1340,"props":1346,"children":1347},{},[1348],{"type":38,"value":1349},"Description",{"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 du modèle",{"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},"NRMSE normalisé — bas = bon ajustement",{"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},"RSSD de décomposition — bas = contributions stables",{"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},"Erreur absolue moyenne en pourcentage",{"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² d'entraînement",{"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 (revenu\u002Fdépense)",{"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 TV",{"type":33,"tag":34,"props":1492,"children":1493},{},[1494],{"type":38,"value":1495},"Tu sélectionnes le meilleur modèle via NRMSE + DECOMP.RSSD + logique métier. Robyn offre un dashboard Shiny, mais en production la sélection programmatique est plus contrôlée :",{"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},"validation-holdout-prévenir-loverfitting",[1547],{"type":38,"value":1548},"Validation holdout : prévenir l'overfitting",{"type":33,"tag":34,"props":1550,"children":1551},{},[1552],{"type":38,"value":1553},"Un modèle ajusté sur données d'entraînement ne généralise pas forcément sur données inédites. Avec validation holdout dans Robyn : tu retires les 8-12 dernières semaines des données d'entraînement et les réserves comme test set. Le modèle s'ajuste sur l'entraînement, fait des prédictions sur le test. Si MAPE (erreur absolue moyenne en pourcentage) sur le test reste \u003C 15 %, le modèle peut aller en 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\",  # Dernières 10 semaines en holdout\n  # ... autres paramètres identiques\n)\n\nOutputModels_train \u003C- robyn_run(InputCollect_train, iterations = 2000)\n\n# Prédiction sur le test 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",[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\",  # Dernières 10 semaines en 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},"  # ... autres paramètres identiques\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},"# Prédiction sur le test set\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},"Si MAPE > 20 %, le modèle est overfit. Tu dois réduire les plages d'hyperparamètres ou ajouter des variables contextuelles (indice économique, météo). La régularisation bayésienne de Robyn (pénalité ridge) réduit l'overfitting, mais la validation holdout est la garantie finale.",{"type":33,"tag":41,"props":1680,"children":1682},{"id":1681},"visualiser-courbes-dadstock-et-saturation",[1683],{"type":38,"value":1684},"Visualiser courbes d'adstock et saturation",{"type":33,"tag":34,"props":1686,"children":1687},{},[1688,1690,1696],{"type":38,"value":1689},"Robyn exporte les courbes d'adstock et saturation via ",{"type":33,"tag":64,"props":1691,"children":1693},{"className":1692},[],[1694],{"type":38,"value":1695},"robyn_outputs()",{"type":38,"value":1697},". En production, tu génères ces graphiques en PNG et les intègres dans le dashboard 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},"Fichiers exportés :",{"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}," — Par canal, courbe dépense vs. réponse. L'axe X : dépense, Y : revenu prédit. La courbe s'aplatit au point de saturation.",{"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}," — Profil decay. X : semaine, Y : multiplicateur adstock. TV décroît sur 6-8 semaines.",{"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}," — Décomposition revenue : base + saisonnalité + contribution par canal.",{"type":33,"tag":34,"props":1801,"children":1802},{},[1803],{"type":38,"value":1804},"Avec ces visualisations, au lieu de dire « augmente la dépense TV de 30 % », tu dis « TV est au point de saturation ; réaffecter 20 % à search augmentera le ROI total de 12 % ».",{"type":33,"tag":41,"props":1806,"children":1808},{"id":1807},"pipeline-production-dbt-robyn-looker-studio",[1809],{"type":38,"value":1810},"Pipeline production : dbt + Robyn + Looker Studio",{"type":33,"tag":34,"props":1812,"children":1813},{},[1814,1816,1825],{"type":38,"value":1815},"MMM n'est pas une analyse ponctuelle — il faut un refresh hebdomadaire. Avec l'approche ",{"type":33,"tag":1817,"props":1818,"children":1822},"a",{"href":1819,"rel":1820},"https:\u002F\u002Fwww.roibase.com.tr\u002Ffr\u002Ffirstparty",[1821],"nofollow",[1823],{"type":38,"value":1824},"First-Party Data & Architecture de Mesure",{"type":38,"value":1826}," de Roibase, le pipeline se structure ainsi :",{"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}," : Produit la table ",{"type":33,"tag":64,"props":1842,"children":1844},{"className":1843},[],[1845],{"type":38,"value":1846},"mmm_input",{"type":38,"value":1848}," depuis les événements bruts dans BigQuery (SQL ci-dessus). Exécution dbt Cloud programmée chaque lundi 00:00.",{"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},"Script Robyn R",{"type":38,"value":1858}," : Container Cloud Run exécute le script. Récupère ",{"type":33,"tag":64,"props":1860,"children":1862},{"className":1861},[],[1863],{"type":38,"value":1846},{"type":38,"value":1865}," via ",{"type":33,"tag":64,"props":1867,"children":1869},{"className":1868},[],[1870],{"type":38,"value":897},{"type":38,"value":1872},", lance ",{"type":33,"tag":64,"props":1874,"children":1876},{"className":1875},[],[1877],{"type":38,"value":1311},{"type":38,"value":1879},", écrit la sortie dans BigQuery (",{"type":33,"tag":64,"props":1881,"children":1883},{"className":1882},[],[1884],{"type":38,"value":1885},"mmm_output",{"type":38,"value":1887}," table : ",{"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}," : Connecté à ",{"type":33,"tag":64,"props":1926,"children":1928},{"className":1927},[],[1929],{"type":38,"value":1885},{"type":38,"value":1931},", crée un dashboard tendance ROI par canal, courbes de saturation et recommandations budgétaires.",{"type":33,"tag":34,"props":1933,"children":1934},{},[1935],{"type":38,"value":1936},"Le container est emballé via 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},"Tu schedules chaque lundi 06:00 via Cloud Scheduler. Robyn 2000 itérations prennent ~20 minutes sur 8 cores.",{"type":33,"tag":41,"props":1992,"children":1994},{"id":1993},"réallocation-budgétaire-décisions-depuis-la-frontière-pareto",[1995],{"type":38,"value":1996},"Réallocation budgétaire : décisions depuis la frontière Pareto",{"type":33,"tag":34,"props":1998,"children":1999},{},[2000,2002,2008,2010,2016],{"type":38,"value":2001},"Le résultat le plus puissant de Robyn : l'",{"type":33,"tag":2003,"props":2004,"children":2005},"em",{},[2006],{"type":38,"value":2007},"allocator",{"type":38,"value":2009},". La fonction ",{"type":33,"tag":64,"props":2011,"children":2013},{"className":2012},[],[2014],{"type":38,"value":2015},"robyn_allocator()",{"type":38,"value":2017}," réalloue le budget courant entre canaux pour maximiser le revenu total :",{"type":33,"tag":112,"props":2019,"children":2021},{"className":902,"code":2020,"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 : min 70%, 70%, 50%\n  channel_constr_up = c(1.5, 1.5, 2),     # Max 150%, 150%, 200%\n  expected_spend = 500000,                # Budget total\n  expected_spend_days = 90\n)\n",[2022],{"type":33,"tag":64,"props":2023,"children":2024},{"__ignoreMap":17},[2025,2033,2040,2048,2055,2063,2071,2079,2087,2095],{"type":33,"tag":122,"props":2026,"children":2027},{"class":124,"line":125},[2028],{"type":33,"tag":122,"props":2029,"children":2030},{},[2031],{"type":38,"value":2032},"AllocatorCollect \u003C- robyn_allocator(\n",{"type":33,"tag":122,"props":2034,"children":2035},{"class":124,"line":151},[2036],{"type":33,"tag":122,"props":2037,"children":2038},{},[2039],{"type":38,"value":1263},{"type":33,"tag":122,"props":2041,"children":2042},{"class":124,"line":160},[2043],{"type":33,"tag":122,"props":2044,"children":2045},{},[2046],{"type":38,"value":2047},"  OutputCollect = OutputModels,\n",{"type":33,"tag":122,"props":2049,"children":2050},{"class":124,"line":188},[2051],{"type":33,"tag":122,"props":2052,"children":2053},{},[2054],{"type":38,"value":1735},{"type":33,"tag":122,"props":2056,"children":2057},{"class":124,"line":212},[2058],{"type":33,"tag":122,"props":2059,"children":2060},{},[2061],{"type":38,"value":2062},"  scenario = \"max_response\",\n",{"type":33,"tag":122,"props":2064,"children":2065},{"class":124,"line":227},[2066],{"type":33,"tag":122,"props":2067,"children":2068},{},[2069],{"type":38,"value":2070},"  channel_constr_low = c(0.7, 0.7, 0.5),  # Google, Meta, TV : min 70%, 70%, 50%\n",{"type":33,"tag":122,"props":2072,"children":2073},{"class":124,"line":251},[2074],{"type":33,"tag":122,"props":2075,"children":2076},{},[2077],{"type":38,"value":2078},"  channel_constr_up = c(1.5, 1.5, 2),     # Max 150%, 150%, 200%\n",{"type":33,"tag":122,"props":2080,"children":2081},{"class":124,"line":27},[2082],{"type":33,"tag":122,"props":2083,"children":2084},{},[2085],{"type":38,"value":2086},"  expected_spend = 500000,                # Budget total\n",{"type":33,"tag":122,"props":2088,"children":2089},{"class":124,"line":273},[2090],{"type":33,"tag":122,"props":2091,"children":2092},{},[2093],{"type":38,"value":2094},"  expected_spend_days = 90\n",{"type":33,"tag":122,"props":2096,"children":2097},{"class":124,"line":290},[2098],{"type":33,"tag":122,"props":2099,"children":2100},{},[2101],{"type":38,"value":427},{"type":33,"tag":34,"props":2103,"children":2104},{},[2105],{"type":38,"value":2106},"Table résultat :",{"type":33,"tag":34,"props":2108,"children":2109},{},[2110],{"type":38,"value":2111},"| Canal | Dépense Actuelle | Dépense Optimisée | Delta | Lift Revenu Attendu |\n|-------|------------------|-------------------|-------|",{"type":33,"tag":2113,"props":2114,"children":2115},"style",{},[2116],{"type":38,"value":2117},"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":2119},[2120,2121,2122,2123,2124,2125,2126,2127],{"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},{"id":1993,"depth":151,"text":1996},"markdown","content:fr:data:marketing-mix-modeling-robyn-pratik-kurulum.md","content","fr\u002Fdata\u002Fmarketing-mix-modeling-robyn-pratik-kurulum.md","fr\u002Fdata\u002Fmarketing-mix-modeling-robyn-pratik-kurulum","md",1782079493276]