[{"data":1,"prerenderedAt":1140},["ShallowReactive",2],{"article-alternates":3,"article-\u002Ffr\u002Fdata\u002Frobyn-marketing-mix-modeling-guide":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":9,"_dir":14,"_draft":15,"_partial":15,"_locale":16,"title":17,"description":18,"publishedAt":19,"modifiedAt":19,"category":14,"i18nKey":4,"tags":20,"readingTime":26,"author":27,"body":28,"_type":1134,"_id":1135,"_source":1136,"_file":1137,"_stem":1138,"_extension":1139},"data",false,"","Marketing Mix Modeling : Configuration pratique avec Robyn","Framework MMM open-source de Meta, Robyn, pour modéliser saturation, adstock et validation holdout avec code R et structure de données éprouvée.","2026-06-05",[21,22,23,24,25],"marketing-mix-modeling","robyn","adstock","saturation-curve","incrementality",9,"Roibase",{"type":29,"children":30,"toc":1126},"root",[31,47,54,67,106,118,124,129,240,248,332,353,377,383,395,403,438,443,451,470,564,569,575,595,796,822,827,881,893,899,925,945,1014,1026,1032,1051,1078,1096,1115,1120],{"type":32,"tag":33,"props":34,"children":35},"element","p",{},[36,39,45],{"type":37,"value":38},"text","Dans un monde de mesure post-cookies, l'attribution perd chaque jour davantage de signal. Avec iOS 17.4 et même SKAdNetwork qui peine à restituer le véritable ROAS, les responsables de budget marketing se tournent vers des modèles économétriques pour mesurer la contribution réelle des canaux. Le Marketing Mix Modeling (MMM), méthode statistique développée dans les années 1960 pour la publicité télévisée, reprend une place centrale en 2026 aux côtés de la mesure server-side et des data lakes propriétaires. ",{"type":32,"tag":40,"props":41,"children":42},"strong",{},[43],{"type":37,"value":44},"Robyn",{"type":37,"value":46},", publié en open-source par Meta en 2021, accélère l'application de cette méthodologie basée sur la régression en y ajoutant l'apprentissage automatique moderne et l'optimisation bayésienne.",{"type":32,"tag":48,"props":49,"children":51},"h2",{"id":50},"pourquoi-mmm-est-critique-aujourdhui",[52],{"type":37,"value":53},"Pourquoi MMM est critique aujourd'hui",{"type":32,"tag":33,"props":55,"children":56},{},[57,59,65],{"type":37,"value":58},"Le modèle last-click s'effondre avec la perte de cookies, tandis que l'attribution multi-touch (MTA) devient impraticable à cause de la nécessité de données au niveau événement — impossible après le RGPD et l'ATT. L'",{"type":32,"tag":60,"props":61,"children":62},"em",{},[63],{"type":37,"value":64},"attribution data-driven",{"type":37,"value":66}," de Google Analytics 4 s'appuie sur le machine learning mais fonctionne seulement dans l'écosystème Google. Or, 60 % du budget marketing se situe en dehors de Google : Meta, TikTok, display programmatique, TV hors ligne, sponsorships.",{"type":32,"tag":33,"props":68,"children":69},{},[70,72,77,79,84,86,90,92,97,99,104],{"type":37,"value":71},"MMM repose sur des données ",{"type":32,"tag":40,"props":73,"children":74},{},[75],{"type":37,"value":76},"agrégées",{"type":37,"value":78}," par semaine ou par jour, non sur le suivi au niveau utilisateur. Le modèle de régression extrait la relation entre les dépenses de chaque canal et les ventes (ou conversions). Deux hypothèses fondamentales soutiennent le modèle : la ",{"type":32,"tag":40,"props":80,"children":81},{},[82],{"type":37,"value":83},"saturation",{"type":37,"value":85}," (les dépenses croissantes génèrent un rendement marginal décroissant) et l'",{"type":32,"tag":40,"props":87,"children":88},{},[89],{"type":37,"value":23},{"type":37,"value":91}," (la publicité d'aujourd'hui impacte les semaines futures). Ces hypothèses sont statistiques mais reflètent la réalité commerciale. Robyn vise à trouver automatiquement ces deux paramètres via optimisation bayésienne des hyperparamètres. Depuis fin 2024 (v3.11+), l'ajout de ",{"type":32,"tag":40,"props":93,"children":94},{},[95],{"type":37,"value":96},"ridge regression",{"type":37,"value":98}," et de ",{"type":32,"tag":40,"props":100,"children":101},{},[102],{"type":37,"value":103},"décomposition de série temporelle Prophet",{"type":37,"value":105}," a amélioré la précision saisonnière du modèle.",{"type":32,"tag":33,"props":107,"children":108},{},[109,111,116],{"type":37,"value":110},"Une autre caractéristique critique de Robyn est la ",{"type":32,"tag":40,"props":112,"children":113},{},[114],{"type":37,"value":115},"validation holdout",{"type":37,"value":117}," : le modèle s'entraîne sur 12 semaines passées et prédit les 4 semaines suivantes pour mesurer l'erreur hors échantillon. Cela prévient l'overfitting et démontre que le modèle apprend réellement les canaux. Les solutions MMM de Google (Meridian) et de Facebook utilisent des approches similaires mais sont à source fermée et coûteuses. Robyn offre accès gratuit à la même méthodologie.",{"type":32,"tag":48,"props":119,"children":121},{"id":120},"structure-des-données-et-préparation",[122],{"type":37,"value":123},"Structure des données et préparation",{"type":32,"tag":33,"props":125,"children":126},{},[127],{"type":37,"value":128},"Pour exécuter Robyn, les données doivent être au format suivant : chaque ligne représente une unité de temps (jour ou semaine), chaque colonne une dépense de canal ou une métrique de conversion. Un minimum de 104 semaines (2 ans) est recommandé, car la signification statistique des coefficients de régression dépend de la taille de l'échantillon. Avec moins de 52 semaines, tu rencontres des problèmes de convergence du modèle.",{"type":32,"tag":130,"props":131,"children":135},"pre",{"code":132,"language":133,"meta":16,"className":134,"style":16},"# Exemple de structure — données agrégées hebdomadaires extraites de BigQuery\ndf \u003C- data.frame(\n  DATE = seq.Date(from = as.Date(\"2024-01-01\"), by = \"week\", length.out = 104),\n  revenue = runif(104, 80000, 150000),\n  google_search_spend = runif(104, 5000, 15000),\n  meta_spend = runif(104, 8000, 20000),\n  tiktok_spend = runif(104, 2000, 8000),\n  tv_grp = runif(104, 50, 200),\n  organic_sessions = runif(104, 10000, 30000),\n  competitor_index = runif(104, 0.8, 1.2)\n)\n","r","language-r shiki shiki-themes github-dark",[136],{"type":32,"tag":137,"props":138,"children":139},"code",{"__ignoreMap":16},[140,151,160,169,178,187,196,205,214,222,231],{"type":32,"tag":141,"props":142,"children":145},"span",{"class":143,"line":144},"line",1,[146],{"type":32,"tag":141,"props":147,"children":148},{},[149],{"type":37,"value":150},"# Exemple de structure — données agrégées hebdomadaires extraites de BigQuery\n",{"type":32,"tag":141,"props":152,"children":154},{"class":143,"line":153},2,[155],{"type":32,"tag":141,"props":156,"children":157},{},[158],{"type":37,"value":159},"df \u003C- data.frame(\n",{"type":32,"tag":141,"props":161,"children":163},{"class":143,"line":162},3,[164],{"type":32,"tag":141,"props":165,"children":166},{},[167],{"type":37,"value":168},"  DATE = seq.Date(from = as.Date(\"2024-01-01\"), by = \"week\", length.out = 104),\n",{"type":32,"tag":141,"props":170,"children":172},{"class":143,"line":171},4,[173],{"type":32,"tag":141,"props":174,"children":175},{},[176],{"type":37,"value":177},"  revenue = runif(104, 80000, 150000),\n",{"type":32,"tag":141,"props":179,"children":181},{"class":143,"line":180},5,[182],{"type":32,"tag":141,"props":183,"children":184},{},[185],{"type":37,"value":186},"  google_search_spend = runif(104, 5000, 15000),\n",{"type":32,"tag":141,"props":188,"children":190},{"class":143,"line":189},6,[191],{"type":32,"tag":141,"props":192,"children":193},{},[194],{"type":37,"value":195},"  meta_spend = runif(104, 8000, 20000),\n",{"type":32,"tag":141,"props":197,"children":199},{"class":143,"line":198},7,[200],{"type":32,"tag":141,"props":201,"children":202},{},[203],{"type":37,"value":204},"  tiktok_spend = runif(104, 2000, 8000),\n",{"type":32,"tag":141,"props":206,"children":208},{"class":143,"line":207},8,[209],{"type":32,"tag":141,"props":210,"children":211},{},[212],{"type":37,"value":213},"  tv_grp = runif(104, 50, 200),\n",{"type":32,"tag":141,"props":215,"children":216},{"class":143,"line":26},[217],{"type":32,"tag":141,"props":218,"children":219},{},[220],{"type":37,"value":221},"  organic_sessions = runif(104, 10000, 30000),\n",{"type":32,"tag":141,"props":223,"children":225},{"class":143,"line":224},10,[226],{"type":32,"tag":141,"props":227,"children":228},{},[229],{"type":37,"value":230},"  competitor_index = runif(104, 0.8, 1.2)\n",{"type":32,"tag":141,"props":232,"children":234},{"class":143,"line":233},11,[235],{"type":32,"tag":141,"props":236,"children":237},{},[238],{"type":37,"value":239},")\n",{"type":32,"tag":33,"props":241,"children":242},{},[243],{"type":32,"tag":40,"props":244,"children":245},{},[246],{"type":37,"value":247},"Détails importants :",{"type":32,"tag":249,"props":250,"children":251},"ul",{},[252,266,271,299,327],{"type":32,"tag":253,"props":254,"children":255},"li",{},[256,258,264],{"type":37,"value":257},"La colonne ",{"type":32,"tag":137,"props":259,"children":261},{"className":260},[],[262],{"type":37,"value":263},"DATE",{"type":37,"value":265}," doit être au format Date, pas en chaîne de caractères",{"type":32,"tag":253,"props":267,"children":268},{},[269],{"type":37,"value":270},"La revenue ou la conversion entre comme variable cible dans le modèle (variable dépendante)",{"type":32,"tag":253,"props":272,"children":273},{},[274,276,282,284,290,292,297],{"type":37,"value":275},"Les canaux (",{"type":32,"tag":137,"props":277,"children":279},{"className":278},[],[280],{"type":37,"value":281},"google_search_spend",{"type":37,"value":283},", ",{"type":32,"tag":137,"props":285,"children":287},{"className":286},[],[288],{"type":37,"value":289},"meta_spend",{"type":37,"value":291},") sont des colonnes ",{"type":32,"tag":40,"props":293,"children":294},{},[295],{"type":37,"value":296},"paid media",{"type":37,"value":298}," — l'adstock et la saturation s'y appliquent",{"type":32,"tag":253,"props":300,"children":301},{},[302,304,310,312,318,320,325],{"type":37,"value":303},"Les variables comme ",{"type":32,"tag":137,"props":305,"children":307},{"className":306},[],[308],{"type":37,"value":309},"organic_sessions",{"type":37,"value":311}," et ",{"type":32,"tag":137,"props":313,"children":315},{"className":314},[],[316],{"type":37,"value":317},"competitor_index",{"type":37,"value":319}," sont des variables ",{"type":32,"tag":40,"props":321,"children":322},{},[323],{"type":37,"value":324},"organiques \u002F contrôle",{"type":37,"value":326}," — aucune transformation ne leur est appliquée, elles servent à l'extraction de baseline",{"type":32,"tag":253,"props":328,"children":329},{},[330],{"type":37,"value":331},"Pour les canaux hors ligne comme la TV, normalise les données en GRP, reach ou minutes regardées",{"type":32,"tag":33,"props":333,"children":334},{},[335,337,343,345,351],{"type":37,"value":336},"Robyn ne fonctionne pas avec des étiquettes prédéfinies comme ",{"type":32,"tag":137,"props":338,"children":340},{"className":339},[],[341],{"type":37,"value":342},"facebook_spend",{"type":37,"value":344}," ; tu définis toi-même les noms de colonnes, mais tu dois spécifier dans la fonction ",{"type":32,"tag":137,"props":346,"children":348},{"className":347},[],[349],{"type":37,"value":350},"InputCollect()",{"type":37,"value":352}," quelles colonnes sont paid et lesquelles sont organiques.",{"type":32,"tag":33,"props":354,"children":355},{},[356,358,367,369,375],{"type":37,"value":357},"Si tu n'as pas construit une ",{"type":32,"tag":359,"props":360,"children":364},"a",{"href":361,"rel":362},"https:\u002F\u002Fwww.roibase.com.tr\u002Ffr\u002Ffirstparty",[363],"nofollow",[365],{"type":37,"value":366},"architecture de données propriétaires",{"type":37,"value":368},", la collecte de ces données est difficile. GTM server-side, export brut de GA4, APIs Meta \u002F Google Ads, données de ventes du CRM — tu dois tout fusionner dans BigQuery et faire un rollup hebdomadaire. Lorsque nous construisons ce pipeline ETL avec dbt, nous produisons un tableau ",{"type":32,"tag":137,"props":370,"children":372},{"className":371},[],[373],{"type":37,"value":374},"fact_marketing_weekly",{"type":37,"value":376}," prêt pour MMM.",{"type":32,"tag":48,"props":378,"children":380},{"id":379},"configuration-de-saturation-et-adstock",[381],{"type":37,"value":382},"Configuration de saturation et adstock",{"type":32,"tag":33,"props":384,"children":385},{},[386,388,393],{"type":37,"value":387},"La force de Robyn réside dans sa capacité à optimiser ",{"type":32,"tag":40,"props":389,"children":390},{},[391],{"type":37,"value":392},"séparément",{"type":37,"value":394}," la courbe de saturation et les paramètres d'adstock pour chaque canal. La saturation est modélisée par la fonction Hill :",{"type":32,"tag":130,"props":396,"children":398},{"code":397},"effect = spend^alpha \u002F (spend^alpha + half_saturation^alpha)\n",[399],{"type":32,"tag":137,"props":400,"children":401},{"__ignoreMap":16},[402],{"type":37,"value":397},{"type":32,"tag":33,"props":404,"children":405},{},[406,408,414,416,422,424,429,431,436],{"type":37,"value":407},"Le paramètre ",{"type":32,"tag":137,"props":409,"children":411},{"className":410},[],[412],{"type":37,"value":413},"alpha",{"type":37,"value":415}," détermine la concavité de la courbe, et ",{"type":32,"tag":137,"props":417,"children":419},{"className":418},[],[420],{"type":37,"value":421},"half_saturation",{"type":37,"value":423}," le niveau de dépense auquel l'effet atteint son point médian. Les canaux basés sur l'intention comme Google Search saturent rapidement (",{"type":32,"tag":137,"props":425,"children":427},{"className":426},[],[428],{"type":37,"value":413},{"type":37,"value":430}," bas, ",{"type":32,"tag":137,"props":432,"children":434},{"className":433},[],[435],{"type":37,"value":421},{"type":37,"value":437}," bas). Les canaux de sensibilisation de marque (TV, YouTube) saturent tard.",{"type":32,"tag":33,"props":439,"children":440},{},[441],{"type":37,"value":442},"L'adstock modélise l'impact des dépenses passées sur l'effet actuel. L'adstock géométrique est la forme la plus courante :",{"type":32,"tag":130,"props":444,"children":446},{"code":445},"adstocked_spend[t] = spend[t] + theta * adstocked_spend[t-1]\n",[447],{"type":32,"tag":137,"props":448,"children":449},{"__ignoreMap":16},[450],{"type":37,"value":445},{"type":32,"tag":33,"props":452,"children":453},{},[454,455,461,463,468],{"type":37,"value":407},{"type":32,"tag":137,"props":456,"children":458},{"className":457},[],[459],{"type":37,"value":460},"theta",{"type":37,"value":462}," (entre 0 et 1) représente la vitesse de décroissance. Pour la TV, theta est élevé (0,7 à 0,9 — l'effet perdure pendant des semaines), pour la search c'est bas (0,1 à 0,3 — l'effet s'éteint rapidement). Robyn trouve ces paramètres via optimisation Nevergrad, mais tu dois fournir une ",{"type":32,"tag":40,"props":464,"children":465},{},[466],{"type":37,"value":467},"plage préalable",{"type":37,"value":469}," :",{"type":32,"tag":130,"props":471,"children":473},{"code":472,"language":133,"meta":16,"className":134,"style":16},"hyperparameters \u003C- list(\n  google_search_spend_alphas = c(0.5, 1.5),\n  google_search_spend_gammas = c(0.1, 0.4), # adstock decay\n  google_search_spend_thetas = c(0, 0.3),   # adstock theta\n  meta_spend_alphas = c(0.5, 2.0),\n  meta_spend_gammas = c(0.3, 0.8),\n  meta_spend_thetas = c(0.2, 0.6),\n  tv_grp_alphas = c(1.0, 3.0),\n  tv_grp_gammas = c(0.5, 0.9),\n  tv_grp_thetas = c(0.6, 0.9)\n)\n",[474],{"type":32,"tag":137,"props":475,"children":476},{"__ignoreMap":16},[477,485,493,501,509,517,525,533,541,549,557],{"type":32,"tag":141,"props":478,"children":479},{"class":143,"line":144},[480],{"type":32,"tag":141,"props":481,"children":482},{},[483],{"type":37,"value":484},"hyperparameters \u003C- list(\n",{"type":32,"tag":141,"props":486,"children":487},{"class":143,"line":153},[488],{"type":32,"tag":141,"props":489,"children":490},{},[491],{"type":37,"value":492},"  google_search_spend_alphas = c(0.5, 1.5),\n",{"type":32,"tag":141,"props":494,"children":495},{"class":143,"line":162},[496],{"type":32,"tag":141,"props":497,"children":498},{},[499],{"type":37,"value":500},"  google_search_spend_gammas = c(0.1, 0.4), # adstock decay\n",{"type":32,"tag":141,"props":502,"children":503},{"class":143,"line":171},[504],{"type":32,"tag":141,"props":505,"children":506},{},[507],{"type":37,"value":508},"  google_search_spend_thetas = c(0, 0.3),   # adstock theta\n",{"type":32,"tag":141,"props":510,"children":511},{"class":143,"line":180},[512],{"type":32,"tag":141,"props":513,"children":514},{},[515],{"type":37,"value":516},"  meta_spend_alphas = c(0.5, 2.0),\n",{"type":32,"tag":141,"props":518,"children":519},{"class":143,"line":189},[520],{"type":32,"tag":141,"props":521,"children":522},{},[523],{"type":37,"value":524},"  meta_spend_gammas = c(0.3, 0.8),\n",{"type":32,"tag":141,"props":526,"children":527},{"class":143,"line":198},[528],{"type":32,"tag":141,"props":529,"children":530},{},[531],{"type":37,"value":532},"  meta_spend_thetas = c(0.2, 0.6),\n",{"type":32,"tag":141,"props":534,"children":535},{"class":143,"line":207},[536],{"type":32,"tag":141,"props":537,"children":538},{},[539],{"type":37,"value":540},"  tv_grp_alphas = c(1.0, 3.0),\n",{"type":32,"tag":141,"props":542,"children":543},{"class":143,"line":26},[544],{"type":32,"tag":141,"props":545,"children":546},{},[547],{"type":37,"value":548},"  tv_grp_gammas = c(0.5, 0.9),\n",{"type":32,"tag":141,"props":550,"children":551},{"class":143,"line":224},[552],{"type":32,"tag":141,"props":553,"children":554},{},[555],{"type":37,"value":556},"  tv_grp_thetas = c(0.6, 0.9)\n",{"type":32,"tag":141,"props":558,"children":559},{"class":143,"line":233},[560],{"type":32,"tag":141,"props":561,"children":562},{},[563],{"type":37,"value":239},{"type":32,"tag":33,"props":565,"children":566},{},[567],{"type":37,"value":568},"Tu dois déterminer ces plages en utilisant ton expertise métier. Si tu les définis entièrement au hasard, le modèle diverge ou trouve des coefficients absurdes (par exemple, un impact négatif de la TV). La documentation de Robyn propose des plages par défaut, mais teste-les sur tes données avant de les appliquer.",{"type":32,"tag":48,"props":570,"children":572},{"id":571},"entraînement-du-modèle-et-validation-holdout",[573],{"type":37,"value":574},"Entraînement du modèle et validation holdout",{"type":32,"tag":33,"props":576,"children":577},{},[578,580,586,588,593],{"type":37,"value":579},"Pour exécuter Robyn, tu utilises la fonction ",{"type":32,"tag":137,"props":581,"children":583},{"className":582},[],[584],{"type":37,"value":585},"robyn_run()",{"type":37,"value":587},". À l'intérieur, la bibliothèque ",{"type":32,"tag":40,"props":589,"children":590},{},[591],{"type":37,"value":592},"Nevergrad",{"type":37,"value":594}," recherche la meilleure combinaison d'hyperparamètres via optimisation bayésienne. Une exécution typique représente 2 000 itérations x 10 essais = 20 000 entraînements de modèle. Sur un MacBook M1 avec 8 cœurs, cela prend environ 15 minutes.",{"type":32,"tag":130,"props":596,"children":598},{"code":597,"language":133,"meta":16,"className":134,"style":16},"library(Robyn)\n\nInputCollect \u003C- robyn_inputs(\n  dt_input = df,\n  date_var = \"DATE\",\n  dep_var = \"revenue\",\n  dep_var_type = \"revenue\",\n  paid_media_vars = c(\"google_search_spend\", \"meta_spend\", \"tiktok_spend\"),\n  paid_media_spends = c(\"google_search_spend\", \"meta_spend\", \"tiktok_spend\"),\n  organic_vars = c(\"organic_sessions\"),\n  prophet_vars = c(\"trend\", \"season\", \"holiday\"),\n  window_start = \"2024-01-01\",\n  window_end = \"2025-12-31\",\n  adstock = \"geometric\",\n  hyperparameters = hyperparameters\n)\n\nOutputModels \u003C- robyn_run(\n  InputCollect = InputCollect,\n  iterations = 2000,\n  trials = 10,\n  outputs = FALSE\n)\n",[599],{"type":32,"tag":137,"props":600,"children":601},{"__ignoreMap":16},[602,610,619,627,635,643,651,659,667,675,683,691,700,709,718,727,735,743,752,761,770,779,788],{"type":32,"tag":141,"props":603,"children":604},{"class":143,"line":144},[605],{"type":32,"tag":141,"props":606,"children":607},{},[608],{"type":37,"value":609},"library(Robyn)\n",{"type":32,"tag":141,"props":611,"children":612},{"class":143,"line":153},[613],{"type":32,"tag":141,"props":614,"children":616},{"emptyLinePlaceholder":615},true,[617],{"type":37,"value":618},"\n",{"type":32,"tag":141,"props":620,"children":621},{"class":143,"line":162},[622],{"type":32,"tag":141,"props":623,"children":624},{},[625],{"type":37,"value":626},"InputCollect \u003C- robyn_inputs(\n",{"type":32,"tag":141,"props":628,"children":629},{"class":143,"line":171},[630],{"type":32,"tag":141,"props":631,"children":632},{},[633],{"type":37,"value":634},"  dt_input = df,\n",{"type":32,"tag":141,"props":636,"children":637},{"class":143,"line":180},[638],{"type":32,"tag":141,"props":639,"children":640},{},[641],{"type":37,"value":642},"  date_var = \"DATE\",\n",{"type":32,"tag":141,"props":644,"children":645},{"class":143,"line":189},[646],{"type":32,"tag":141,"props":647,"children":648},{},[649],{"type":37,"value":650},"  dep_var = \"revenue\",\n",{"type":32,"tag":141,"props":652,"children":653},{"class":143,"line":198},[654],{"type":32,"tag":141,"props":655,"children":656},{},[657],{"type":37,"value":658},"  dep_var_type = \"revenue\",\n",{"type":32,"tag":141,"props":660,"children":661},{"class":143,"line":207},[662],{"type":32,"tag":141,"props":663,"children":664},{},[665],{"type":37,"value":666},"  paid_media_vars = c(\"google_search_spend\", \"meta_spend\", \"tiktok_spend\"),\n",{"type":32,"tag":141,"props":668,"children":669},{"class":143,"line":26},[670],{"type":32,"tag":141,"props":671,"children":672},{},[673],{"type":37,"value":674},"  paid_media_spends = c(\"google_search_spend\", \"meta_spend\", \"tiktok_spend\"),\n",{"type":32,"tag":141,"props":676,"children":677},{"class":143,"line":224},[678],{"type":32,"tag":141,"props":679,"children":680},{},[681],{"type":37,"value":682},"  organic_vars = c(\"organic_sessions\"),\n",{"type":32,"tag":141,"props":684,"children":685},{"class":143,"line":233},[686],{"type":32,"tag":141,"props":687,"children":688},{},[689],{"type":37,"value":690},"  prophet_vars = c(\"trend\", \"season\", \"holiday\"),\n",{"type":32,"tag":141,"props":692,"children":694},{"class":143,"line":693},12,[695],{"type":32,"tag":141,"props":696,"children":697},{},[698],{"type":37,"value":699},"  window_start = \"2024-01-01\",\n",{"type":32,"tag":141,"props":701,"children":703},{"class":143,"line":702},13,[704],{"type":32,"tag":141,"props":705,"children":706},{},[707],{"type":37,"value":708},"  window_end = \"2025-12-31\",\n",{"type":32,"tag":141,"props":710,"children":712},{"class":143,"line":711},14,[713],{"type":32,"tag":141,"props":714,"children":715},{},[716],{"type":37,"value":717},"  adstock = \"geometric\",\n",{"type":32,"tag":141,"props":719,"children":721},{"class":143,"line":720},15,[722],{"type":32,"tag":141,"props":723,"children":724},{},[725],{"type":37,"value":726},"  hyperparameters = hyperparameters\n",{"type":32,"tag":141,"props":728,"children":730},{"class":143,"line":729},16,[731],{"type":32,"tag":141,"props":732,"children":733},{},[734],{"type":37,"value":239},{"type":32,"tag":141,"props":736,"children":738},{"class":143,"line":737},17,[739],{"type":32,"tag":141,"props":740,"children":741},{"emptyLinePlaceholder":615},[742],{"type":37,"value":618},{"type":32,"tag":141,"props":744,"children":746},{"class":143,"line":745},18,[747],{"type":32,"tag":141,"props":748,"children":749},{},[750],{"type":37,"value":751},"OutputModels \u003C- robyn_run(\n",{"type":32,"tag":141,"props":753,"children":755},{"class":143,"line":754},19,[756],{"type":32,"tag":141,"props":757,"children":758},{},[759],{"type":37,"value":760},"  InputCollect = InputCollect,\n",{"type":32,"tag":141,"props":762,"children":764},{"class":143,"line":763},20,[765],{"type":32,"tag":141,"props":766,"children":767},{},[768],{"type":37,"value":769},"  iterations = 2000,\n",{"type":32,"tag":141,"props":771,"children":773},{"class":143,"line":772},21,[774],{"type":32,"tag":141,"props":775,"children":776},{},[777],{"type":37,"value":778},"  trials = 10,\n",{"type":32,"tag":141,"props":780,"children":782},{"class":143,"line":781},22,[783],{"type":32,"tag":141,"props":784,"children":785},{},[786],{"type":37,"value":787},"  outputs = FALSE\n",{"type":32,"tag":141,"props":789,"children":791},{"class":143,"line":790},23,[792],{"type":32,"tag":141,"props":793,"children":794},{},[795],{"type":37,"value":239},{"type":32,"tag":33,"props":797,"children":798},{},[799,801,806,808,813,815,820],{"type":37,"value":800},"Une fois le modèle entraîné, il affiche les solutions ",{"type":32,"tag":40,"props":802,"children":803},{},[804],{"type":37,"value":805},"Pareto-optimales",{"type":37,"value":807},". Robyn optimise deux métriques : NRMSE (",{"type":32,"tag":60,"props":809,"children":810},{},[811],{"type":37,"value":812},"normalized root mean square error",{"type":37,"value":814},") et decomposition RSSD (",{"type":32,"tag":60,"props":816,"children":817},{},[818],{"type":37,"value":819},"residual sum of squared differences",{"type":37,"value":821},"). Chaque modèle sur la frontière de Pareto représente un compromis : l'un ajuste bien mais a une mauvaise décomposition, l'autre l'inverse. Tu dois sélectionner manuellement le modèle le plus raisonnable.",{"type":32,"tag":33,"props":823,"children":824},{},[825],{"type":37,"value":826},"Pour la validation holdout, tu réserves les 4 à 8 dernières semaines. Robyn le fait automatiquement :",{"type":32,"tag":130,"props":828,"children":830},{"code":829,"language":133,"meta":16,"className":134,"style":16},"robyn_refresh(\n  robyn_object = OutputModels,\n  dt_input = df_new, # Actualiser avec nouvelles données\n  refresh_steps = 4,\n  refresh_mode = \"manual\"\n)\n",[831],{"type":32,"tag":137,"props":832,"children":833},{"__ignoreMap":16},[834,842,850,858,866,874],{"type":32,"tag":141,"props":835,"children":836},{"class":143,"line":144},[837],{"type":32,"tag":141,"props":838,"children":839},{},[840],{"type":37,"value":841},"robyn_refresh(\n",{"type":32,"tag":141,"props":843,"children":844},{"class":143,"line":153},[845],{"type":32,"tag":141,"props":846,"children":847},{},[848],{"type":37,"value":849},"  robyn_object = OutputModels,\n",{"type":32,"tag":141,"props":851,"children":852},{"class":143,"line":162},[853],{"type":32,"tag":141,"props":854,"children":855},{},[856],{"type":37,"value":857},"  dt_input = df_new, # Actualiser avec nouvelles données\n",{"type":32,"tag":141,"props":859,"children":860},{"class":143,"line":171},[861],{"type":32,"tag":141,"props":862,"children":863},{},[864],{"type":37,"value":865},"  refresh_steps = 4,\n",{"type":32,"tag":141,"props":867,"children":868},{"class":143,"line":180},[869],{"type":32,"tag":141,"props":870,"children":871},{},[872],{"type":37,"value":873},"  refresh_mode = \"manual\"\n",{"type":32,"tag":141,"props":875,"children":876},{"class":143,"line":189},[877],{"type":32,"tag":141,"props":878,"children":879},{},[880],{"type":37,"value":239},{"type":32,"tag":33,"props":882,"children":883},{},[884,886,891],{"type":37,"value":885},"Si le MAPE (",{"type":32,"tag":60,"props":887,"children":888},{},[889],{"type":37,"value":890},"mean absolute percentage error",{"type":37,"value":892},") holdout est inférieur à 10 %, le modèle est considéré comme fiable. Au-delà de 20 %, c'est dangereux — signe d'overfitting ou de variables manquantes.",{"type":32,"tag":48,"props":894,"children":896},{"id":895},"interprétation-des-résultats-et-optimisation-budgétaire",[897],{"type":37,"value":898},"Interprétation des résultats et optimisation budgétaire",{"type":32,"tag":33,"props":900,"children":901},{},[902,904,909,911,916,918,923],{"type":37,"value":903},"Le résultat le plus critique de Robyn est le tableau de ",{"type":32,"tag":40,"props":905,"children":906},{},[907],{"type":37,"value":908},"contribution par canal",{"type":37,"value":910},". Il affiche le pourcentage de contribution au chiffre d'affaires et le ",{"type":32,"tag":40,"props":912,"children":913},{},[914],{"type":37,"value":915},"ROAS",{"type":37,"value":917}," de chaque canal. Mais attention : ces valeurs de ROAS historiques ne sont pas le ROAS ",{"type":32,"tag":40,"props":919,"children":920},{},[921],{"type":37,"value":922},"marginal",{"type":37,"value":924},". Le ROAS marginal indique le revenu supplémentaire généré par les 1 000 € suivants dépensés et se calcule par la dérivée de la courbe de saturation.",{"type":32,"tag":33,"props":926,"children":927},{},[928,930,936,938,943],{"type":37,"value":929},"La fonction ",{"type":32,"tag":137,"props":931,"children":933},{"className":932},[],[934],{"type":37,"value":935},"budget_allocator()",{"type":37,"value":937}," de Robyn redistribue le budget courant en fonction des courbes de saturation. Si Google Search est saturé, elle transfère le budget excédentaire vers Meta ou TikTok. Cette optimisation trouve le point sur la ",{"type":32,"tag":40,"props":939,"children":940},{},[941],{"type":37,"value":942},"courbe de réponse",{"type":37,"value":944}," où le rendement marginal s'équilibre (économie 101 : MR₁ = MR₂).",{"type":32,"tag":130,"props":946,"children":948},{"code":947,"language":133,"meta":16,"className":134,"style":16},"AllocatorCollect \u003C- robyn_allocator(\n  robyn_object = OutputModels,\n  select_model = \"1_100_2\", # ID du modèle sélectionné depuis Pareto\n  scenario = \"max_response_expected_spend\",\n  channel_constr_low = c(0.7, 0.7, 0.5), # Au moins 70 % Google, 70 % Meta, 50 % TikTok\n  channel_constr_up = c(1.5, 2.0, 3.0),  # Limites d'augmentation maximale\n  expected_spend = 100000\n)\n",[949],{"type":32,"tag":137,"props":950,"children":951},{"__ignoreMap":16},[952,960,967,975,983,991,999,1007],{"type":32,"tag":141,"props":953,"children":954},{"class":143,"line":144},[955],{"type":32,"tag":141,"props":956,"children":957},{},[958],{"type":37,"value":959},"AllocatorCollect \u003C- robyn_allocator(\n",{"type":32,"tag":141,"props":961,"children":962},{"class":143,"line":153},[963],{"type":32,"tag":141,"props":964,"children":965},{},[966],{"type":37,"value":849},{"type":32,"tag":141,"props":968,"children":969},{"class":143,"line":162},[970],{"type":32,"tag":141,"props":971,"children":972},{},[973],{"type":37,"value":974},"  select_model = \"1_100_2\", # ID du modèle sélectionné depuis Pareto\n",{"type":32,"tag":141,"props":976,"children":977},{"class":143,"line":171},[978],{"type":32,"tag":141,"props":979,"children":980},{},[981],{"type":37,"value":982},"  scenario = \"max_response_expected_spend\",\n",{"type":32,"tag":141,"props":984,"children":985},{"class":143,"line":180},[986],{"type":32,"tag":141,"props":987,"children":988},{},[989],{"type":37,"value":990},"  channel_constr_low = c(0.7, 0.7, 0.5), # Au moins 70 % Google, 70 % Meta, 50 % TikTok\n",{"type":32,"tag":141,"props":992,"children":993},{"class":143,"line":189},[994],{"type":32,"tag":141,"props":995,"children":996},{},[997],{"type":37,"value":998},"  channel_constr_up = c(1.5, 2.0, 3.0),  # Limites d'augmentation maximale\n",{"type":32,"tag":141,"props":1000,"children":1001},{"class":143,"line":198},[1002],{"type":32,"tag":141,"props":1003,"children":1004},{},[1005],{"type":37,"value":1006},"  expected_spend = 100000\n",{"type":32,"tag":141,"props":1008,"children":1009},{"class":143,"line":207},[1010],{"type":32,"tag":141,"props":1011,"children":1012},{},[1013],{"type":37,"value":239},{"type":32,"tag":33,"props":1015,"children":1016},{},[1017,1019,1024],{"type":37,"value":1018},"Le résultat montre comment distribuer ton budget de 100 000 € pour maximiser le revenu. Mais c'est une recommandation statique — en réalité, le renouvellement créatif, l'activité concurrentielle et la saisonnalité changent. C'est pourquoi tu dois ",{"type":32,"tag":40,"props":1020,"children":1021},{},[1022],{"type":37,"value":1023},"rafraîchir MMM chaque mois",{"type":37,"value":1025},".",{"type":32,"tag":48,"props":1027,"children":1029},{"id":1028},"compromis-et-limites",[1030],{"type":37,"value":1031},"Compromis et limites",{"type":32,"tag":33,"props":1033,"children":1034},{},[1035,1037,1042,1044,1049],{"type":37,"value":1036},"Contrairement à l'attribution, MMM fonctionne au niveau ",{"type":32,"tag":40,"props":1038,"children":1039},{},[1040],{"type":37,"value":1041},"agrégé",{"type":37,"value":1043},". Il ne peut pas être utilisé pour la personnalisation. Dans Google Search, Robyn ne peut pas te dire quel mot-clé performe mieux — il mesure seulement la contribution totale de Search. De plus, le modèle est exposé au problème ",{"type":32,"tag":40,"props":1045,"children":1046},{},[1047],{"type":37,"value":1048},"corrélation ≠ causalité",{"type":37,"value":1050}," : si les ventes augmentent en été et que tu augmentes aussi les dépenses TV en été, le modèle peut surévaluer la contribution de la TV.",{"type":32,"tag":33,"props":1052,"children":1053},{},[1054,1056,1061,1063,1069,1071,1076],{"type":37,"value":1055},"Pour résoudre ce problème, tu dois ",{"type":32,"tag":40,"props":1057,"children":1058},{},[1059],{"type":37,"value":1060},"valider MMM avec un test d'incrémentalité",{"type":37,"value":1062},". Un test geo-lift ou holdout mesure le véritable impact causal et le compare aux résultats de MMM. Robyn peut intégrer les résultats d'incrémentalité en tant que paramètre ",{"type":32,"tag":137,"props":1064,"children":1066},{"className":1065},[],[1067],{"type":37,"value":1068},"calibration",{"type":37,"value":1070}," — cela fonctionne comme un ",{"type":32,"tag":60,"props":1072,"children":1073},{},[1074],{"type":37,"value":1075},"prior",{"type":37,"value":1077}," bayésien et rapproche le modèle de la réalité.",{"type":32,"tag":33,"props":1079,"children":1080},{},[1081,1083,1088,1090,1094],{"type":37,"value":1082},"Un autre défi : ",{"type":32,"tag":40,"props":1084,"children":1085},{},[1086],{"type":37,"value":1087},"ajouter de nouveaux canaux",{"type":37,"value":1089}," au modèle. Si tu ouvres un nouveau canal (par exemple Snapchat) avec seulement 8 semaines de données, Robyn ne peut pas apprendre sa courbe de saturation. Tu devras soit définir un ",{"type":32,"tag":60,"props":1091,"children":1092},{},[1093],{"type":37,"value":1075},{"type":37,"value":1095}," manuel, soit exclure ce canal pendant les 12 premières semaines avant de l'ajouter.",{"type":32,"tag":33,"props":1097,"children":1098},{},[1099,1101,1106,1108,1113],{"type":37,"value":1100},"Enfin, MMM est ",{"type":32,"tag":40,"props":1102,"children":1103},{},[1104],{"type":37,"value":1105},"le plus puissant quand il combine l'hors ligne et l'en ligne",{"type":37,"value":1107},". Si tu n'inclus pas dans le modèle les dépenses de canaux hors ligne (TV, affichage, sponsorships), le modèle surattribue aux canaux en ligne (",{"type":32,"tag":60,"props":1109,"children":1110},{},[1111],{"type":37,"value":1112},"omitted variable bias",{"type":37,"value":1114},"). Robyn est flexible : il accepte des variables proxy comme GRP, reach, ou même le volume de recherche de marque.",{"type":32,"tag":33,"props":1116,"children":1117},{},[1118],{"type":37,"value":1119},"Un pipeline MMM correctement conçu transforme la planification budgétaire du marketing — de la devinette à l'ingénierie basée sur la preuve. Robyn rend cette transformation accessible en open-source — mais la structure des données, le tuning des hyperparamètres et la validation d'incrémentalité requièrent une expertise humaine. Les équipes marketing qui investissent dans la régression économétrique plutôt que dans l'attribution au lieu des cookies auront un avantage de 12 mois sur leurs concurrents en 2027.",{"type":32,"tag":1121,"props":1122,"children":1123},"style",{},[1124],{"type":37,"value":1125},"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":16,"searchDepth":162,"depth":162,"links":1127},[1128,1129,1130,1131,1132,1133],{"id":50,"depth":153,"text":53},{"id":120,"depth":153,"text":123},{"id":379,"depth":153,"text":382},{"id":571,"depth":153,"text":574},{"id":895,"depth":153,"text":898},{"id":1028,"depth":153,"text":1031},"markdown","content:fr:data:robyn-marketing-mix-modeling-guide.md","content","fr\u002Fdata\u002Frobyn-marketing-mix-modeling-guide.md","fr\u002Fdata\u002Frobyn-marketing-mix-modeling-guide","md",1782079494111]