[{"data":1,"prerenderedAt":2184},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fit\u002Fdata\u002Fmarketing-mix-modeling-robyn-setup-praktis":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":2178,"_id":2179,"_source":2180,"_file":2181,"_stem":2182,"_extension":2183},"\u002Fit\u002Fdata\u002Fmarketing-mix-modeling-robyn-setup-praktis","data",false,"","Marketing Mix Modeling: Configurazione pratica con Robyn","Costruire un modello di attribuzione con Robyn di Meta: curve di saturazione, adstock decay e validazione holdout. SQL, R e pipeline production.","2026-06-21",[22,23,24,25,26],"marketing-mix-modeling","robyn","adstock","attribution","mmm",9,"Roibase",{"type":30,"children":31,"toc":2168},"root",[32,40,47,52,72,90,100,106,111,887,900,974,979,985,997,1187,1195,1230,1235,1241,1303,1314,1327,1491,1496,1543,1549,1554,1674,1679,1685,1698,1759,1764,1800,1805,1811,1827,1932,1937,1986,1991,1997,2010,2094,2099,2162],{"type":33,"tag":34,"props":35,"children":36},"element","p",{},[37],{"type":38,"value":39},"text","L'abbandono dei cookie di terze parti e le normative sulla privacy spostano l'attribuzione da metodi deterministici a modelli probabilistici. Marketing Mix Modeling (MMM) — uno strumento statistico degli anni '60 — ritorna al centro della scena. Il framework open source Robyn di Meta fornisce l'aspetto pratico di questa trasformazione: con inferenza bayesiana, curve di saturazione e adstock decay, colleghi la spesa di marketing settimanale alle vendite tramite regressione, portandola in produzione. Questo articolo mostra come configurare Robyn, adattare il modello a dati reali, eseguire grid search di iperparametri e prevenire l'overfitting con validazione holdout.",{"type":33,"tag":41,"props":42,"children":44},"h2",{"id":43},"che-cosa-è-robyn-e-come-differisce-dalla-regressione-classica",[45],{"type":38,"value":46},"Che cosa è Robyn e come differisce dalla regressione classica",{"type":33,"tag":34,"props":48,"children":49},{},[50],{"type":38,"value":51},"Robyn è un framework MMM open source scritto in R. Meta l'ha sviluppato nel 2020 per il proprio team di marketing e rilasciato nel 2021. Le differenze rispetto alla regressione lineare classica sono significative:",{"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},"Trasformazione Adstock",{"type":38,"value":62},": L'effetto del marketing non è immediato — uno spot televisivo genera top-of-mind per settimane. Adstock modella il contributo della spesa passata alle vendite odierne tramite decadimento esponenziale. Robyn supporta funzioni adstock geometriche e Weibull. Geometrica è semplice: ",{"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},", dove θ è il parametro di decadimento. Weibull è più flessibile — puoi posizionare l'effetto di picco con ritardo.",{"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},"Saturazione (Rendimenti decrescenti)",{"type":38,"value":81},": La relazione spesa-vendite non è lineare. I primi 100.000 EUR generano ROI dell'80%, mentre i successivi 100.000 EUR possono generare il 40%. Robyn applica funzioni di saturazione Hill e S-curve. L'equazione di Hill è: ",{"type":33,"tag":64,"props":83,"children":85},{"className":84},[],[86],{"type":38,"value":87},"y = V_max × x^n \u002F (K^n + x^n)",{"type":38,"value":89},", dove K è il punto di semisaturazione e n è la pendenza. Questa non-linearità è critica per l'ottimizzazione del budget a livello di canale.",{"type":33,"tag":34,"props":91,"children":92},{},[93,98],{"type":33,"tag":56,"props":94,"children":95},{},[96],{"type":38,"value":97},"Tuning degli iperparametri",{"type":38,"value":99},": I valori di decay dell'adstock, K e n di saturazione sono sconosciuti — li trovi tramite grid search. Robyn utilizza un algoritmo genetico (NSGAII) per testare migliaia di combinazioni di modelli, selezionando i migliori trade-off dalla frontiera di Pareto.",{"type":33,"tag":41,"props":101,"children":103},{"id":102},"preparazione-dei-dati-da-sql-a-granularità-settimanale",[104],{"type":38,"value":105},"Preparazione dei dati: da SQL a granularità settimanale",{"type":33,"tag":34,"props":107,"children":108},{},[109],{"type":38,"value":110},"Robyn funziona con granularità settimanale. Dai log delle transazioni giornaliere aggreghi spesa media e ricavi settimanali. Esempio di query BigQuery:",{"type":33,"tag":112,"props":113,"children":117},"pre",{"className":114,"code":115,"language":116,"meta":17,"style":17},"language-sql shiki shiki-themes github-dark","WITH weekly_revenue AS (\n  SELECT\n    DATE_TRUNC(order_date, WEEK) AS week_start,\n    SUM(revenue) AS revenue\n  FROM `project.dataset.orders`\n  WHERE order_date >= '2024-01-01'\n  GROUP BY 1\n),\nweekly_spend AS (\n  SELECT\n    DATE_TRUNC(date, WEEK) AS week_start,\n    channel,\n    SUM(cost) AS spend\n  FROM `project.dataset.marketing_costs`\n  WHERE date >= '2024-01-01'\n  GROUP BY 1, 2\n)\nSELECT\n  r.week_start,\n  r.revenue,\n  COALESCE(s_google.spend, 0) AS google_search_spend,\n  COALESCE(s_meta.spend, 0) AS meta_paid_social_spend,\n  COALESCE(s_tv.spend, 0) AS tv_spend\nFROM weekly_revenue r\nLEFT JOIN weekly_spend s_google\n  ON r.week_start = s_google.week_start AND s_google.channel = 'google_search'\nLEFT JOIN weekly_spend s_meta\n  ON r.week_start = s_meta.week_start AND s_meta.channel = 'meta'\nLEFT JOIN weekly_spend s_tv\n  ON r.week_start = s_tv.week_start AND s_tv.channel = 'tv'\nORDER BY 1;\n","sql",[118],{"type":33,"tag":64,"props":119,"children":120},{"__ignoreMap":17},[121,149,158,186,210,225,249,263,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},"La query produce una riga per settimana, 1 ricavo e N colonne di spesa per canale. Robyn accetta CSV, ma in produzione è più pulito estrarre direttamente da BigQuery in R. Con il pacchetto ",{"type":33,"tag":64,"props":893,"children":895},{"className":894},[],[896],{"type":38,"value":897},"bigrquery",{"type":38,"value":899},":",{"type":33,"tag":112,"props":901,"children":905},{"className":902,"code":903,"language":904,"meta":17,"style":17},"language-r shiki shiki-themes github-dark","library(bigrquery)\nlibrary(Robyn)\n\nbq_auth()\ndf_input \u003C- bq_project_query(\n  \"project-id\",\n  \"SELECT week_start, revenue, google_search_spend, meta_paid_social_spend, tv_spend FROM `project.dataset.mmm_input`\"\n) %>% bq_table_download()\n","r",[906],{"type":33,"tag":64,"props":907,"children":908},{"__ignoreMap":17},[909,917,925,934,942,950,958,966],{"type":33,"tag":122,"props":910,"children":911},{"class":124,"line":125},[912],{"type":33,"tag":122,"props":913,"children":914},{},[915],{"type":38,"value":916},"library(bigrquery)\n",{"type":33,"tag":122,"props":918,"children":919},{"class":124,"line":151},[920],{"type":33,"tag":122,"props":921,"children":922},{},[923],{"type":38,"value":924},"library(Robyn)\n",{"type":33,"tag":122,"props":926,"children":927},{"class":124,"line":160},[928],{"type":33,"tag":122,"props":929,"children":931},{"emptyLinePlaceholder":930},true,[932],{"type":38,"value":933},"\n",{"type":33,"tag":122,"props":935,"children":936},{"class":124,"line":188},[937],{"type":33,"tag":122,"props":938,"children":939},{},[940],{"type":38,"value":941},"bq_auth()\n",{"type":33,"tag":122,"props":943,"children":944},{"class":124,"line":212},[945],{"type":33,"tag":122,"props":946,"children":947},{},[948],{"type":38,"value":949},"df_input \u003C- bq_project_query(\n",{"type":33,"tag":122,"props":951,"children":952},{"class":124,"line":227},[953],{"type":33,"tag":122,"props":954,"children":955},{},[956],{"type":38,"value":957},"  \"project-id\",\n",{"type":33,"tag":122,"props":959,"children":960},{"class":124,"line":251},[961],{"type":33,"tag":122,"props":962,"children":963},{},[964],{"type":38,"value":965},"  \"SELECT week_start, revenue, google_search_spend, meta_paid_social_spend, tv_spend FROM `project.dataset.mmm_input`\"\n",{"type":33,"tag":122,"props":967,"children":968},{"class":124,"line":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},"Requisito minimo di dati: 104 settimane (2 anni). Meno dati comportano rischi di overfitting. I prior bayesiani di Robyn funzionano con 52 settimane, ma 104+ settimane catturano meglio la stagionalità.",{"type":33,"tag":41,"props":980,"children":982},{"id":981},"configurazione-del-modello-robyn_inputs-e-griglia-di-iperparametri",[983],{"type":38,"value":984},"Configurazione del modello: robyn_inputs e griglia di iperparametri",{"type":33,"tag":34,"props":986,"children":987},{},[988,990,996],{"type":38,"value":989},"Robyn crea un oggetto di configurazione con la funzione ",{"type":33,"tag":64,"props":991,"children":993},{"className":992},[],[994],{"type":38,"value":995},"robyn_inputs()",{"type":38,"value":899},{"type":33,"tag":112,"props":998,"children":1000},{"className":902,"code":999,"language":904,"meta":17,"style":17},"InputCollect \u003C- robyn_inputs(\n  dt_input = df_input,\n  date_var = \"week_start\",\n  dep_var = \"revenue\",\n  dep_var_type = \"revenue\",\n  paid_media_spends = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n  paid_media_vars = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n  context_vars = c(\"competitor_index\", \"seasonality\"),\n  window_start = \"2024-01-01\",\n  window_end = \"2026-06-14\",\n  adstock = \"geometric\",\n  hyperparameters = list(\n    google_search_spend_alphas = c(0.5, 3),\n    google_search_spend_gammas = c(0.3, 1),\n    google_search_spend_thetas = c(0, 0.3),\n    meta_paid_social_spend_alphas = c(0.5, 3),\n    meta_paid_social_spend_gammas = c(0.3, 1),\n    meta_paid_social_spend_thetas = c(0, 0.5),\n    tv_spend_alphas = c(0.5, 3),\n    tv_spend_gammas = c(0.3, 1),\n    tv_spend_thetas = c(0.1, 0.7)\n  )\n)\n",[1001],{"type":33,"tag":64,"props":1002,"children":1003},{"__ignoreMap":17},[1004,1012,1020,1028,1036,1044,1052,1060,1068,1076,1084,1092,1100,1108,1116,1124,1132,1140,1148,1156,1164,1172,1180],{"type":33,"tag":122,"props":1005,"children":1006},{"class":124,"line":125},[1007],{"type":33,"tag":122,"props":1008,"children":1009},{},[1010],{"type":38,"value":1011},"InputCollect \u003C- robyn_inputs(\n",{"type":33,"tag":122,"props":1013,"children":1014},{"class":124,"line":151},[1015],{"type":33,"tag":122,"props":1016,"children":1017},{},[1018],{"type":38,"value":1019},"  dt_input = df_input,\n",{"type":33,"tag":122,"props":1021,"children":1022},{"class":124,"line":160},[1023],{"type":33,"tag":122,"props":1024,"children":1025},{},[1026],{"type":38,"value":1027},"  date_var = \"week_start\",\n",{"type":33,"tag":122,"props":1029,"children":1030},{"class":124,"line":188},[1031],{"type":33,"tag":122,"props":1032,"children":1033},{},[1034],{"type":38,"value":1035},"  dep_var = \"revenue\",\n",{"type":33,"tag":122,"props":1037,"children":1038},{"class":124,"line":212},[1039],{"type":33,"tag":122,"props":1040,"children":1041},{},[1042],{"type":38,"value":1043},"  dep_var_type = \"revenue\",\n",{"type":33,"tag":122,"props":1045,"children":1046},{"class":124,"line":227},[1047],{"type":33,"tag":122,"props":1048,"children":1049},{},[1050],{"type":38,"value":1051},"  paid_media_spends = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n",{"type":33,"tag":122,"props":1053,"children":1054},{"class":124,"line":251},[1055],{"type":33,"tag":122,"props":1056,"children":1057},{},[1058],{"type":38,"value":1059},"  paid_media_vars = c(\"google_search_spend\", \"meta_paid_social_spend\", \"tv_spend\"),\n",{"type":33,"tag":122,"props":1061,"children":1062},{"class":124,"line":265},[1063],{"type":33,"tag":122,"props":1064,"children":1065},{},[1066],{"type":38,"value":1067},"  context_vars = c(\"competitor_index\", \"seasonality\"),\n",{"type":33,"tag":122,"props":1069,"children":1070},{"class":124,"line":27},[1071],{"type":33,"tag":122,"props":1072,"children":1073},{},[1074],{"type":38,"value":1075},"  window_start = \"2024-01-01\",\n",{"type":33,"tag":122,"props":1077,"children":1078},{"class":124,"line":290},[1079],{"type":33,"tag":122,"props":1080,"children":1081},{},[1082],{"type":38,"value":1083},"  window_end = \"2026-06-14\",\n",{"type":33,"tag":122,"props":1085,"children":1086},{"class":124,"line":298},[1087],{"type":33,"tag":122,"props":1088,"children":1089},{},[1090],{"type":38,"value":1091},"  adstock = \"geometric\",\n",{"type":33,"tag":122,"props":1093,"children":1094},{"class":124,"line":333},[1095],{"type":33,"tag":122,"props":1096,"children":1097},{},[1098],{"type":38,"value":1099},"  hyperparameters = list(\n",{"type":33,"tag":122,"props":1101,"children":1102},{"class":124,"line":342},[1103],{"type":33,"tag":122,"props":1104,"children":1105},{},[1106],{"type":38,"value":1107},"    google_search_spend_alphas = c(0.5, 3),\n",{"type":33,"tag":122,"props":1109,"children":1110},{"class":124,"line":364},[1111],{"type":33,"tag":122,"props":1112,"children":1113},{},[1114],{"type":38,"value":1115},"    google_search_spend_gammas = c(0.3, 1),\n",{"type":33,"tag":122,"props":1117,"children":1118},{"class":124,"line":377},[1119],{"type":33,"tag":122,"props":1120,"children":1121},{},[1122],{"type":38,"value":1123},"    google_search_spend_thetas = c(0, 0.3),\n",{"type":33,"tag":122,"props":1125,"children":1126},{"class":124,"line":399},[1127],{"type":33,"tag":122,"props":1128,"children":1129},{},[1130],{"type":38,"value":1131},"    meta_paid_social_spend_alphas = c(0.5, 3),\n",{"type":33,"tag":122,"props":1133,"children":1134},{"class":124,"line":421},[1135],{"type":33,"tag":122,"props":1136,"children":1137},{},[1138],{"type":38,"value":1139},"    meta_paid_social_spend_gammas = c(0.3, 1),\n",{"type":33,"tag":122,"props":1141,"children":1142},{"class":124,"line":430},[1143],{"type":33,"tag":122,"props":1144,"children":1145},{},[1146],{"type":38,"value":1147},"    meta_paid_social_spend_thetas = c(0, 0.5),\n",{"type":33,"tag":122,"props":1149,"children":1150},{"class":124,"line":439},[1151],{"type":33,"tag":122,"props":1152,"children":1153},{},[1154],{"type":38,"value":1155},"    tv_spend_alphas = c(0.5, 3),\n",{"type":33,"tag":122,"props":1157,"children":1158},{"class":124,"line":463},[1159],{"type":33,"tag":122,"props":1160,"children":1161},{},[1162],{"type":38,"value":1163},"    tv_spend_gammas = c(0.3, 1),\n",{"type":33,"tag":122,"props":1165,"children":1166},{"class":124,"line":484},[1167],{"type":33,"tag":122,"props":1168,"children":1169},{},[1170],{"type":38,"value":1171},"    tv_spend_thetas = c(0.1, 0.7)\n",{"type":33,"tag":122,"props":1173,"children":1174},{"class":124,"line":534},[1175],{"type":33,"tag":122,"props":1176,"children":1177},{},[1178],{"type":38,"value":1179},"  )\n",{"type":33,"tag":122,"props":1181,"children":1182},{"class":124,"line":580},[1183],{"type":33,"tag":122,"props":1184,"children":1185},{},[1186],{"type":38,"value":427},{"type":33,"tag":34,"props":1188,"children":1189},{},[1190],{"type":33,"tag":56,"props":1191,"children":1192},{},[1193],{"type":38,"value":1194},"Spiegazione degli iperparametri:",{"type":33,"tag":1196,"props":1197,"children":1198},"ul",{},[1199,1210,1220],{"type":33,"tag":1200,"props":1201,"children":1202},"li",{},[1203,1208],{"type":33,"tag":56,"props":1204,"children":1205},{},[1206],{"type":38,"value":1207},"alpha",{"type":38,"value":1209},": Parametro di pendenza della funzione di saturazione Hill (n). Alpha alto = saturazione tardiva.",{"type":33,"tag":1200,"props":1211,"children":1212},{},[1213,1218],{"type":33,"tag":56,"props":1214,"children":1215},{},[1216],{"type":38,"value":1217},"gamma",{"type":38,"value":1219},": Parametro K di Hill — punto di semisaturazione. Gamma basso = saturazione precoce.",{"type":33,"tag":1200,"props":1221,"children":1222},{},[1223,1228],{"type":33,"tag":56,"props":1224,"children":1225},{},[1226],{"type":38,"value":1227},"theta",{"type":38,"value":1229},": Decadimento adstock geometrico. 0 = effetto istantaneo, 0.7 = 70% trasferito alla settimana successiva.",{"type":33,"tag":34,"props":1231,"children":1232},{},[1233],{"type":38,"value":1234},"Fornisci un intervallo min-max per ogni canale. Robyn esegue grid search entro questi intervalli. Per TV, il limite superiore di theta è 0.7 — lo share-of-mind dura a lungo. Per paid search, 0.3 — la conversione è a breve termine.",{"type":33,"tag":41,"props":1236,"children":1238},{"id":1237},"esecuzione-del-modello-robyn_run-e-ottimizzazione-pareto",[1239],{"type":38,"value":1240},"Esecuzione del modello: robyn_run e ottimizzazione Pareto",{"type":33,"tag":112,"props":1242,"children":1244},{"className":902,"code":1243,"language":904,"meta":17,"style":17},"OutputModels \u003C- robyn_run(\n  InputCollect = InputCollect,\n  cores = 8,\n  iterations = 2000,\n  trials = 5,\n  outputs = FALSE\n)\n",[1245],{"type":33,"tag":64,"props":1246,"children":1247},{"__ignoreMap":17},[1248,1256,1264,1272,1280,1288,1296],{"type":33,"tag":122,"props":1249,"children":1250},{"class":124,"line":125},[1251],{"type":33,"tag":122,"props":1252,"children":1253},{},[1254],{"type":38,"value":1255},"OutputModels \u003C- robyn_run(\n",{"type":33,"tag":122,"props":1257,"children":1258},{"class":124,"line":151},[1259],{"type":33,"tag":122,"props":1260,"children":1261},{},[1262],{"type":38,"value":1263},"  InputCollect = InputCollect,\n",{"type":33,"tag":122,"props":1265,"children":1266},{"class":124,"line":160},[1267],{"type":33,"tag":122,"props":1268,"children":1269},{},[1270],{"type":38,"value":1271},"  cores = 8,\n",{"type":33,"tag":122,"props":1273,"children":1274},{"class":124,"line":188},[1275],{"type":33,"tag":122,"props":1276,"children":1277},{},[1278],{"type":38,"value":1279},"  iterations = 2000,\n",{"type":33,"tag":122,"props":1281,"children":1282},{"class":124,"line":212},[1283],{"type":33,"tag":122,"props":1284,"children":1285},{},[1286],{"type":38,"value":1287},"  trials = 5,\n",{"type":33,"tag":122,"props":1289,"children":1290},{"class":124,"line":227},[1291],{"type":33,"tag":122,"props":1292,"children":1293},{},[1294],{"type":38,"value":1295},"  outputs = FALSE\n",{"type":33,"tag":122,"props":1297,"children":1298},{"class":124,"line":251},[1299],{"type":33,"tag":122,"props":1300,"children":1301},{},[1302],{"type":38,"value":427},{"type":33,"tag":34,"props":1304,"children":1305},{},[1306,1312],{"type":33,"tag":64,"props":1307,"children":1309},{"className":1308},[],[1310],{"type":38,"value":1311},"robyn_run()",{"type":38,"value":1313}," esegue un algoritmo genetico su 2000 iterazioni testando combinazioni di iperparametri. Ad ogni iterazione, minimizza NRMSE (normalized root mean squared error) e DECOMP.RSSD (decomposition residual sum of squares difference). Seleziona 5 modelli dalla frontiera di Pareto — trade-off tra qualità del fit e logica aziendale (ad esempio, l'ROI della TV non dovrebbe superare quello della ricerca).",{"type":33,"tag":34,"props":1315,"children":1316},{},[1317,1319,1325],{"type":38,"value":1318},"L'oggetto output contiene la tabella ",{"type":33,"tag":64,"props":1320,"children":1322},{"className":1321},[],[1323],{"type":38,"value":1324},"df_allpareto",{"type":38,"value":1326}," — ogni modello con ROI a livello di canale, ROAS e CPA. Numero di righe = iterazioni × trial. Include queste colonne:",{"type":33,"tag":1328,"props":1329,"children":1330},"table",{},[1331,1350],{"type":33,"tag":1332,"props":1333,"children":1334},"thead",{},[1335],{"type":33,"tag":1336,"props":1337,"children":1338},"tr",{},[1339,1345],{"type":33,"tag":1340,"props":1341,"children":1342},"th",{},[1343],{"type":38,"value":1344},"Colonna",{"type":33,"tag":1340,"props":1346,"children":1347},{},[1348],{"type":38,"value":1349},"Descrizione",{"type":33,"tag":1351,"props":1352,"children":1353},"tbody",{},[1354,1372,1389,1406,1423,1440,1457,1474],{"type":33,"tag":1336,"props":1355,"children":1356},{},[1357,1367],{"type":33,"tag":1358,"props":1359,"children":1360},"td",{},[1361],{"type":33,"tag":64,"props":1362,"children":1364},{"className":1363},[],[1365],{"type":38,"value":1366},"solID",{"type":33,"tag":1358,"props":1368,"children":1369},{},[1370],{"type":38,"value":1371},"ID del modello",{"type":33,"tag":1336,"props":1373,"children":1374},{},[1375,1384],{"type":33,"tag":1358,"props":1376,"children":1377},{},[1378],{"type":33,"tag":64,"props":1379,"children":1381},{"className":1380},[],[1382],{"type":38,"value":1383},"nrmse",{"type":33,"tag":1358,"props":1385,"children":1386},{},[1387],{"type":38,"value":1388},"Normalized RMSE — basso = buon fit",{"type":33,"tag":1336,"props":1390,"children":1391},{},[1392,1401],{"type":33,"tag":1358,"props":1393,"children":1394},{},[1395],{"type":33,"tag":64,"props":1396,"children":1398},{"className":1397},[],[1399],{"type":38,"value":1400},"decomp.rssd",{"type":33,"tag":1358,"props":1402,"children":1403},{},[1404],{"type":38,"value":1405},"Decomposition RSSD — basso = contributi stabili",{"type":33,"tag":1336,"props":1407,"children":1408},{},[1409,1418],{"type":33,"tag":1358,"props":1410,"children":1411},{},[1412],{"type":33,"tag":64,"props":1413,"children":1415},{"className":1414},[],[1416],{"type":38,"value":1417},"mape",{"type":33,"tag":1358,"props":1419,"children":1420},{},[1421],{"type":38,"value":1422},"Mean absolute percentage error",{"type":33,"tag":1336,"props":1424,"children":1425},{},[1426,1435],{"type":33,"tag":1358,"props":1427,"children":1428},{},[1429],{"type":33,"tag":64,"props":1430,"children":1432},{"className":1431},[],[1433],{"type":38,"value":1434},"rsq_train",{"type":33,"tag":1358,"props":1436,"children":1437},{},[1438],{"type":38,"value":1439},"R² di training",{"type":33,"tag":1336,"props":1441,"children":1442},{},[1443,1452],{"type":33,"tag":1358,"props":1444,"children":1445},{},[1446],{"type":33,"tag":64,"props":1447,"children":1449},{"className":1448},[],[1450],{"type":38,"value":1451},"google_search_spend_roi",{"type":33,"tag":1358,"props":1453,"children":1454},{},[1455],{"type":38,"value":1456},"ROI di Google Search (ricavi\u002Fspesa)",{"type":33,"tag":1336,"props":1458,"children":1459},{},[1460,1469],{"type":33,"tag":1358,"props":1461,"children":1462},{},[1463],{"type":33,"tag":64,"props":1464,"children":1466},{"className":1465},[],[1467],{"type":38,"value":1468},"meta_paid_social_spend_roi",{"type":33,"tag":1358,"props":1470,"children":1471},{},[1472],{"type":38,"value":1473},"ROI di Meta",{"type":33,"tag":1336,"props":1475,"children":1476},{},[1477,1486],{"type":33,"tag":1358,"props":1478,"children":1479},{},[1480],{"type":33,"tag":64,"props":1481,"children":1483},{"className":1482},[],[1484],{"type":38,"value":1485},"tv_spend_roi",{"type":33,"tag":1358,"props":1487,"children":1488},{},[1489],{"type":38,"value":1490},"ROI della TV",{"type":33,"tag":34,"props":1492,"children":1493},{},[1494],{"type":38,"value":1495},"Scegli il miglior modello per NRMSE + DECOMP.RSSD + logica aziendale. La dashboard Shiny di Robyn offre un'interfaccia visiva, ma in produzione la selezione programmatica è più controllata:",{"type":33,"tag":112,"props":1497,"children":1499},{"className":902,"code":1498,"language":904,"meta":17,"style":17},"best_model_id \u003C- OutputModels$allPareto %>%\n  filter(nrmse \u003C 0.1, decomp.rssd \u003C 0.05) %>%\n  arrange(nrmse) %>%\n  slice(1) %>%\n  pull(solID)\n",[1500],{"type":33,"tag":64,"props":1501,"children":1502},{"__ignoreMap":17},[1503,1511,1519,1527,1535],{"type":33,"tag":122,"props":1504,"children":1505},{"class":124,"line":125},[1506],{"type":33,"tag":122,"props":1507,"children":1508},{},[1509],{"type":38,"value":1510},"best_model_id \u003C- OutputModels$allPareto %>%\n",{"type":33,"tag":122,"props":1512,"children":1513},{"class":124,"line":151},[1514],{"type":33,"tag":122,"props":1515,"children":1516},{},[1517],{"type":38,"value":1518},"  filter(nrmse \u003C 0.1, decomp.rssd \u003C 0.05) %>%\n",{"type":33,"tag":122,"props":1520,"children":1521},{"class":124,"line":160},[1522],{"type":33,"tag":122,"props":1523,"children":1524},{},[1525],{"type":38,"value":1526},"  arrange(nrmse) %>%\n",{"type":33,"tag":122,"props":1528,"children":1529},{"class":124,"line":188},[1530],{"type":33,"tag":122,"props":1531,"children":1532},{},[1533],{"type":38,"value":1534},"  slice(1) %>%\n",{"type":33,"tag":122,"props":1536,"children":1537},{"class":124,"line":212},[1538],{"type":33,"tag":122,"props":1539,"children":1540},{},[1541],{"type":38,"value":1542},"  pull(solID)\n",{"type":33,"tag":41,"props":1544,"children":1546},{"id":1545},"validazione-holdout-prevenire-loverfitting",[1547],{"type":38,"value":1548},"Validazione Holdout: prevenire l'overfitting",{"type":33,"tag":34,"props":1550,"children":1551},{},[1552],{"type":38,"value":1553},"Un modello adattato ai dati di training potrebbe non generalizzare bene ai dati invisibili. Con Robyn, esegui validazione holdout: escludere le ultime 8-12 settimane dal training e usarle come test set. Il modello si adatta ai dati di training, fa previsioni sul test set. Se MAPE (mean absolute percentage error) sul test set è inferiore al 15%, il modello è pronto per la produzione.",{"type":33,"tag":112,"props":1555,"children":1557},{"className":902,"code":1556,"language":904,"meta":17,"style":17},"InputCollect_train \u003C- robyn_inputs(\n  dt_input = df_input,\n  date_var = \"week_start\",\n  dep_var = \"revenue\",\n  window_start = \"2024-01-01\",\n  window_end = \"2026-04-12\",  # Ultime 10 settimane in holdout\n  # ... altri parametri uguali\n)\n\nOutputModels_train \u003C- robyn_run(InputCollect_train, iterations = 2000)\n\n# Previsioni sul test set\ndf_test \u003C- df_input %>% filter(week_start > \"2026-04-12\")\npredictions \u003C- predict(OutputModels_train, newdata = df_test)\nmape_test \u003C- mean(abs((df_test$revenue - predictions) \u002F df_test$revenue)) * 100\n",[1558],{"type":33,"tag":64,"props":1559,"children":1560},{"__ignoreMap":17},[1561,1569,1576,1583,1590,1597,1605,1613,1620,1627,1635,1642,1650,1658,1666],{"type":33,"tag":122,"props":1562,"children":1563},{"class":124,"line":125},[1564],{"type":33,"tag":122,"props":1565,"children":1566},{},[1567],{"type":38,"value":1568},"InputCollect_train \u003C- robyn_inputs(\n",{"type":33,"tag":122,"props":1570,"children":1571},{"class":124,"line":151},[1572],{"type":33,"tag":122,"props":1573,"children":1574},{},[1575],{"type":38,"value":1019},{"type":33,"tag":122,"props":1577,"children":1578},{"class":124,"line":160},[1579],{"type":33,"tag":122,"props":1580,"children":1581},{},[1582],{"type":38,"value":1027},{"type":33,"tag":122,"props":1584,"children":1585},{"class":124,"line":188},[1586],{"type":33,"tag":122,"props":1587,"children":1588},{},[1589],{"type":38,"value":1035},{"type":33,"tag":122,"props":1591,"children":1592},{"class":124,"line":212},[1593],{"type":33,"tag":122,"props":1594,"children":1595},{},[1596],{"type":38,"value":1075},{"type":33,"tag":122,"props":1598,"children":1599},{"class":124,"line":227},[1600],{"type":33,"tag":122,"props":1601,"children":1602},{},[1603],{"type":38,"value":1604},"  window_end = \"2026-04-12\",  # Ultime 10 settimane in holdout\n",{"type":33,"tag":122,"props":1606,"children":1607},{"class":124,"line":251},[1608],{"type":33,"tag":122,"props":1609,"children":1610},{},[1611],{"type":38,"value":1612},"  # ... altri parametri uguali\n",{"type":33,"tag":122,"props":1614,"children":1615},{"class":124,"line":265},[1616],{"type":33,"tag":122,"props":1617,"children":1618},{},[1619],{"type":38,"value":427},{"type":33,"tag":122,"props":1621,"children":1622},{"class":124,"line":27},[1623],{"type":33,"tag":122,"props":1624,"children":1625},{"emptyLinePlaceholder":930},[1626],{"type":38,"value":933},{"type":33,"tag":122,"props":1628,"children":1629},{"class":124,"line":290},[1630],{"type":33,"tag":122,"props":1631,"children":1632},{},[1633],{"type":38,"value":1634},"OutputModels_train \u003C- robyn_run(InputCollect_train, iterations = 2000)\n",{"type":33,"tag":122,"props":1636,"children":1637},{"class":124,"line":298},[1638],{"type":33,"tag":122,"props":1639,"children":1640},{"emptyLinePlaceholder":930},[1641],{"type":38,"value":933},{"type":33,"tag":122,"props":1643,"children":1644},{"class":124,"line":333},[1645],{"type":33,"tag":122,"props":1646,"children":1647},{},[1648],{"type":38,"value":1649},"# Previsioni sul test set\n",{"type":33,"tag":122,"props":1651,"children":1652},{"class":124,"line":342},[1653],{"type":33,"tag":122,"props":1654,"children":1655},{},[1656],{"type":38,"value":1657},"df_test \u003C- df_input %>% filter(week_start > \"2026-04-12\")\n",{"type":33,"tag":122,"props":1659,"children":1660},{"class":124,"line":364},[1661],{"type":33,"tag":122,"props":1662,"children":1663},{},[1664],{"type":38,"value":1665},"predictions \u003C- predict(OutputModels_train, newdata = df_test)\n",{"type":33,"tag":122,"props":1667,"children":1668},{"class":124,"line":377},[1669],{"type":33,"tag":122,"props":1670,"children":1671},{},[1672],{"type":38,"value":1673},"mape_test \u003C- mean(abs((df_test$revenue - predictions) \u002F df_test$revenue)) * 100\n",{"type":33,"tag":34,"props":1675,"children":1676},{},[1677],{"type":38,"value":1678},"Se MAPE > 20%, il modello è overfitting. Riduci gli intervalli di iperparametri o aggiungi variabili di contesto (indice economico, meteo). La regolarizzazione bayesiana di Robyn (penalty di ridge) riduce l'overfitting, ma la validazione holdout è la garanzia finale.",{"type":33,"tag":41,"props":1680,"children":1682},{"id":1681},"visualizzazione-delle-curve-di-adstock-e-saturazione",[1683],{"type":38,"value":1684},"Visualizzazione delle curve di adstock e saturazione",{"type":33,"tag":34,"props":1686,"children":1687},{},[1688,1690,1696],{"type":38,"value":1689},"Robyn, con ",{"type":33,"tag":64,"props":1691,"children":1693},{"className":1692},[],[1694],{"type":38,"value":1695},"robyn_outputs()",{"type":38,"value":1697},", traccia curve di adstock e saturazione. In produzione, esporti questi grafici come PNG e li incorpori nel dashboard BI:",{"type":33,"tag":112,"props":1699,"children":1701},{"className":902,"code":1700,"language":904,"meta":17,"style":17},"robyn_outputs(\n  InputCollect = InputCollect,\n  OutputModels = OutputModels,\n  select_model = best_model_id,\n  export = TRUE,\n  export_location = \"\u002Fdata\u002Fmmm_output\u002F\"\n)\n",[1702],{"type":33,"tag":64,"props":1703,"children":1704},{"__ignoreMap":17},[1705,1713,1720,1728,1736,1744,1752],{"type":33,"tag":122,"props":1706,"children":1707},{"class":124,"line":125},[1708],{"type":33,"tag":122,"props":1709,"children":1710},{},[1711],{"type":38,"value":1712},"robyn_outputs(\n",{"type":33,"tag":122,"props":1714,"children":1715},{"class":124,"line":151},[1716],{"type":33,"tag":122,"props":1717,"children":1718},{},[1719],{"type":38,"value":1263},{"type":33,"tag":122,"props":1721,"children":1722},{"class":124,"line":160},[1723],{"type":33,"tag":122,"props":1724,"children":1725},{},[1726],{"type":38,"value":1727},"  OutputModels = OutputModels,\n",{"type":33,"tag":122,"props":1729,"children":1730},{"class":124,"line":188},[1731],{"type":33,"tag":122,"props":1732,"children":1733},{},[1734],{"type":38,"value":1735},"  select_model = best_model_id,\n",{"type":33,"tag":122,"props":1737,"children":1738},{"class":124,"line":212},[1739],{"type":33,"tag":122,"props":1740,"children":1741},{},[1742],{"type":38,"value":1743},"  export = TRUE,\n",{"type":33,"tag":122,"props":1745,"children":1746},{"class":124,"line":227},[1747],{"type":33,"tag":122,"props":1748,"children":1749},{},[1750],{"type":38,"value":1751},"  export_location = \"\u002Fdata\u002Fmmm_output\u002F\"\n",{"type":33,"tag":122,"props":1753,"children":1754},{"class":124,"line":251},[1755],{"type":33,"tag":122,"props":1756,"children":1757},{},[1758],{"type":38,"value":427},{"type":33,"tag":34,"props":1760,"children":1761},{},[1762],{"type":38,"value":1763},"File esportati:",{"type":33,"tag":1196,"props":1765,"children":1766},{},[1767,1778,1789],{"type":33,"tag":1200,"props":1768,"children":1769},{},[1770,1776],{"type":33,"tag":64,"props":1771,"children":1773},{"className":1772},[],[1774],{"type":38,"value":1775},"saturate_curves.png",{"type":38,"value":1777}," — Per ogni canale, spesa vs. risposta. Asse X: spesa, asse Y: ricavi previsti. La curva si appiattisce al punto di saturazione.",{"type":33,"tag":1200,"props":1779,"children":1780},{},[1781,1787],{"type":33,"tag":64,"props":1782,"children":1784},{"className":1783},[],[1785],{"type":38,"value":1786},"adstock_curves.png",{"type":38,"value":1788}," — Profilo di decadimento. Asse X: settimana, asse Y: moltiplicatore adstock. Per la TV, puoi vedere decadimento di 6-8 settimane.",{"type":33,"tag":1200,"props":1790,"children":1791},{},[1792,1798],{"type":33,"tag":64,"props":1793,"children":1795},{"className":1794},[],[1796],{"type":38,"value":1797},"waterfall.png",{"type":38,"value":1799}," — Decomposizione dei ricavi: base + stagionalità + contributo per canale.",{"type":33,"tag":34,"props":1801,"children":1802},{},[1803],{"type":38,"value":1804},"Con questi grafici, comunichi al CMO non \"Aumenta la spesa in TV del 30%\", ma \"La TV è al punto di saturazione; spostando il 20% su ricerca, l'ROI totale aumenta del 12%\".",{"type":33,"tag":41,"props":1806,"children":1808},{"id":1807},"pipeline-di-produzione-dbt-robyn-looker-studio",[1809],{"type":38,"value":1810},"Pipeline di produzione: dbt + Robyn + Looker Studio",{"type":33,"tag":34,"props":1812,"children":1813},{},[1814,1816,1825],{"type":38,"value":1815},"MMM non è un'analisi una tantum — richiede aggiornamento settimanale. Con l'approccio di Roibase per ",{"type":33,"tag":1817,"props":1818,"children":1822},"a",{"href":1819,"rel":1820},"https:\u002F\u002Fwww.roibase.com.tr\u002Fit\u002Ffirstparty",[1821],"nofollow",[1823],{"type":38,"value":1824},"First-Party Veri & Ölçüm Mimarisi",{"type":38,"value":1826},", la pipeline è:",{"type":33,"tag":1828,"props":1829,"children":1830},"ol",{},[1831,1849,1915],{"type":33,"tag":1200,"props":1832,"children":1833},{},[1834,1839,1841,1847],{"type":33,"tag":56,"props":1835,"children":1836},{},[1837],{"type":38,"value":1838},"dbt",{"type":38,"value":1840},": Crea la tabella ",{"type":33,"tag":64,"props":1842,"children":1844},{"className":1843},[],[1845],{"type":38,"value":1846},"mmm_input",{"type":38,"value":1848}," dagli eventi raw di BigQuery (query SQL sopra). Esecuzione programmata dbt Cloud ogni lunedì 00:00.",{"type":33,"tag":1200,"props":1850,"children":1851},{},[1852,1857,1859,1864,1866,1871,1873,1878,1880,1886,1888,1893,1894,1899,1900,1906,1907,1913],{"type":33,"tag":56,"props":1853,"children":1854},{},[1855],{"type":38,"value":1856},"Script R Robyn",{"type":38,"value":1858},": Eseguito in un container Cloud Run. Estrae ",{"type":33,"tag":64,"props":1860,"children":1862},{"className":1861},[],[1863],{"type":38,"value":1846},{"type":38,"value":1865}," con ",{"type":33,"tag":64,"props":1867,"children":1869},{"className":1868},[],[1870],{"type":38,"value":897},{"type":38,"value":1872},", chiama ",{"type":33,"tag":64,"props":1874,"children":1876},{"className":1875},[],[1877],{"type":38,"value":1311},{"type":38,"value":1879},", scrive output su BigQuery (tabella ",{"type":33,"tag":64,"props":1881,"children":1883},{"className":1882},[],[1884],{"type":38,"value":1885},"mmm_output",{"type":38,"value":1887},": ",{"type":33,"tag":64,"props":1889,"children":1891},{"className":1890},[],[1892],{"type":38,"value":455},{"type":38,"value":314},{"type":33,"tag":64,"props":1895,"children":1897},{"className":1896},[],[1898],{"type":38,"value":709},{"type":38,"value":314},{"type":33,"tag":64,"props":1901,"children":1903},{"className":1902},[],[1904],{"type":38,"value":1905},"roi",{"type":38,"value":314},{"type":33,"tag":64,"props":1908,"children":1910},{"className":1909},[],[1911],{"type":38,"value":1912},"predicted_revenue",{"type":38,"value":1914},").",{"type":33,"tag":1200,"props":1916,"children":1917},{},[1918,1923,1925,1930],{"type":33,"tag":56,"props":1919,"children":1920},{},[1921],{"type":38,"value":1922},"Looker Studio",{"type":38,"value":1924},": Alimentato da ",{"type":33,"tag":64,"props":1926,"children":1928},{"className":1927},[],[1929],{"type":38,"value":1885},{"type":38,"value":1931},", mostra dashboard di trend ROI per canale, curve di saturazione e raccomandazioni di budget.",{"type":33,"tag":34,"props":1933,"children":1934},{},[1935],{"type":38,"value":1936},"Pacchetti il container con Dockerfile:",{"type":33,"tag":112,"props":1938,"children":1942},{"className":1939,"code":1940,"language":1941,"meta":17,"style":17},"language-dockerfile shiki shiki-themes github-dark","FROM rocker\u002Ftidyverse:4.2.0\nRUN R -e \"install.packages('Robyn', repos='https:\u002F\u002Fcloud.r-project.org')\"\nRUN R -e \"install.packages('bigrquery')\"\nCOPY run_mmm.R \u002Fapp\u002Frun_mmm.R\nCMD [\"Rscript\", \"\u002Fapp\u002Frun_mmm.R\"]\n","dockerfile",[1943],{"type":33,"tag":64,"props":1944,"children":1945},{"__ignoreMap":17},[1946,1954,1962,1970,1978],{"type":33,"tag":122,"props":1947,"children":1948},{"class":124,"line":125},[1949],{"type":33,"tag":122,"props":1950,"children":1951},{},[1952],{"type":38,"value":1953},"FROM rocker\u002Ftidyverse:4.2.0\n",{"type":33,"tag":122,"props":1955,"children":1956},{"class":124,"line":151},[1957],{"type":33,"tag":122,"props":1958,"children":1959},{},[1960],{"type":38,"value":1961},"RUN R -e \"install.packages('Robyn', repos='https:\u002F\u002Fcloud.r-project.org')\"\n",{"type":33,"tag":122,"props":1963,"children":1964},{"class":124,"line":160},[1965],{"type":33,"tag":122,"props":1966,"children":1967},{},[1968],{"type":38,"value":1969},"RUN R -e \"install.packages('bigrquery')\"\n",{"type":33,"tag":122,"props":1971,"children":1972},{"class":124,"line":188},[1973],{"type":33,"tag":122,"props":1974,"children":1975},{},[1976],{"type":38,"value":1977},"COPY run_mmm.R \u002Fapp\u002Frun_mmm.R\n",{"type":33,"tag":122,"props":1979,"children":1980},{"class":124,"line":212},[1981],{"type":33,"tag":122,"props":1982,"children":1983},{},[1984],{"type":38,"value":1985},"CMD [\"Rscript\", \"\u002Fapp\u002Frun_mmm.R\"]\n",{"type":33,"tag":34,"props":1987,"children":1988},{},[1989],{"type":38,"value":1990},"Attivi con Cloud Scheduler ogni lunedì 06:00. Robyn con 2000 iterazioni richiede ~20 minuti (con 8 core).",{"type":33,"tag":41,"props":1992,"children":1994},{"id":1993},"riallocazione-del-budget-decisioni-dalla-frontiera-di-pareto",[1995],{"type":38,"value":1996},"Riallocazione del budget: decisioni dalla frontiera di Pareto",{"type":33,"tag":34,"props":1998,"children":1999},{},[2000,2002,2008],{"type":38,"value":2001},"L'output più potente di Robyn è l'ottimizzatore di budget. La funzione ",{"type":33,"tag":64,"props":2003,"children":2005},{"className":2004},[],[2006],{"type":38,"value":2007},"robyn_allocator()",{"type":38,"value":2009}," ridistribuisce il budget tra canali per massimizzare i ricavi totali:",{"type":33,"tag":112,"props":2011,"children":2013},{"className":902,"code":2012,"language":904,"meta":17,"style":17},"AllocatorCollect \u003C- robyn_allocator(\n  InputCollect = InputCollect,\n  OutputCollect = OutputModels,\n  select_model = best_model_id,\n  scenario = \"max_response\",\n  channel_constr_low = c(0.7, 0.7, 0.5),  # Google, Meta, TV: mantenere min 70%, 70%, 50%\n  channel_constr_up = c(1.5, 1.5, 2),     # Max 150%, 150%, 200%\n  expected_spend = 500000,                # Budget totale\n  expected_spend_days = 90\n)\n",[2014],{"type":33,"tag":64,"props":2015,"children":2016},{"__ignoreMap":17},[2017,2025,2032,2040,2047,2055,2063,2071,2079,2087],{"type":33,"tag":122,"props":2018,"children":2019},{"class":124,"line":125},[2020],{"type":33,"tag":122,"props":2021,"children":2022},{},[2023],{"type":38,"value":2024},"AllocatorCollect \u003C- robyn_allocator(\n",{"type":33,"tag":122,"props":2026,"children":2027},{"class":124,"line":151},[2028],{"type":33,"tag":122,"props":2029,"children":2030},{},[2031],{"type":38,"value":1263},{"type":33,"tag":122,"props":2033,"children":2034},{"class":124,"line":160},[2035],{"type":33,"tag":122,"props":2036,"children":2037},{},[2038],{"type":38,"value":2039},"  OutputCollect = OutputModels,\n",{"type":33,"tag":122,"props":2041,"children":2042},{"class":124,"line":188},[2043],{"type":33,"tag":122,"props":2044,"children":2045},{},[2046],{"type":38,"value":1735},{"type":33,"tag":122,"props":2048,"children":2049},{"class":124,"line":212},[2050],{"type":33,"tag":122,"props":2051,"children":2052},{},[2053],{"type":38,"value":2054},"  scenario = \"max_response\",\n",{"type":33,"tag":122,"props":2056,"children":2057},{"class":124,"line":227},[2058],{"type":33,"tag":122,"props":2059,"children":2060},{},[2061],{"type":38,"value":2062},"  channel_constr_low = c(0.7, 0.7, 0.5),  # Google, Meta, TV: mantenere min 70%, 70%, 50%\n",{"type":33,"tag":122,"props":2064,"children":2065},{"class":124,"line":251},[2066],{"type":33,"tag":122,"props":2067,"children":2068},{},[2069],{"type":38,"value":2070},"  channel_constr_up = c(1.5, 1.5, 2),     # Max 150%, 150%, 200%\n",{"type":33,"tag":122,"props":2072,"children":2073},{"class":124,"line":265},[2074],{"type":33,"tag":122,"props":2075,"children":2076},{},[2077],{"type":38,"value":2078},"  expected_spend = 500000,                # Budget totale\n",{"type":33,"tag":122,"props":2080,"children":2081},{"class":124,"line":27},[2082],{"type":33,"tag":122,"props":2083,"children":2084},{},[2085],{"type":38,"value":2086},"  expected_spend_days = 90\n",{"type":33,"tag":122,"props":2088,"children":2089},{"class":124,"line":290},[2090],{"type":33,"tag":122,"props":2091,"children":2092},{},[2093],{"type":38,"value":427},{"type":33,"tag":34,"props":2095,"children":2096},{},[2097],{"type":38,"value":2098},"Tabella di output:",{"type":33,"tag":1328,"props":2100,"children":2101},{},[2102,2133],{"type":33,"tag":1332,"props":2103,"children":2104},{},[2105],{"type":33,"tag":1336,"props":2106,"children":2107},{},[2108,2113,2118,2123,2128],{"type":33,"tag":1340,"props":2109,"children":2110},{},[2111],{"type":38,"value":2112},"Canale",{"type":33,"tag":1340,"props":2114,"children":2115},{},[2116],{"type":38,"value":2117},"Spesa attuale",{"type":33,"tag":1340,"props":2119,"children":2120},{},[2121],{"type":38,"value":2122},"Spesa ottimizzata",{"type":33,"tag":1340,"props":2124,"children":2125},{},[2126],{"type":38,"value":2127},"Delta",{"type":33,"tag":1340,"props":2129,"children":2130},{},[2131],{"type":38,"value":2132},"Lift ricavi previsto",{"type":33,"tag":1351,"props":2134,"children":2135},{},[2136],{"type":33,"tag":1336,"props":2137,"children":2138},{},[2139,2144,2149,2154,2159],{"type":33,"tag":1358,"props":2140,"children":2141},{},[2142],{"type":38,"value":2143},"Google Search",{"type":33,"tag":1358,"props":2145,"children":2146},{},[2147],{"type":38,"value":2148},"200.000",{"type":33,"tag":1358,"props":2150,"children":2151},{},[2152],{"type":38,"value":2153},"180.000",{"type":33,"tag":1358,"props":2155,"children":2156},{},[2157],{"type":38,"value":2158},"-",{"type":33,"tag":1358,"props":2160,"children":2161},{},[],{"type":33,"tag":2163,"props":2164,"children":2165},"style",{},[2166],{"type":38,"value":2167},"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":2169},[2170,2171,2172,2173,2174,2175,2176,2177],{"id":43,"depth":151,"text":46},{"id":102,"depth":151,"text":105},{"id":981,"depth":151,"text":984},{"id":1237,"depth":151,"text":1240},{"id":1545,"depth":151,"text":1548},{"id":1681,"depth":151,"text":1684},{"id":1807,"depth":151,"text":1810},{"id":1993,"depth":151,"text":1996},"markdown","content:it:data:marketing-mix-modeling-robyn-setup-praktis.md","content","it\u002Fdata\u002Fmarketing-mix-modeling-robyn-setup-praktis.md","it\u002Fdata\u002Fmarketing-mix-modeling-robyn-setup-praktis","md",1782050754315]