[{"data":1,"prerenderedAt":2046},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fde\u002Fdata\u002Fmarketing-mix-modeling-robyn-practical-setup":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":2040,"_id":2041,"_source":2042,"_file":2043,"_stem":2044,"_extension":2045},"\u002Fde\u002Fdata\u002Fmarketing-mix-modeling-robyn-practical-setup","data",false,"","Marketing Mix Modeling: Praktische Implementierung mit Robyn","Meta's Robyn Framework mit Sättigungskurven, Adstock-Decay und Holdout-Validierung für Attribution-Modelle. SQL, R und Production-Pipeline.","2026-06-21",[22,23,24,25,26],"marketing-mix-modeling","robyn","adstock","attribution","mmm",9,"Roibase",{"type":30,"children":31,"toc":2030},"root",[32,40,47,52,72,90,100,106,111,887,900,974,979,985,998,1188,1196,1231,1236,1242,1304,1315,1328,1492,1497,1544,1550,1555,1675,1680,1686,1699,1760,1765,1801,1806,1812,1828,1933,1938,1987,1992,1998,2011,2024],{"type":33,"tag":34,"props":35,"children":36},"element","p",{},[37],{"type":38,"value":39},"text","Cookie-Deprecation und Datenschutzbestimmungen verschieben Attribution von deterministischen Methoden zur probabilistischen Modellierung. Marketing Mix Modeling (MMM) — ein statistisches Werkzeug aus den 1960er Jahren — steht erneut im Mittelpunkt. Metas Open-Source-Framework Robyn bietet die praktische Umsetzung: Mit Bayesian Inference, Sättigungskurven und Adstock-Decay verbindest du wöchentliche Marketingausgaben mit Umsatzzielen in einem Regressionsmodell und bringst es in die Production. Dieser Beitrag zeigt dir, wie du Robyn aufbaust, echte Daten ins Modell integrierst, Hyperparameter durch Grid Search optimierst und mit Holdout-Validierung Overfitting vermeidest.",{"type":33,"tag":41,"props":42,"children":44},"h2",{"id":43},"was-ist-robyn-und-wie-unterscheidet-es-sich-von-klassischer-regression",[45],{"type":38,"value":46},"Was ist Robyn und wie unterscheidet es sich von klassischer Regression",{"type":33,"tag":34,"props":48,"children":49},{},[50],{"type":38,"value":51},"Robyn ist ein auf R basierendes Open-Source-MMM-Framework. Meta hat es 2020 für sein eigenes Marketing-Team entwickelt und 2021 veröffentlicht. Die Unterschiede zur klassischen linearen Regression:",{"type":33,"tag":34,"props":53,"children":54},{},[55,61,63,70],{"type":33,"tag":56,"props":57,"children":58},"strong",{},[59],{"type":38,"value":60},"Adstock-Transformation",{"type":38,"value":62},": Marketing-Effekte sind nicht augenblicklich — eine TV-Anzeige erzeugt Branding-Effekt über Wochen. Adstock modelliert den Beitrag früherer Ausgaben zur aktuellen Umsatzgeneration durch exponentiellen Zerfall. Robyn unterstützt geometrisches und Weibull-Adstock. Geometrisch ist einfach: ",{"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},", wobei θ der Decay-Parameter ist. Weibull ist flexibler — du kannst verzögerte Peak-Effekte positionieren.",{"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},"Sättigungskurve (Diminishing Returns)",{"type":38,"value":81},": Die Beziehung zwischen Ausgaben und Umsatz ist nicht linear. Die ersten 100.000 € könnten 80 % ROI bringen, die nächsten 100.000 € nur 40 %. Robyn nutzt Hill- und S-Kurven-Sättigungsfunktionen. Die Hill-Gleichung lautet: ",{"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},", wobei K der Halbmaximum-Punkt und n die Steigung ist. Diese Nichtlinearität ist kritisch für Channel-basierte Budget-Optimierung.",{"type":33,"tag":34,"props":91,"children":92},{},[93,98],{"type":33,"tag":56,"props":94,"children":95},{},[96],{"type":38,"value":97},"Hyperparameter-Tuning",{"type":38,"value":99},": Adstock-Decay, Sättigungs-K- und n-Werte sind unbekannt — du findest sie durch Grid Search. Robyn nutzt genetische Algorithmen (NSGAII), um Tausende von Modell-Kombinationen zu testen und dir die beste Pareto-Trade-off auszuwählen.",{"type":33,"tag":41,"props":101,"children":103},{"id":102},"datenvorbereitung-sql-zu-wöchentlicher-granularität",[104],{"type":38,"value":105},"Datenvorbereitung: SQL zu wöchentlicher Granularität",{"type":33,"tag":34,"props":107,"children":108},{},[109],{"type":38,"value":110},"Robyn arbeitet mit wöchentlicher Granularität. Du aggregierst aus täglichen Transaction-Logs wöchentlich Media Spend und Revenue. Beispiel BigQuery-Abfrage:",{"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,272,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":266},{"class":124,"line":265},8,[267],{"type":33,"tag":122,"props":268,"children":269},{"style":135},[270],{"type":38,"value":271},"),\n",{"type":33,"tag":122,"props":273,"children":274},{"class":124,"line":27},[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},"Diese Abfrage erzeugt pro Zeile 1 Woche, 1 Umsatz und N Channel-Spend-Spalten. Du kannst Robyn die CSV-Datei übergeben, aber in Production ist das Ziehen direkt von BigQuery nach R sauberer. Mit dem ",{"type":33,"tag":64,"props":893,"children":895},{"className":894},[],[896],{"type":38,"value":897},"bigrquery",{"type":38,"value":899}," Paket:",{"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":265},[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},"Minimale Datenanforderung: 104 Wochen (2 Jahre). Weniger Daten führt zu Overfitting. Robyn's Bayesian Priors funktionieren mit 52 Wochen, aber 104+ Wochen erfassen Saisonalität besser.",{"type":33,"tag":41,"props":980,"children":982},{"id":981},"modell-setup-robyn_inputs-und-hyperparameter-grid",[983],{"type":38,"value":984},"Modell-Setup: robyn_inputs und Hyperparameter-Grid",{"type":33,"tag":34,"props":986,"children":987},{},[988,990,996],{"type":38,"value":989},"Robyn erstellt mit ",{"type":33,"tag":64,"props":991,"children":993},{"className":992},[],[994],{"type":38,"value":995},"robyn_inputs()",{"type":38,"value":997}," ein Config-Objekt:",{"type":33,"tag":112,"props":999,"children":1001},{"className":902,"code":1000,"language":904,"meta":17,"style":17},"InputCollect \u003C- robyn_inputs(\n  dt_input = df_input,\n  date_var = \"week_start\",\n  dep_var = \"revenue\",\n  dep_var_type = \"revenue\",\n  paid_media_spends = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n  paid_media_vars = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n  context_vars = c(\"competitor_index\", \"seasonality\"),\n  window_start = \"2024-01-01\",\n  window_end = \"2026-06-14\",\n  adstock = \"geometric\",\n  hyperparameters = list(\n    google_search_spend_alphas = c(0.5, 3),\n    google_search_spend_gammas = c(0.3, 1),\n    google_search_spend_thetas = c(0, 0.3),\n    meta_paid_social_spend_alphas = c(0.5, 3),\n    meta_paid_social_spend_gammas = c(0.3, 1),\n    meta_paid_social_spend_thetas = c(0, 0.5),\n    tv_spend_alphas = c(0.5, 3),\n    tv_spend_gammas = c(0.3, 1),\n    tv_spend_thetas = c(0.1, 0.7)\n  )\n)\n",[1002],{"type":33,"tag":64,"props":1003,"children":1004},{"__ignoreMap":17},[1005,1013,1021,1029,1037,1045,1053,1061,1069,1077,1085,1093,1101,1109,1117,1125,1133,1141,1149,1157,1165,1173,1181],{"type":33,"tag":122,"props":1006,"children":1007},{"class":124,"line":125},[1008],{"type":33,"tag":122,"props":1009,"children":1010},{},[1011],{"type":38,"value":1012},"InputCollect \u003C- robyn_inputs(\n",{"type":33,"tag":122,"props":1014,"children":1015},{"class":124,"line":151},[1016],{"type":33,"tag":122,"props":1017,"children":1018},{},[1019],{"type":38,"value":1020},"  dt_input = df_input,\n",{"type":33,"tag":122,"props":1022,"children":1023},{"class":124,"line":160},[1024],{"type":33,"tag":122,"props":1025,"children":1026},{},[1027],{"type":38,"value":1028},"  date_var = \"week_start\",\n",{"type":33,"tag":122,"props":1030,"children":1031},{"class":124,"line":188},[1032],{"type":33,"tag":122,"props":1033,"children":1034},{},[1035],{"type":38,"value":1036},"  dep_var = \"revenue\",\n",{"type":33,"tag":122,"props":1038,"children":1039},{"class":124,"line":212},[1040],{"type":33,"tag":122,"props":1041,"children":1042},{},[1043],{"type":38,"value":1044},"  dep_var_type = \"revenue\",\n",{"type":33,"tag":122,"props":1046,"children":1047},{"class":124,"line":227},[1048],{"type":33,"tag":122,"props":1049,"children":1050},{},[1051],{"type":38,"value":1052},"  paid_media_spends = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n",{"type":33,"tag":122,"props":1054,"children":1055},{"class":124,"line":251},[1056],{"type":33,"tag":122,"props":1057,"children":1058},{},[1059],{"type":38,"value":1060},"  paid_media_vars = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n",{"type":33,"tag":122,"props":1062,"children":1063},{"class":124,"line":265},[1064],{"type":33,"tag":122,"props":1065,"children":1066},{},[1067],{"type":38,"value":1068},"  context_vars = c(\"competitor_index\", \"seasonality\"),\n",{"type":33,"tag":122,"props":1070,"children":1071},{"class":124,"line":27},[1072],{"type":33,"tag":122,"props":1073,"children":1074},{},[1075],{"type":38,"value":1076},"  window_start = \"2024-01-01\",\n",{"type":33,"tag":122,"props":1078,"children":1079},{"class":124,"line":290},[1080],{"type":33,"tag":122,"props":1081,"children":1082},{},[1083],{"type":38,"value":1084},"  window_end = \"2026-06-14\",\n",{"type":33,"tag":122,"props":1086,"children":1087},{"class":124,"line":298},[1088],{"type":33,"tag":122,"props":1089,"children":1090},{},[1091],{"type":38,"value":1092},"  adstock = \"geometric\",\n",{"type":33,"tag":122,"props":1094,"children":1095},{"class":124,"line":333},[1096],{"type":33,"tag":122,"props":1097,"children":1098},{},[1099],{"type":38,"value":1100},"  hyperparameters = list(\n",{"type":33,"tag":122,"props":1102,"children":1103},{"class":124,"line":342},[1104],{"type":33,"tag":122,"props":1105,"children":1106},{},[1107],{"type":38,"value":1108},"    google_search_spend_alphas = c(0.5, 3),\n",{"type":33,"tag":122,"props":1110,"children":1111},{"class":124,"line":364},[1112],{"type":33,"tag":122,"props":1113,"children":1114},{},[1115],{"type":38,"value":1116},"    google_search_spend_gammas = c(0.3, 1),\n",{"type":33,"tag":122,"props":1118,"children":1119},{"class":124,"line":377},[1120],{"type":33,"tag":122,"props":1121,"children":1122},{},[1123],{"type":38,"value":1124},"    google_search_spend_thetas = c(0, 0.3),\n",{"type":33,"tag":122,"props":1126,"children":1127},{"class":124,"line":399},[1128],{"type":33,"tag":122,"props":1129,"children":1130},{},[1131],{"type":38,"value":1132},"    meta_paid_social_spend_alphas = c(0.5, 3),\n",{"type":33,"tag":122,"props":1134,"children":1135},{"class":124,"line":421},[1136],{"type":33,"tag":122,"props":1137,"children":1138},{},[1139],{"type":38,"value":1140},"    meta_paid_social_spend_gammas = c(0.3, 1),\n",{"type":33,"tag":122,"props":1142,"children":1143},{"class":124,"line":430},[1144],{"type":33,"tag":122,"props":1145,"children":1146},{},[1147],{"type":38,"value":1148},"    meta_paid_social_spend_thetas = c(0, 0.5),\n",{"type":33,"tag":122,"props":1150,"children":1151},{"class":124,"line":439},[1152],{"type":33,"tag":122,"props":1153,"children":1154},{},[1155],{"type":38,"value":1156},"    tv_spend_alphas = c(0.5, 3),\n",{"type":33,"tag":122,"props":1158,"children":1159},{"class":124,"line":463},[1160],{"type":33,"tag":122,"props":1161,"children":1162},{},[1163],{"type":38,"value":1164},"    tv_spend_gammas = c(0.3, 1),\n",{"type":33,"tag":122,"props":1166,"children":1167},{"class":124,"line":484},[1168],{"type":33,"tag":122,"props":1169,"children":1170},{},[1171],{"type":38,"value":1172},"    tv_spend_thetas = c(0.1, 0.7)\n",{"type":33,"tag":122,"props":1174,"children":1175},{"class":124,"line":534},[1176],{"type":33,"tag":122,"props":1177,"children":1178},{},[1179],{"type":38,"value":1180},"  )\n",{"type":33,"tag":122,"props":1182,"children":1183},{"class":124,"line":580},[1184],{"type":33,"tag":122,"props":1185,"children":1186},{},[1187],{"type":38,"value":427},{"type":33,"tag":34,"props":1189,"children":1190},{},[1191],{"type":33,"tag":56,"props":1192,"children":1193},{},[1194],{"type":38,"value":1195},"Hyperparameter-Erklärungen:",{"type":33,"tag":1197,"props":1198,"children":1199},"ul",{},[1200,1211,1221],{"type":33,"tag":1201,"props":1202,"children":1203},"li",{},[1204,1209],{"type":33,"tag":56,"props":1205,"children":1206},{},[1207],{"type":38,"value":1208},"alpha",{"type":38,"value":1210},": Slope-Parameter der Hill-Sättigungsfunktion (n). Höheres Alpha = spätere Sättigung.",{"type":33,"tag":1201,"props":1212,"children":1213},{},[1214,1219],{"type":33,"tag":56,"props":1215,"children":1216},{},[1217],{"type":38,"value":1218},"gamma",{"type":38,"value":1220},": K-Parameter der Hill-Funktion — Halbmaximum-Punkt. Niedriges Gamma = frühe Sättigung.",{"type":33,"tag":1201,"props":1222,"children":1223},{},[1224,1229],{"type":33,"tag":56,"props":1225,"children":1226},{},[1227],{"type":38,"value":1228},"theta",{"type":38,"value":1230},": Geometric Adstock Decay. 0 = Effekt endet sofort, 0.7 = 70 % werden in die nächste Woche getragen.",{"type":33,"tag":34,"props":1232,"children":1233},{},[1234],{"type":38,"value":1235},"Du definierst Min-Max-Bereiche pro Channel. Robyn führt Grid Search in diesen Bereichen durch. Für TV ist die obere Theta-Grenze 0.7 — der Awareness-Effekt wirkt lange nach. Für Paid Search ist sie 0.3 — Conversions sind kurzfristig.",{"type":33,"tag":41,"props":1237,"children":1239},{"id":1238},"modell-lauf-robyn_run-und-pareto-optimierung",[1240],{"type":38,"value":1241},"Modell-Lauf: robyn_run und Pareto-Optimierung",{"type":33,"tag":112,"props":1243,"children":1245},{"className":902,"code":1244,"language":904,"meta":17,"style":17},"OutputModels \u003C- robyn_run(\n  InputCollect = InputCollect,\n  cores = 8,\n  iterations = 2000,\n  trials = 5,\n  outputs = FALSE\n)\n",[1246],{"type":33,"tag":64,"props":1247,"children":1248},{"__ignoreMap":17},[1249,1257,1265,1273,1281,1289,1297],{"type":33,"tag":122,"props":1250,"children":1251},{"class":124,"line":125},[1252],{"type":33,"tag":122,"props":1253,"children":1254},{},[1255],{"type":38,"value":1256},"OutputModels \u003C- robyn_run(\n",{"type":33,"tag":122,"props":1258,"children":1259},{"class":124,"line":151},[1260],{"type":33,"tag":122,"props":1261,"children":1262},{},[1263],{"type":38,"value":1264},"  InputCollect = InputCollect,\n",{"type":33,"tag":122,"props":1266,"children":1267},{"class":124,"line":160},[1268],{"type":33,"tag":122,"props":1269,"children":1270},{},[1271],{"type":38,"value":1272},"  cores = 8,\n",{"type":33,"tag":122,"props":1274,"children":1275},{"class":124,"line":188},[1276],{"type":33,"tag":122,"props":1277,"children":1278},{},[1279],{"type":38,"value":1280},"  iterations = 2000,\n",{"type":33,"tag":122,"props":1282,"children":1283},{"class":124,"line":212},[1284],{"type":33,"tag":122,"props":1285,"children":1286},{},[1287],{"type":38,"value":1288},"  trials = 5,\n",{"type":33,"tag":122,"props":1290,"children":1291},{"class":124,"line":227},[1292],{"type":33,"tag":122,"props":1293,"children":1294},{},[1295],{"type":38,"value":1296},"  outputs = FALSE\n",{"type":33,"tag":122,"props":1298,"children":1299},{"class":124,"line":251},[1300],{"type":33,"tag":122,"props":1301,"children":1302},{},[1303],{"type":38,"value":427},{"type":33,"tag":34,"props":1305,"children":1306},{},[1307,1313],{"type":33,"tag":64,"props":1308,"children":1310},{"className":1309},[],[1311],{"type":38,"value":1312},"robyn_run()",{"type":38,"value":1314}," testet über 2000 Iterationen Hyperparameter-Kombinationen mit genetischen Algorithmen. In jeder Iteration werden NRMSE (normalized root mean squared error) und DECOMP.RSSD (decomposition residual sum of squares difference) minimiert. Aus der Pareto-Frontier werden 5 Modelle ausgewählt — ein Trade-off zwischen Fit-Qualität und Business-Logik (z.B. TV-ROI sollte nicht höher als Search-ROI sein).",{"type":33,"tag":34,"props":1316,"children":1317},{},[1318,1320,1326],{"type":38,"value":1319},"Das Output-Objekt enthält die Tabelle ",{"type":33,"tag":64,"props":1321,"children":1323},{"className":1322},[],[1324],{"type":38,"value":1325},"df_allpareto",{"type":38,"value":1327}," — jedes Modell mit Channel-Level-ROI, ROAS und CPA. Zeilenzahl = iterations × trials. Die wichtigsten Spalten:",{"type":33,"tag":1329,"props":1330,"children":1331},"table",{},[1332,1351],{"type":33,"tag":1333,"props":1334,"children":1335},"thead",{},[1336],{"type":33,"tag":1337,"props":1338,"children":1339},"tr",{},[1340,1346],{"type":33,"tag":1341,"props":1342,"children":1343},"th",{},[1344],{"type":38,"value":1345},"Spalte",{"type":33,"tag":1341,"props":1347,"children":1348},{},[1349],{"type":38,"value":1350},"Bedeutung",{"type":33,"tag":1352,"props":1353,"children":1354},"tbody",{},[1355,1373,1390,1407,1424,1441,1458,1475],{"type":33,"tag":1337,"props":1356,"children":1357},{},[1358,1368],{"type":33,"tag":1359,"props":1360,"children":1361},"td",{},[1362],{"type":33,"tag":64,"props":1363,"children":1365},{"className":1364},[],[1366],{"type":38,"value":1367},"solID",{"type":33,"tag":1359,"props":1369,"children":1370},{},[1371],{"type":38,"value":1372},"Modell-ID",{"type":33,"tag":1337,"props":1374,"children":1375},{},[1376,1385],{"type":33,"tag":1359,"props":1377,"children":1378},{},[1379],{"type":33,"tag":64,"props":1380,"children":1382},{"className":1381},[],[1383],{"type":38,"value":1384},"nrmse",{"type":33,"tag":1359,"props":1386,"children":1387},{},[1388],{"type":38,"value":1389},"Normalized RMSE — niedrig = besserer Fit",{"type":33,"tag":1337,"props":1391,"children":1392},{},[1393,1402],{"type":33,"tag":1359,"props":1394,"children":1395},{},[1396],{"type":33,"tag":64,"props":1397,"children":1399},{"className":1398},[],[1400],{"type":38,"value":1401},"decomp.rssd",{"type":33,"tag":1359,"props":1403,"children":1404},{},[1405],{"type":38,"value":1406},"Decomposition RSSD — niedrig = stabile Channel-Beiträge",{"type":33,"tag":1337,"props":1408,"children":1409},{},[1410,1419],{"type":33,"tag":1359,"props":1411,"children":1412},{},[1413],{"type":33,"tag":64,"props":1414,"children":1416},{"className":1415},[],[1417],{"type":38,"value":1418},"mape",{"type":33,"tag":1359,"props":1420,"children":1421},{},[1422],{"type":38,"value":1423},"Mean absolute percentage error",{"type":33,"tag":1337,"props":1425,"children":1426},{},[1427,1436],{"type":33,"tag":1359,"props":1428,"children":1429},{},[1430],{"type":33,"tag":64,"props":1431,"children":1433},{"className":1432},[],[1434],{"type":38,"value":1435},"rsq_train",{"type":33,"tag":1359,"props":1437,"children":1438},{},[1439],{"type":38,"value":1440},"Training R²",{"type":33,"tag":1337,"props":1442,"children":1443},{},[1444,1453],{"type":33,"tag":1359,"props":1445,"children":1446},{},[1447],{"type":33,"tag":64,"props":1448,"children":1450},{"className":1449},[],[1451],{"type":38,"value":1452},"google_search_spend_roi",{"type":33,"tag":1359,"props":1454,"children":1455},{},[1456],{"type":38,"value":1457},"Google Search ROI (Revenue\u002FSpend)",{"type":33,"tag":1337,"props":1459,"children":1460},{},[1461,1470],{"type":33,"tag":1359,"props":1462,"children":1463},{},[1464],{"type":33,"tag":64,"props":1465,"children":1467},{"className":1466},[],[1468],{"type":38,"value":1469},"meta_paid_social_spend_roi",{"type":33,"tag":1359,"props":1471,"children":1472},{},[1473],{"type":38,"value":1474},"Meta ROI",{"type":33,"tag":1337,"props":1476,"children":1477},{},[1478,1487],{"type":33,"tag":1359,"props":1479,"children":1480},{},[1481],{"type":33,"tag":64,"props":1482,"children":1484},{"className":1483},[],[1485],{"type":38,"value":1486},"tv_spend_roi",{"type":33,"tag":1359,"props":1488,"children":1489},{},[1490],{"type":38,"value":1491},"TV ROI",{"type":33,"tag":34,"props":1493,"children":1494},{},[1495],{"type":38,"value":1496},"Du wählst das beste Modell anhand von NRMSE + DECOMP.RSSD + Business-Logik. Robyn bietet ein Shiny-Dashboard, aber in Production ist programmatische Auswahl kontrollierter:",{"type":33,"tag":112,"props":1498,"children":1500},{"className":902,"code":1499,"language":904,"meta":17,"style":17},"best_model_id \u003C- OutputModels$allPareto %>%\n  filter(nrmse \u003C 0.1, decomp.rssd \u003C 0.05) %>%\n  arrange(nrmse) %>%\n  slice(1) %>%\n  pull(solID)\n",[1501],{"type":33,"tag":64,"props":1502,"children":1503},{"__ignoreMap":17},[1504,1512,1520,1528,1536],{"type":33,"tag":122,"props":1505,"children":1506},{"class":124,"line":125},[1507],{"type":33,"tag":122,"props":1508,"children":1509},{},[1510],{"type":38,"value":1511},"best_model_id \u003C- OutputModels$allPareto %>%\n",{"type":33,"tag":122,"props":1513,"children":1514},{"class":124,"line":151},[1515],{"type":33,"tag":122,"props":1516,"children":1517},{},[1518],{"type":38,"value":1519},"  filter(nrmse \u003C 0.1, decomp.rssd \u003C 0.05) %>%\n",{"type":33,"tag":122,"props":1521,"children":1522},{"class":124,"line":160},[1523],{"type":33,"tag":122,"props":1524,"children":1525},{},[1526],{"type":38,"value":1527},"  arrange(nrmse) %>%\n",{"type":33,"tag":122,"props":1529,"children":1530},{"class":124,"line":188},[1531],{"type":33,"tag":122,"props":1532,"children":1533},{},[1534],{"type":38,"value":1535},"  slice(1) %>%\n",{"type":33,"tag":122,"props":1537,"children":1538},{"class":124,"line":212},[1539],{"type":33,"tag":122,"props":1540,"children":1541},{},[1542],{"type":38,"value":1543},"  pull(solID)\n",{"type":33,"tag":41,"props":1545,"children":1547},{"id":1546},"holdout-validierung-overfitting-verhindern",[1548],{"type":38,"value":1549},"Holdout-Validierung: Overfitting verhindern",{"type":33,"tag":34,"props":1551,"children":1552},{},[1553],{"type":38,"value":1554},"Ein Modell, das auf Training-Daten fit ist, generalisiert möglicherweise nicht auf unsichtbare Daten. Bei Robyn nutzt du Holdout-Validierung: Die letzten 8–12 Wochen bleiben außerhalb des Trainings als Test-Set. Das Modell wird auf Training-Daten fit, macht Vorhersagen auf Test-Daten. Wenn MAPE (mean absolute percentage error) im Test unter 15 % liegt, kann das Modell in Production gehen.",{"type":33,"tag":112,"props":1556,"children":1558},{"className":902,"code":1557,"language":904,"meta":17,"style":17},"InputCollect_train \u003C- robyn_inputs(\n  dt_input = df_input,\n  date_var = \"week_start\",\n  dep_var = \"revenue\",\n  window_start = \"2024-01-01\",\n  window_end = \"2026-04-12\",  # Letzte 10 Wochen ausgespart\n  # ... andere Parameter identisch\n)\n\nOutputModels_train \u003C- robyn_run(InputCollect_train, iterations = 2000)\n\n# Vorhersage auf Holdout-Set\ndf_test \u003C- df_input %>% filter(week_start > \"2026-04-12\")\npredictions \u003C- predict(OutputModels_train, newdata = df_test)\nmape_test \u003C- mean(abs((df_test$revenue - predictions) \u002F df_test$revenue)) * 100\n",[1559],{"type":33,"tag":64,"props":1560,"children":1561},{"__ignoreMap":17},[1562,1570,1577,1584,1591,1598,1606,1614,1621,1628,1636,1643,1651,1659,1667],{"type":33,"tag":122,"props":1563,"children":1564},{"class":124,"line":125},[1565],{"type":33,"tag":122,"props":1566,"children":1567},{},[1568],{"type":38,"value":1569},"InputCollect_train \u003C- robyn_inputs(\n",{"type":33,"tag":122,"props":1571,"children":1572},{"class":124,"line":151},[1573],{"type":33,"tag":122,"props":1574,"children":1575},{},[1576],{"type":38,"value":1020},{"type":33,"tag":122,"props":1578,"children":1579},{"class":124,"line":160},[1580],{"type":33,"tag":122,"props":1581,"children":1582},{},[1583],{"type":38,"value":1028},{"type":33,"tag":122,"props":1585,"children":1586},{"class":124,"line":188},[1587],{"type":33,"tag":122,"props":1588,"children":1589},{},[1590],{"type":38,"value":1036},{"type":33,"tag":122,"props":1592,"children":1593},{"class":124,"line":212},[1594],{"type":33,"tag":122,"props":1595,"children":1596},{},[1597],{"type":38,"value":1076},{"type":33,"tag":122,"props":1599,"children":1600},{"class":124,"line":227},[1601],{"type":33,"tag":122,"props":1602,"children":1603},{},[1604],{"type":38,"value":1605},"  window_end = \"2026-04-12\",  # Letzte 10 Wochen ausgespart\n",{"type":33,"tag":122,"props":1607,"children":1608},{"class":124,"line":251},[1609],{"type":33,"tag":122,"props":1610,"children":1611},{},[1612],{"type":38,"value":1613},"  # ... andere Parameter identisch\n",{"type":33,"tag":122,"props":1615,"children":1616},{"class":124,"line":265},[1617],{"type":33,"tag":122,"props":1618,"children":1619},{},[1620],{"type":38,"value":427},{"type":33,"tag":122,"props":1622,"children":1623},{"class":124,"line":27},[1624],{"type":33,"tag":122,"props":1625,"children":1626},{"emptyLinePlaceholder":930},[1627],{"type":38,"value":933},{"type":33,"tag":122,"props":1629,"children":1630},{"class":124,"line":290},[1631],{"type":33,"tag":122,"props":1632,"children":1633},{},[1634],{"type":38,"value":1635},"OutputModels_train \u003C- robyn_run(InputCollect_train, iterations = 2000)\n",{"type":33,"tag":122,"props":1637,"children":1638},{"class":124,"line":298},[1639],{"type":33,"tag":122,"props":1640,"children":1641},{"emptyLinePlaceholder":930},[1642],{"type":38,"value":933},{"type":33,"tag":122,"props":1644,"children":1645},{"class":124,"line":333},[1646],{"type":33,"tag":122,"props":1647,"children":1648},{},[1649],{"type":38,"value":1650},"# Vorhersage auf Holdout-Set\n",{"type":33,"tag":122,"props":1652,"children":1653},{"class":124,"line":342},[1654],{"type":33,"tag":122,"props":1655,"children":1656},{},[1657],{"type":38,"value":1658},"df_test \u003C- df_input %>% filter(week_start > \"2026-04-12\")\n",{"type":33,"tag":122,"props":1660,"children":1661},{"class":124,"line":364},[1662],{"type":33,"tag":122,"props":1663,"children":1664},{},[1665],{"type":38,"value":1666},"predictions \u003C- predict(OutputModels_train, newdata = df_test)\n",{"type":33,"tag":122,"props":1668,"children":1669},{"class":124,"line":377},[1670],{"type":33,"tag":122,"props":1671,"children":1672},{},[1673],{"type":38,"value":1674},"mape_test \u003C- mean(abs((df_test$revenue - predictions) \u002F df_test$revenue)) * 100\n",{"type":33,"tag":34,"props":1676,"children":1677},{},[1678],{"type":38,"value":1679},"Wenn MAPE > 20 %, ist das Modell überangepasst. Du musst Hyperparameter-Bereiche verengen oder Context-Variablen hinzufügen (z.B. Wirtschaftsindex, Wetter). Robyns Bayesian Regularisierung (Ridge Penalty) reduziert Overfitting, aber Holdout-Validierung ist die finale Sicherheit.",{"type":33,"tag":41,"props":1681,"children":1683},{"id":1682},"adstock-decay-und-sättigungskurven-visualisieren",[1684],{"type":38,"value":1685},"Adstock-Decay und Sättigungskurven visualisieren",{"type":33,"tag":34,"props":1687,"children":1688},{},[1689,1691,1697],{"type":38,"value":1690},"Robyn plottet mit ",{"type":33,"tag":64,"props":1692,"children":1694},{"className":1693},[],[1695],{"type":38,"value":1696},"robyn_outputs()",{"type":38,"value":1698}," Adstock- und Sättigungskurven. In Production kannst du diese als PNG exportieren und in dein BI-Dashboard einbetten:",{"type":33,"tag":112,"props":1700,"children":1702},{"className":902,"code":1701,"language":904,"meta":17,"style":17},"robyn_outputs(\n  InputCollect = InputCollect,\n  OutputModels = OutputModels,\n  select_model = best_model_id,\n  export = TRUE,\n  export_location = \"\u002Fdata\u002Fmmm_output\u002F\"\n)\n",[1703],{"type":33,"tag":64,"props":1704,"children":1705},{"__ignoreMap":17},[1706,1714,1721,1729,1737,1745,1753],{"type":33,"tag":122,"props":1707,"children":1708},{"class":124,"line":125},[1709],{"type":33,"tag":122,"props":1710,"children":1711},{},[1712],{"type":38,"value":1713},"robyn_outputs(\n",{"type":33,"tag":122,"props":1715,"children":1716},{"class":124,"line":151},[1717],{"type":33,"tag":122,"props":1718,"children":1719},{},[1720],{"type":38,"value":1264},{"type":33,"tag":122,"props":1722,"children":1723},{"class":124,"line":160},[1724],{"type":33,"tag":122,"props":1725,"children":1726},{},[1727],{"type":38,"value":1728},"  OutputModels = OutputModels,\n",{"type":33,"tag":122,"props":1730,"children":1731},{"class":124,"line":188},[1732],{"type":33,"tag":122,"props":1733,"children":1734},{},[1735],{"type":38,"value":1736},"  select_model = best_model_id,\n",{"type":33,"tag":122,"props":1738,"children":1739},{"class":124,"line":212},[1740],{"type":33,"tag":122,"props":1741,"children":1742},{},[1743],{"type":38,"value":1744},"  export = TRUE,\n",{"type":33,"tag":122,"props":1746,"children":1747},{"class":124,"line":227},[1748],{"type":33,"tag":122,"props":1749,"children":1750},{},[1751],{"type":38,"value":1752},"  export_location = \"\u002Fdata\u002Fmmm_output\u002F\"\n",{"type":33,"tag":122,"props":1754,"children":1755},{"class":124,"line":251},[1756],{"type":33,"tag":122,"props":1757,"children":1758},{},[1759],{"type":38,"value":427},{"type":33,"tag":34,"props":1761,"children":1762},{},[1763],{"type":38,"value":1764},"Exportierte Dateien:",{"type":33,"tag":1197,"props":1766,"children":1767},{},[1768,1779,1790],{"type":33,"tag":1201,"props":1769,"children":1770},{},[1771,1777],{"type":33,"tag":64,"props":1772,"children":1774},{"className":1773},[],[1775],{"type":38,"value":1776},"saturate_curves.png",{"type":38,"value":1778}," — Für jeden Channel: Spend vs. Response-Kurve. X-Achse = Ausgaben, Y-Achse = predicted Revenue. Kurve flacht am Sättigungspunkt ab.",{"type":33,"tag":1201,"props":1780,"children":1781},{},[1782,1788],{"type":33,"tag":64,"props":1783,"children":1785},{"className":1784},[],[1786],{"type":38,"value":1787},"adstock_curves.png",{"type":38,"value":1789}," — Decay-Profil. X-Achse = Wochen, Y-Achse = Adstock-Multiplikator. TV zeigt 6–8 Wochen Decay.",{"type":33,"tag":1201,"props":1791,"children":1792},{},[1793,1799],{"type":33,"tag":64,"props":1794,"children":1796},{"className":1795},[],[1797],{"type":38,"value":1798},"waterfall.png",{"type":38,"value":1800}," — Revenue-Dekomposition: Basis + Saisonalität + Channel-Beiträge.",{"type":33,"tag":34,"props":1802,"children":1803},{},[1804],{"type":38,"value":1805},"Mit diesen Visualisierungen kannst du dem CMO sagen: \"TV-Budget um 30 % erhöhen\" — oder besser: \"Wenn du TV um 30 % erhöhst und Search um 20 % reduzierst, steigt der Gesamt-ROI um 12 %.\"",{"type":33,"tag":41,"props":1807,"children":1809},{"id":1808},"production-pipeline-dbt-robyn-looker-studio",[1810],{"type":38,"value":1811},"Production-Pipeline: dbt + Robyn + Looker Studio",{"type":33,"tag":34,"props":1813,"children":1814},{},[1815,1817,1826],{"type":38,"value":1816},"MMM ist kein einmaliger Report — es braucht wöchentliche Aktualisierung. Mit Roibases Ansatz zur ",{"type":33,"tag":1818,"props":1819,"children":1823},"a",{"href":1820,"rel":1821},"https:\u002F\u002Fwww.roibase.com.tr\u002Fde\u002Ffirstparty",[1822],"nofollow",[1824],{"type":38,"value":1825},"First-Party Daten & Messung Architektur",{"type":38,"value":1827}," sieht die Pipeline so aus:",{"type":33,"tag":1829,"props":1830,"children":1831},"ol",{},[1832,1850,1916],{"type":33,"tag":1201,"props":1833,"children":1834},{},[1835,1840,1842,1848],{"type":33,"tag":56,"props":1836,"children":1837},{},[1838],{"type":38,"value":1839},"dbt",{"type":38,"value":1841},": Rohe Events in BigQuery werden in die ",{"type":33,"tag":64,"props":1843,"children":1845},{"className":1844},[],[1846],{"type":38,"value":1847},"mmm_input",{"type":38,"value":1849},"-Tabelle transformiert (SQL oben). Jeden Montag 00:00 Uhr: dbt Cloud scheduled run.",{"type":33,"tag":1201,"props":1851,"children":1852},{},[1853,1858,1860,1865,1867,1872,1874,1879,1881,1887,1889,1894,1895,1900,1901,1907,1908,1914],{"type":33,"tag":56,"props":1854,"children":1855},{},[1856],{"type":38,"value":1857},"Robyn R-Skript",{"type":38,"value":1859},": Läuft in einem Cloud Run Container. Zieht ",{"type":33,"tag":64,"props":1861,"children":1863},{"className":1862},[],[1864],{"type":38,"value":1847},{"type":38,"value":1866}," mit ",{"type":33,"tag":64,"props":1868,"children":1870},{"className":1869},[],[1871],{"type":38,"value":897},{"type":38,"value":1873},", ruft ",{"type":33,"tag":64,"props":1875,"children":1877},{"className":1876},[],[1878],{"type":38,"value":1312},{"type":38,"value":1880}," auf, schreibt Output in BigQuery (",{"type":33,"tag":64,"props":1882,"children":1884},{"className":1883},[],[1885],{"type":38,"value":1886},"mmm_output",{"type":38,"value":1888},"-Tabelle: ",{"type":33,"tag":64,"props":1890,"children":1892},{"className":1891},[],[1893],{"type":38,"value":455},{"type":38,"value":314},{"type":33,"tag":64,"props":1896,"children":1898},{"className":1897},[],[1899],{"type":38,"value":709},{"type":38,"value":314},{"type":33,"tag":64,"props":1902,"children":1904},{"className":1903},[],[1905],{"type":38,"value":1906},"roi",{"type":38,"value":314},{"type":33,"tag":64,"props":1909,"children":1911},{"className":1910},[],[1912],{"type":38,"value":1913},"predicted_revenue",{"type":38,"value":1915},").",{"type":33,"tag":1201,"props":1917,"children":1918},{},[1919,1924,1926,1931],{"type":33,"tag":56,"props":1920,"children":1921},{},[1922],{"type":38,"value":1923},"Looker Studio",{"type":38,"value":1925},": Speist sich aus ",{"type":33,"tag":64,"props":1927,"children":1929},{"className":1928},[],[1930],{"type":38,"value":1886},{"type":38,"value":1932}," — Channel-ROI-Trends, Sättigungskurven und Budget-Recommendation-Dashboard.",{"type":33,"tag":34,"props":1934,"children":1935},{},[1936],{"type":38,"value":1937},"Den Container packst du mit Dockerfile:",{"type":33,"tag":112,"props":1939,"children":1943},{"className":1940,"code":1941,"language":1942,"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",[1944],{"type":33,"tag":64,"props":1945,"children":1946},{"__ignoreMap":17},[1947,1955,1963,1971,1979],{"type":33,"tag":122,"props":1948,"children":1949},{"class":124,"line":125},[1950],{"type":33,"tag":122,"props":1951,"children":1952},{},[1953],{"type":38,"value":1954},"FROM rocker\u002Ftidyverse:4.2.0\n",{"type":33,"tag":122,"props":1956,"children":1957},{"class":124,"line":151},[1958],{"type":33,"tag":122,"props":1959,"children":1960},{},[1961],{"type":38,"value":1962},"RUN R -e \"install.packages('Robyn', repos='https:\u002F\u002Fcloud.r-project.org')\"\n",{"type":33,"tag":122,"props":1964,"children":1965},{"class":124,"line":160},[1966],{"type":33,"tag":122,"props":1967,"children":1968},{},[1969],{"type":38,"value":1970},"RUN R -e \"install.packages('bigrquery')\"\n",{"type":33,"tag":122,"props":1972,"children":1973},{"class":124,"line":188},[1974],{"type":33,"tag":122,"props":1975,"children":1976},{},[1977],{"type":38,"value":1978},"COPY run_mmm.R \u002Fapp\u002Frun_mmm.R\n",{"type":33,"tag":122,"props":1980,"children":1981},{"class":124,"line":212},[1982],{"type":33,"tag":122,"props":1983,"children":1984},{},[1985],{"type":38,"value":1986},"CMD [\"Rscript\", \"\u002Fapp\u002Frun_mmm.R\"]\n",{"type":33,"tag":34,"props":1988,"children":1989},{},[1990],{"type":38,"value":1991},"Cloud Scheduler triggert jeden Montag 06:00 Uhr. Robyn mit 2000 Iterationen dauert ~20 Minuten (8-Core-Maschine).",{"type":33,"tag":41,"props":1993,"children":1995},{"id":1994},"budget-reallocation-entscheidungen-aus-der-pareto-frontier",[1996],{"type":38,"value":1997},"Budget-Reallocation: Entscheidungen aus der Pareto-Frontier",{"type":33,"tag":34,"props":1999,"children":2000},{},[2001,2003,2009],{"type":38,"value":2002},"Robyns stärkstes Ergebnis ist der Budget Optimizer. Die Funktion ",{"type":33,"tag":64,"props":2004,"children":2006},{"className":2005},[],[2007],{"type":38,"value":2008},"robyn_allocator()",{"type":38,"value":2010}," verteilt dein Budget zwischen Channels neu, um den Umsatz zu maximieren:",{"type":33,"tag":112,"props":2012,"children":2013},{"className":902,"code":17,"language":904,"meta":17,"style":17},[2014],{"type":33,"tag":64,"props":2015,"children":2016},{"__ignoreMap":17},[2017],{"type":33,"tag":122,"props":2018,"children":2019},{"class":124,"line":125},[2020],{"type":33,"tag":122,"props":2021,"children":2022},{},[2023],{"type":38,"value":17},{"type":33,"tag":2025,"props":2026,"children":2027},"style",{},[2028],{"type":38,"value":2029},"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":2031},[2032,2033,2034,2035,2036,2037,2038,2039],{"id":43,"depth":151,"text":46},{"id":102,"depth":151,"text":105},{"id":981,"depth":151,"text":984},{"id":1238,"depth":151,"text":1241},{"id":1546,"depth":151,"text":1549},{"id":1682,"depth":151,"text":1685},{"id":1808,"depth":151,"text":1811},{"id":1994,"depth":151,"text":1997},"markdown","content:de:data:marketing-mix-modeling-robyn-practical-setup.md","content","de\u002Fdata\u002Fmarketing-mix-modeling-robyn-practical-setup.md","de\u002Fdata\u002Fmarketing-mix-modeling-robyn-practical-setup","md",1782079488600]