ãã®è¨äºã¯
R Advent Calendar 202211æ¥ç®ã®è¨äºã§ãã
10æ¥ç®ã®è¨äºã«ã¯ãããããã®è¨äºã§ããã
Twitterã§ã¯å人çã«ãåãã°ã©ãããããããä½ã£ã¦ããããã人ãã¨ããèªèã§ããã®ã§ãããä»å㯠rtweet
ããã±ã¼ã¸ã使ã£ã¦Twitterã®ç»åãéãã¦ã
ãããã¢ãã¡ã¼ã·ã§ã³ã«ãã¦ããããã§ãããããã
ã¾ã èªãã§ããªãï¼ãã²è¡ã£ã¦ãã¦ãã ããããã®è¨äºã¯ã¨ã¦ãé·ãã®ã§ã
ãä¹ ãã¶ãã§ã
çµå±æ1æ稿ããã¾ã¾ãªããªãã£ãã§ãããå
æ°ã«ãã£ã¦ãã¾ãã
ã¢ãã«ã¬ã®è¨äºã§ãããã¨ããªãã®ã§ããã以ä¸ã®ãå ±åããã¾ãã
- çµå©ãã¾ãã
- PCè²·ãã¾ãã
- çµ±è¨æ¤å®ã¯ãã¡ã§ãã
- CTFå§ãã¾ãã
- 転è·ãã¾ã
- æ¥å¹´ããããããé¡ããã¾ã
å 容
ä»äºã¨å人çãªé楽ãå
¼ãã¦ä¸ææåå¼·ãã¦ããMarketing Mixed Modelã«ã¤ãã¦ã
ãã®ã³ã³ã»ããã¨Meta社ã®å®è£
ã§ããRobynãWalkthroughãããã¨æãã¾ãã
å®è¡ç°å¢
以ä¸ã®githubã«ããã§è¨è¿°ããã³ã¼ãã¯ç½®ãã¦ããã¾ãã
以ä¸ã®ç°å¢ã§åä½ãããã¦ãã¾ãã
Rã¯åªããã®ã§ããã¼ã¸ã§ã³4.0ããããªãåä½ããã¨æãã¾ãããã ããWSL2ä¸ã®Ubuntuã§ã¯æåä¸å¯©ã§ããã
Robynã¯reticulate
ããã±ã¼ã¸ãéãã¦ãè£ã§Pythonã使ã£ã¦ããã®ã§ããã
åã®ç°å¢ã§ã¯WSL2ã«condaç³»ãå
¥ããããªãã¦ãpipenv
ã®ä»®æ³ç°å¢ã使ãããã£ããã¨ãããã¾ãè¯ãçµæã«çµã³ã¤ããªãã£ãã®ãããããªãã§ãã
reticulate
ã®æåã¯ããããããªãã§ãããã»ãã·ã§ã³åä½ã§Pythonã®ä»®æ³ç°å¢ãä½ãããããªã®ã§ããã»ã©ã®ãã¨ããªããã°ãããã¥ã¡ã³ãéãã«ä»®æ³ç°å¢ãç«ã¦ã¦è¯ãã¨æãã¾ãã
- PC: Thinkpad T14 Gen3
- OS: windows 11
- RAM: 32GiB
- CPU: 12th Gen Intel(R) Core(TM) i7-1260P
- Rã®ãã¼ã¸ã§ã³: 以ä¸ã
> version _ platform x86_64-w64-mingw32 arch x86_64 os mingw32 crt ucrt system x86_64, mingw32 status major 4 minor 2.2 year 2022 month 10 day 31 svn rev 83211 language R version.string R version 4.2.2 (2022-10-31 ucrt) nickname Innocent and Trusting
対象èªè
- Rã¯è§¦ãããã©çµ±è¨çè«ã¯ããç¥ããªã
- MMMã«èå³ã¯ãããã©çè«ã®è©³ç´°ã«ã¾ã§è¸ã¿è¾¼ãã è°è«ã¯ä¸æ¦èã«ããã¦ã´ã¼ã«ãè¦ãã
éã«è¨ãã¨MMMã®ãããçµ±è¨çè«ã®ããã®çããã¯å¯¾è±¡èªè
ã§ã¯ãªããã§ããã©ã
ããã®ä¼ãæ¹ã¯ãã¡ã ããã¨ããã®ãããã°ãã²ã¨ãæãã¦ãã ããï¼ï¼ï¼ï¼
â» ãçè«ããããããã¦ã³çã«ç解ããã¹ãã ãã¨ããããããå²å¦çãªæ¹å¤ã¯ããã¤ããªãã§ãã
MMMã¨ã¯
å é§è ã®è¨è¿°
saltcockeyããã®è¨äºãTJOããã®è¨äºã§ã¯ã
MMMãä½ã表ç¾ãã¦ããã¢ãã«ã§ããããæä¸ã¨ãã¦ãåºåå¹æã®æç³»åä¸ã®æ³¢åããã表ç¾ããã¢ãã«ã¨ã¯ãªã«ããä¸å¯§ã«è¨è¿°ããã¦ãã¾ãã
æ¬è¨äºãèªã人ã¯Marketing Mixed Modelã«ã¤ãã¦ããããã£ã¦ãã人ããç¥ããªãããããã§ã¯ãªããããããªãã®ã§ãã¨ããããã©ããªã³ã³ã»ããã®ã¢ãã«ãªã®ããã©ãããåé¡ã«çããã¢ãã«ãªã®ãã«ã¤ãã¦è¨è¿°ãã¦ããã¾ãã
éã«è¨ãã¨MMMã®æã¤çµ±è¨ã¢ãã«ã¨ãã¦ã®åé¡ç¹ãæ¹å¤ã«ã¤ãã¦ã¯è°è«ãã¾ããããã¨ãã°ä»¥ä¸ã
- ã¢ãã«ã®å çæ§ã«ã¤ãã¦
- åºåã¨å©çææ¨ã¨ã®å æé¢ä¿ã«ã¤ãã¦
- æç³»åã¢ãã«ã®ãã©ã¡ã¼ã¿æ¨å®ã®å¦¥å½æ§ã«ã¤ãã¦ãã
ãªã©ã
ããã¾ã§å人ã®è¦è§£ãªã®ã§ãééã£ãç解ããã£ããæãã¦ãã ããã
MMMã®ã³ã³ã»ãã
Marketing Mixed Model(é¢åãªã®ã§MMMã¨ç¥ãã¾ã)ã¯ãåºåã®äºç®åã³åºåã®åå¿ãç¨ãã¦ã売ä¸éé¡ãæ¥åºå®¢æ°ãè³æè«æ±ãªã©ãä¼æ¥ã®å©çã«ç´çµããææã表ç¾ãããã¨ã§ãåºåãå©çã«ã©ãã ãå¹æãä¸ããããã説æã»è©ä¾¡ããã¢ãã«ã§ãã
Cockieã®å»æ¢ãªã©ãå人ã追ãããã«ãããªãWebåºåããããããå人ã追ããããã®ãå°é£ãªãã¹ã¡ãã£ã¢ã®åºåãç·åçã«è©ä¾¡ã§ããã¨ããç¹ã§ã2022å¹´ã¯ããããªè©±é¡ãå¤ãã£ãããªã¨å人çã«ã¯æãã¦ãã¾ãã
ã©ã®ããã«åºåã®å¹æã§å©çææ¨ã表ç¾ãããã¨ããã¨ãå帰ã¢ãã«ãåºæ¬ãã¬ã¼ã ã¯ã¼ã¯æ
ã£ã¦ãã¾ããå
·ä½çã«ã¯RobynãLightWeight MMMãã以ä¸ã®ãããªã¢ãã«æ§é ã¯å
±éãã¦ãã¾ãã
ããã§ã$t$ã¯æç³»åã«é¢ããã¤ã³ããã¯ã¹ã$f(.)$ã¯åºåäºç®ã»ã³ã¹ãã®ã©ã°å¹æãèæ ®ããããã®é¢æ°ã表ç¾ãã¦ãã¾ãããã®ç¹ã¯å¾è¿°ãã¾ãã
ããã®ä»è¦å ãã«ã¤ãã¦ã¯ããã¨ãã°ç«¶åã®ããã¢ã¼ã·ã§ã³ãªã©ãèªç¤¾ã®åºå以å¤ã«å©çææ¨ã«å½±é¿ãä¸ããããªè¦å ãæãã¾ãã
MMMã¯ããããåé
ã®å½±é¿åº¦ãæ¨å®ãããã¨ã§ãåºåã®å©çææ¨ã«å¯¾ããå¹æãè¨è¿°ã»èª¬æãã¾ãã
ãã©ã¡ã¼ã¿ãæ¨å®ã§ããã°ãä¸è¨ã®ã¢ãã«å¼ãæ´ç¨ãããã¨ã§ãåºåã®æè³åçç(ROI)ãç®åºãããã¨ãå¯è½ã§ãã
æ³å®å ¥åãã¼ã¿
å ¥åãã¼ã¿ã¯é¢ä¿åæãæ§ã ã«å®å¼åãã¦ãã¾ãããåºæ¬ã¯ä»¥ä¸ã®å¤æ°ãæç³»åã§å¿ è¦ã§ãã
- å©çææ¨(売ä¸ãæ¥åºå®¢æ°ãè³æè«æ±æ°ãªã©)
- åºåã¤ã³ãã¬ãã·ã§ã³(ã¡ãã£ã¢å¥)
- åºåã³ã¹ã(æä¸äºç®ã»ã¡ãã£ã¢å¥)
- ãã®ä»è¦å ã«é¢é£ããå¤æ°
- 天æ°ãæ°æ¸©
- 競åã®ããã¢ã¼ã·ã§ã³
- ãã¥ã¼ã¹
ç®çå¤æ°ã¨ãªãå©çææ¨ã¨ã説æå¤æ°ã§ããåºåã¤ã³ãã¬ãã·ã§ã³ã¾ãã¯äºç®ã¯å¿
é ã§ããã
ãã®ä»è¦å ã«ã¤ãã¦ã¯ãã£ã¦ããªãã¦ãè¯ãã§ããã¹ã¢ã¼ã«ã¹ã¿ã¼ããå¿åãããªããã¾ãã¯ãã®ä»è¦å ãèããã«ã¹ã¿ã¼ããã¦ãè¯ãããããã¾ããã
ãã¼ã¿ã®éã§ãããæ¥æ¬¡ãã¼ã¿ãé±æ¬¡ãã¼ã¿ã§2ï½3å¹´åãããã¨ãæã¾ããã¨è¨ãããæ°ããã¾ãã
ãã¡ãããã¡ãã£ã¢ã®æ½çããMMMã§è§£æ±ºãããåé¡ã®è¦æ¨¡ã«ããã®ã§ãããæ¥æã®åºåã®äºç®ãç®å®ããã®ã«ä½¿ããããã¨ãã£ãå ´åã¯ãæ°å¹´ã®ãã¼ã¿èç©ãå¿
è¦ã«ãªãã®ã§ã¯ãªãããªã¨æãã¾ãã
ãã®å ´åãæ¥æ¬¡ã§ããã°365Ã2=730ã¬ã³ã¼ãï½ã§ãããé±æ¬¡ã§ããã°52Ã2=104ã¬ã³ã¼ãï½ã§ãããã¼ã¿ãµã¤ã¨ã³ã¹ããã£ã¼ãã©ã¼ãã³ã°ãé¨ãããæ¨ä»ã®ãã¼ã¿äºæ
ã®ä¸ã§ã¯ã¨ã¦ãè¦æ¨¡ã®å°ãããã¼ã¿ã«ãªãã¨æãã¾ãã
ãã®ãããå°ãªããã¼ã¿ã§ããè¯ããã¼ã¿ããéãã¦ã使ããæ
å ±ãæ大é使ããããªã¢ããã¼ããéè¦ã«ãªã£ã¦ãããã§ãã
MMMã«ããããã©ã¡ã¼ã¿æ¨å®
MMMã¯æç³»åãã¼ã¿ãç¨ãã¾ãããã®ããç®çå¤æ°ã¯èªå·±ç¸é¢(èªå·±å
±åæ£)ãæã¡ã
æ®éã®å帰ã¢ãã«ãè¦è«ãã誤差é
ã®ç¬ç«æ§ãä¿è¨¼ããã¾ããã
ãã®ããé常ã®æ¨å®æ¹æ³ã§ã¯æ¨å®å¤ã®æ¨æºèª¤å·®ãä¸è´æ§ãæããããã©ã¡ã¼ã¿ã®ä»®èª¬æ¤å®ãä¿¡é ¼åºéãæ£ããè¨ç®ã§ãã¾ãã*1ã
ã¾ããæç³»åãã¼ã¿ã®ç¹å¾´ãã³ã³ããã¼ã«ã§ãã¦ããåºåã®ã¤ã³ãã¬ãã·ã§ã³ãã³ã¹ãã¯è¦ããä¸é£åãããããéå帰ã¢ãã«ã«ãããå¤éå
±ç·æ§ãæ¸å¿µããã¾ã*2ãå¤éå
±ç·æ§ãåå¨ããã¨ããã¡ããæ¨å®å¤ã®æ¨æºèª¤å·®ã大ãããªã£ã¦ãã¾ããããæ¤å®ãä¿¡é ¼åºéã«å¯¾ããä¿¡é ¼æ§ããããã¾ãã
ããããåé¡ãã¿ãªãã£ããã¨åé¿ããå¿
è¦ããããé¢ä¿åæè²ã
ã«åªåãéãã¦ããã¨ããã§ãã
ãã¨ãã°LightWeight MMMã¯é層ãã¤ãºã¢ãã«ãå°å
¥ãã¦ããããå
æãããã¨ãã¦ãã¾ãããå¾è¿°ã®ããã«Robynã§ã¯Ridgeå帰ã«ãã£ã¦å¤éå
±ç·æ§ã®å½±é¿ã軽æ¸ããã¦ãã¾ãã
åºåã®ãã©ã°ãå¹æ
æ¥å¸¸çæ´»ãæ¯ãè¿ãã¨ãåºåãè¦ããç¬éãã«ããããã®ååãè²·ãããã¨ãããããã®ãåºè¡ãããã¨æãè³ããã¨ãããã§ãããããåºåãè¦ã¦ãæ°æ¥ï½æ°é±éçµãå¾ãæ¥å¸¸ã®ãè²·ãç©ããæ£æ©ãªã©ã§ããã®ååãã¬ãã§ã¿ãããã¨ãããã¼ããã®ã¿ã¬ã³ããåºã¦ãCMã®ãåºããã«ãã£ãã®ããã¨ããçºè¦ããã¦ãååãæã«åã£ããããåºã«å
¥ã£ãããããã¨ã大ãã«èãããã¾ãã
ãããããã©ã°ãå¹æãAdstockå¹æã¨ãCarryoverå¹æã¨ãå¼ã³ã¾ãã
Robynã§ã¯geometric
ã¨weibull
ã®2ã¤ã®åå¸ãä»®å®ã§ãã¾ãããããã¯å
±éãã¦ãå½é±ã®åºåã®å¹æã¯ãããæ¸è¡°ç$\theta$ã«ãã£ã¦æ¸è¡°ããã¤ã¤ã次é±ã«ç¹°ãè¶ããããã¨ããä»®å®ãéãã¦ãåºåã®å¹æã表ç¾ãã¦ãã¾ãã
MMMã®åºå
åºæ¬çã«ãMMMã¯éå帰ã¢ãã«ã§è¡¨ç¾ããããã®ãã©ã¡ã¼ã¿æ¨å®çµæããæ§ã ãªçµæææ¨ãè©ä¾¡ãã¾ãã
1. 精度
äºæ¸¬å¤ã¨å®æ¸¬å¤ã®ä¹é¢ããªããã¨ãæã¾ãããã¨ã¯MMMãä¾å¤ã§ã¯ããã¾ãããRobynãLightWeight MMM両æ¹ã¨ããäºæ¸¬ã¨å®æ¸¬ã®ä¹é¢åº¦ãè©ä¾¡ãã¾ãã
ã¾ãããã¸ãã¹èª²é¡ã«ãã£ã¦ã¯éå°é©å(éå¦ç¿)ãæã¾ãããªãå ´åãããã®ã§ã
ã¯ãã¹ããªãã¼ã·ã§ã³ãè¨è¨ãããã¨ãæå¹ã ã¨æãã¾ã*3ã
2. ãã©ã¡ã¼ã¿æ¨å®å¤
ãããããå帰ä¿æ°ãã®ãããªãã®ã§ããå¾è¿°ã®ãè¦å å解ãã«ç¨ãã¾ãã
3. è¦å å解
ã売ä¸ãåºåã¡ãã£ã¢ã§èª¬æãããã¨ãã¦ãã©ã®ã¡ãã£ã¢ãã©ã®ç¨åº¦å£²ä¸ãæ§æãã¦ãããï¼ãã表ç¾ãã¾ãããã¨ãã°ãã¬ãCMã売ä¸ã®40%ãå ãã¦ãã¦ã競åã®ããã¢ã¼ã·ã§ã³ã10%ç¨åº¦å£²ä¸ããæ¼ãä¸ããã¦ãããã¨ãããããªè§£éãéãã¦ææ決å®ãåºæ¥ã¾ãã
ãã®è¦å å解ã«åºã¥ããã¨ã§ã次ã®æã®åºåäºç®ããã©ã®ã¡ãã£ã¢ã«ã©ã®ç¨åº¦å²ãå½ã¦ããã¨ã§ã売ä¸ããæãããã¨ããã·ãã¥ã¬ã¼ã·ã§ã³(äºç®ã¢ãã±ã¼ã·ã§ã³)ãå¯è½ã§ãã
4. åå¿æ²ç·
åºåã®äºç®æè³ã¨ãã®åå¿ãã©ããã£ãé¢ä¿æ§ãæã¤ã®ããã¢ãã«åãã¾ãã
ãã¨ãã°ãWebåºåã«æä¸ããäºç®ã¯ã©ããããå¹ççã«ä½¿ããã¦ããã®ãï¼ãã«çãã¾ãã
ããã§ã¯ãä¸å®éã®åºåæä¸ã¯å¿
è¦ã§ããããæä¸ã®ãéãã¯ãããå¹çãæªããã¨ãããããªæè³å¹çã®å¤åã表ç¾ããäºãå¤ãã¨æãã¾ãããã®ä»®èª¬ã表ç¾ããããã«ãSåãã®æ²ç·ã§ãã£ããã対æ°æ²ç·ã§ãã£ããã§åå¿æ²ç·ãã¢ãã«åãããã©ã¡ã¼ã¿ãæ¨å®ãã¾ãã
Robynã§ã¯hillé¢æ°ãLightWeight MMMã§ã¯carryoverã¢ãã«ãAdstockã¢ãã«ãhill-Adstockã¢ãã«ã®3ã¤ããé¸ã¹ãããã«ãªã£ã¦ãã¾ãã
ã¤ããã
ããã¾ã§MMMã®ã³ã³ã»ããé¨åã«ã¤ãã¦è¨è¿°ãã¾ããã
- RobynãLightWeight MMMãåºæ¬çã«ã¯ãå帰ã¢ãã«ããä»®å®ãã¦ãã
- åºåæè³å¹æã«ã¯ãæè³å¹æéæ¸ããä»®å®ãã¦ãã
- ä»®å®ã«åºã¥ãã¦æ¨è«ããããããè¤æ°ã®çµæãå¾ããã¨ã§ãç·åçã«ææ決å®ãè¡ã
- å ´åã«ãã£ã¦ã¯å°æ¥çãªåºåäºç®é åã®ã·ãã¥ã¬ã¼ã·ã§ã³ãå¯è½
éè¦ã§ããã®ã¯ãMMMã¯åºåã¨å©çææ¨ã¨ã®éã«ããé¢ä¿æ§ã«ã¤ãã¦ããã¤ãã®ä»®å®ã®ãã¨ã§ã¢ãã«åãã表ç¾ãã¦ããã¨ããç¹ã«ããã¾ãã
ãã®ã¢ãã«èªä½ã¯ã·ã³ãã«ã§ãããªããæ±ç¨çãªãè¯ãã¢ãã«ãã ã¨æã£ã¦ãã¦ã
åºåã¨å©çææ¨ã¨ã®é¢ä¿æ§ã¯æ¥ç¨®ãåæã«ãã£ã¦ä¸å®ç¨åº¦å
±éããæ§é ã ã¨ã¯æãã¾ãã
ä¸æ¹ã§ããã©ã¡ã¼ã¿ã®å¤§å°ã§ã¯ãªããã¢ãã«ã«ç¨ãã¦ããé¢æ°å½¢ã大ããç°ãªããã¨ãæ³å®ãããååã»ãµã¼ãã¹ã§ããå ´åããã®æ§é ããªãªã¸ãã«ã§æ§ç¯ããå¿
è¦ãããã¨æãã¾ãã
Robynã§MMMãæ§ç¯ããåã«ãåºæ¬çãªéè¨ãæ¢ç´¢çãªåæãè¡ã£ã¦ã
Robynãæ³å®ããã¢ãã«ã§è¡¨ç¾ã§ãããããå°ãæ¤è¨ããã»ããè¯ãããããã¾ããã
å®è£
Robynã¨ã¯
Robynã¯Meta社ãFacebookã ã£ãé ããéçºãã¦ããMMMã楽ã«å®è¡ããããã®OSSã§ãã
å¾è¿°ããããã«åå¦çãçµæã®å¯è¦åã«è³ãã¾ã§ãçµæãåºããã¾ã§ãã¨ã¦ãæ°æ¥½ã«ã§ããããã±ã¼ã¸ã§ããããã¦Rã§å®è£
ããã¦ããã¨ããç¹ãç´ æ´ãããã
ããã¥ã¡ã³ãã¯é¢æ°ã®èª¬æã ãã§ãªããã¢ããªã¹ãåãMMMã¬ã¤ããã¨ãããä¸è¨ã®MMMã«é¢ãã説æãæ°å¼ã使ããã«ç°¡æã«èª¬æãã¦ãã¦ãã¢ããªã³ã°ãå§ããåã®ããã¼ã¿ãåéããããã»ã¹ã§æ°ãã¤ããã¹ããã¨ã¨ã¯ä½ãããã¼ã¿ã®ã¬ãã¥ã¼ããã¦ç¢ºèªããã¹ããã¤ã³ãã¯ä½ããªã©ã大å¤ä¸å¯§ãªè¨è¼ãããã®ã§ãã¿ããªèªãã ã»ããããã¨æãã¾ãã
æ°å¼ãç解ããªãã¦ã誰ã§ãMMMãã§ããããã«ããã¨ããæå³ã§ãRobynã¯ã¨ã¦ãè¯ãã¨æãã¾ãã
ãã¼ã¿
kaggleã«MMMãããããããªãã¼ã¿ã»ããããã£ãã®ã§ããã¡ããæ´ç¨ãã¾ãã www.kaggle.com
æ¥æ¬¡æç³»åã§ãã©ãã§ã©ããªåºåãã©ã®ç¨åº¦ã®ã³ã¹ãã§æã£ã¦ã売ä¸ãã¤ã³ãã¬ãã·ã§ã³ãªã©ãã©ãã ãå¾ãããã®ããã¨ãããã¼ã¿ãä¸éãæã£ã¦ãã¾ãã
ä»åã¯Robynã§MMMãè¡ãä¸ã§å¿
è¦ãªãã¼ã¿ã«çµã£ã¦ã·ã³ãã«ã«å®è¡ããããã«
- 売ä¸(
Sales
) - åºåã¤ã³ãã¬ãã·ã§ã³(
Impressions
) - æè³é(
Spend
)
ã«çµã£ã¦è°è«ãã¾ãã
åè:How To Create A Marketing Mix Model With LightweightMMM
åºæ¬ã¹ããã
Robynã¯åºæ¬çã«3ã¤ã®ã¹ããããè¸ãã°è¯ãè¨è¨ã§ãã
robyn_inputs
: ãã¼ã¿ã»ãããèªã¿è¾¼ã¿ãåå¦çãè¡ã- ãã®æ®µéã§å度確èªããæ¹ãè¯ãå¤æ°ãªã©ã«ã¤ãã¦ã¯
warnings
ãåºã¦ããã¾ãã - åå¦çãè¡ã£ãä¸ã§ãå種ãã©ã¡ã¼ã¿ãæ¨å®ããä¸ã§ã®ãã¤ãã¼ãã©ã¡ã¼ã¿ãè¨å®ã§ãã¾ãã
- ãã®æ®µéã§å度確èªããæ¹ãè¯ãå¤æ°ãªã©ã«ã¤ãã¦ã¯
robyn_run
: ã¢ãã«ã®å®è¡ã»ãã©ã¡ã¼ã¿ã®æ¨å®- ããã©ã«ãã§ã¯5Chainããããåãã¦ããã¾ããããããæéãããã
robyn_outputs
: åæçµæã®åºå- ãããããããã¢ãã«ã®åæçµæã«ã¤ãã¦ãã©ã«ããèªåçæãããã
- ãã®ä¸ã«
png
å½¢å¼ã§ã®ã°ã©ãã¨ãcsv
å½¢å¼ã§ã®æ°è¡¨ã¨ãã¦åºåãããã - çµæã®ã°ã©ããæ£é¸ãããã¨ãªããããã¸ã§ã¯ããã©ã«ãããããã«ä½¿ããç¹ã¯ã¨ã¦ããã
robyn_allocator
(ãªãã·ã§ã³):ã·ããªãªãç½®ãã¦ãåºåäºç®ã®æé©åã·ãã¥ã¬ã¼ã·ã§ã³ãè¡ãã- 大ãã以ä¸ã®2ã¤ã®ã·ããªãªã§ã·ãã¥ã¬ã¼ã·ã§ã³ãã§ãã
- åãåºåäºç®ã§ãã£ãå ´åã«ããå©çãä¸ãããã¨ãæå¾ ã§ãããããªã¡ãã£ã¢é åãã©ã³ã¹
- åºåäºç®ãä¸ããä¸ã§ãå©çãæ大åãããããªã¡ãã£ã¢é åãã©ã³ã¹
ãã®ä»ãæ°ãããã¼ã¿ãå ¥ã£ãã¨ãã®ã¢ãã«ã®ãã¥ã¼ãã³ã°ãå²ã¨ç°¡åã«ã§ãã¾ãããä»åã¯çç¥ã
step1: robyn_inputs
ãã¼ã¿ã®åå¦çé¨åããå ¥ãã¾ãã
# loading packages library(reticulate) library(Robyn) library(tidyverse) library(readxl) # setup clean python virtual environment virtualenv_create("r-reticulate") py_install("nevergrad", pip = TRUE) use_virtualenv("r-reticulate", required = TRUE) # load data usedata <- readxl::read_excel("./input/kaggle_ad_data.xlsx") ##### çç¥ï¼è©³ç´°ã¯githubå´ã§ç¢ºèªãã ãã ##### robyn_usedata <- media_data %>% dplyr::left_join(costs_data, by = "Date") %>% dplyr::left_join(sales_target, by = "Date")
Rããããã°å¤§ä½ããã£ã¦ãããã¨æãã¾ããæ¬å½ã¯ä»¥ä¸ã®ã³ã¼ãã
Robyn::robyn_inputs()
ã使ã£ã¦ãä¸è¨ãã¼ã¿ãRobynã«æ¸¡ãã¾ãã
# make input data InputCollect <- Robyn::robyn_inputs( dt_input = robyn_usedata, # 使ããã¼ã¿ãã¬ã¼ã date_var = "Date", # æ¥ä»ã®å¤æ°å dep_var = "Sales", # ç®çå¤æ° dep_var_type = "revenue", # ç®çå¤æ°ã®å±æ§(売ä¸ãã³ã³ãã¼ã¸ã§ã³ã) # prophetãç¨ããæç³»åã®ãã³ã³ãã¸ã·ã§ã³ã # holidayã¯çç¥ãã¦ããããæ¥æ¬ã®ç¥æ¥ã¯prophetããæã£ã¦ããããã« # å°ãPythonã§ã¹ã¯ãªãããçµãå¿ è¦ããã prophet_vars = c("trend", "season", "weekday"), prophet_country = "US", paid_media_spends = costs_col_names, # ã¡ãã£ã¢æè³å¤æ° paid_media_vars = media_col_names, # ã¡ãã£ã¢ã®ã¤ã³ãã¬ãã·ã§ã³ # ã¡ãã£ã¢å¤æ°ã®ä¿æ°ã®æ£è² ãåºæ¬ã¯ãæ£ãã§è¯ããã # ãã¨ãã°ç«¶åããã¢ã¼ã·ã§ã³ããçä¸ãããã£ãé ç®ã¯ãè² ãæ±ãã paid_media_signs = rep("positive", length(media_col_names)), # æç³»åã®ç¯å²ãè¨å®ãããtrain-test splitãªã©ã¯ããã§ã»ããã£ã³ã°ã§ããã window_start = "2021-10-17", window_end = "2022-01-11", # åºåã®ãã©ã°ãã®ã¢ãã«æå®ãä»åã¯è¨ç®ã¹ãã¼ããå ¼ãã¦geometricã adstock = "geometric" )
ãã¤ãã¼ãã©ã¡ã¼ã¿ã®èª¿æ´ããä¸å®ç¨åº¦ã¬ã¤ããããã¾ãã
ç¹°ãè¿ãã®ããã³ã¼ãã«ãªã£ã¦ããã®ã§ãããã§ã¯ãªãã®ã§ããã
åãã¤ãã¼ãã©ã¡ã¼ã¿ã®æ¢ç´¢ç¯å²ãå®ãã¦ãã¾ãã
# hyperparameter setup hyperparameter_names <- Robyn::hyper_names( adstock = InputCollect$adstock, all_media = InputCollect$all_media ) ##### çç¥ï¼è©³ç´°ã¯githubå´ã§ç¢ºèªãã ãã ##### hyper_params <- cbind( hyper_params_from, hyper_params_to ) %>% t %>% as.data.frame colnames(hyper_params) <- hyper_params_names hyper_params <- as.list(hyper_params) # error not found, but not defined the hyperparameter. InputCollect <- Robyn::robyn_inputs( InputCollect = InputCollect, hyperparameters = hyper_params )
ä»åã¯ä»¥ä¸ã®ãããªwarnings
ãåºã¦ãã¾ãã
ãã¼ã¿ã®ãã§ãã¯ãåå¦çã®æ®µéã§ãã£ããã£ã³ã°ãåä¸ãããããã«ãã¼ã¿ãsplitãããã
Impressionã§ã¯ãªãSpendã使ãã¨ããããã¨ããªã¹ã¹ã¡ããã¾ãã
Robynã«çªã£è¾¼ãåã«ãã¼ã¿ã¬ãã¥ã¼ãè¡ããã¨ã¯åæã§ããããã®ä¸ã§ããã®ããã«ã¬ã³ã¡ã³ããè¿ãã¦ãããã®ã¯ã¨ã¦ãåªããã§ããã
ãããåºãããã«ä»åã¯æªããã¼ã¿ãå
¥ãã¦ããç¯ãããã¾ãâ¦â¦ã
>> Running feature engineering... NOTE: potential improvement on splitting channels for better exposure fitting. Threshold (Minimum R2) = 0.8 Check: InputCollect$plotNLSCollect outputs Check data on: "Impressions_Brand_1_Ad_Group_10", "Impressions_Brand_1_Ad_Group_11", "Impressions_Brand_1_Ad_Group_3", "Impressions_Brand_1_Ad_Group_5", "Impressions_Brand_1_Ad_Group_7", "Impressions_Brand_1_Ad_Group_8", "Impressions_Brand_2_Ad_Group_5", "Impressions_Brand_2_Ad_Group_6" Warning messages: 1: In .font_global(font, quiet = FALSE) : Font 'Arial Narrow' is not installed, has other name, or can't be found 2: In fit_spend_exposure(dt_spendModInput, mediaCostFactor[i], paid_media_vars[i]) : Spend-exposure fitting for Impressions_Brand_1_Ad_Group_3 has rsq = 0.6488 To increase the fit, try splitting the variable. Otherwise consider using spend instead. 3: In fit_spend_exposure(dt_spendModInput, mediaCostFactor[i], paid_media_vars[i]) : Spend-exposure fitting for Impressions_Brand_1_Ad_Group_5 has rsq = 0.3885 To increase the fit, try splitting the variable. Otherwise consider using spend instead. 4: In fit_spend_exposure(dt_spendModInput, mediaCostFactor[i], paid_media_vars[i]) : Spend-exposure fitting for Impressions_Brand_1_Ad_Group_7 has rsq = 0.6573 To increase the fit, try splitting the variable. Otherwise consider using spend instead. 5: In fit_spend_exposure(dt_spendModInput, mediaCostFactor[i], paid_media_vars[i]) : Spend-exposure fitting for Impressions_Brand_2_Ad_Group_6 has rsq = 0.6145 To increase the fit, try splitting the variable. Otherwise consider using spend instead. 6: In robyn_engineering(InputCollect, ...) : R2 (nls): weak relationship for "Impressions_Brand_1_Ad_Group_1", "Impressions_Brand_1_Ad_Group_10", "Impressions_Brand_1_Ad_Group_11", "Impressions_Brand_1_Ad_Group_13", "Impressions_Brand_1_Ad_Group_2", "Impressions_Brand_1_Ad_Group_3", "Impressions_Brand_1_Ad_Group_5", "Impressions_Brand_1_Ad_Group_6", "Impressions_Brand_1_Ad_Group_7", "Impressions_Brand_1_Ad_Group_8", "Impressions_Brand_2_Ad_Group_1", "Impressions_Brand_2_Ad_Group_2", "Impressions_Brand_2_Ad_Group_3", "Impressions_Brand_2_Ad_Group_4", "Impressions_Brand_2_Ad_Group_5", "and Impressions_Brand_2_Ad_Group_6" and their spend 7: In robyn_engineering(InputCollect, ...) : R2 (lm): weak relationship for "Impressions_Brand_1_Ad_Group_10", "Impressions_Brand_1_Ad_Group_11", "Impressions_Brand_1_Ad_Group_3", "Impressions_Brand_1_Ad_Group_5", "Impressions_Brand_1_Ad_Group_7", "Impressions_Brand_1_Ad_Group_8", "Impressions_Brand_2_Ad_Group_5", "and Impressions_Brand_2_Ad_Group_6" and their spend
step2: robyn_run
Robynã§ã®åæã®å®è¡ã¯Robyn::robyn_run
ã§åºæ¥ã¾ãã
ä¸è¨ã®å¤§éã®ãªãã¸ã§ã¯ããå«ãInputCollect
ãå
¥ãã¦ãããã¤ãã®è¨å®ãè¨è¼ãããã¨ã§ã
åæã«å®è¡ãå¯è½ã§ãã
注æã¨ãã¦ãrobyn_run
ã§ã¯èå¾ã«nevergrad
ã使ã£ã¦ããã®ã§ããããããreticulate
ãéãã¦ä»®æ³ç°å¢ä¸ã«ã¤ã³ã¹ãã¼ã«ãã¦ããå¿
è¦ãããããããã¾ããã
OutputModels <- Robyn::robyn_run( InputCollect = InputCollect, iterations = 15000, trials = 5, outputs = FALSE ) OutputModels$convergence$moo_distrb_plot OutputModels$convergence$moo_cloud_plot
step3: robyn_outputs
Robyn::robyn_outputs
ã使ãã¨ãä»»æã®ãã©ã«ãã«çµæãä¸éãæ ¼ç´ããã¾ãã
ãã®ç¹ãé常ã«ããããããrobyn_outputs
ãå®è¡ããã°ãã©ã«ããåæã«ä½ããã
ããã«ãã¹ã¦ã®çµæãã¢ã¦ããããããã¾ããä»åã¯ç´¹ä»ãã¾ããããcsvãã¡ã¤ã«ãåºåãããã®ã§ã
ãExcelã§ããããã¨è¨ããã¦ãå¹³æ°ã§ããã
ããã©ã«ãã§ã¯è¨å¤§ãªã¢ãã«ãã3ã¤é¸æããã¾ã*4ã
ãã®3ã¤ã®ã¢ãã«ããã©ã®ã¢ãã«ãæ¡ç¨ãããã¯ãåæè
ã«å§ãããã¾ãã
output_path <- "./output" OutputCollect <- Robyn::robyn_outputs( InputCollect = InputCollect, OutputModels = OutputModels, csv_out = "pareto", clusters = TRUE, plot_pareto = TRUE, plot_folder = output_path ) print(OutputCollect)
çµæã®ã°ã©ã
åºåçµæã«ã¤ãã¦ã¯ãRobynå´ã§ãè¯ããã¨å¤å®ããã¢ãã«ãï¼ï½ï¼åºã¦ãã¾ãã®ã§ã
ãã®çµæãè¦ãªããã精度ã¨å®åä¸è§£éã§ãããã©ãããå¤æããªããã¢ãã«ãé¸æãã¾ãã
ãã®æå³ã§æçµåè£ã®3ã¤ããã¢ãã«ã1ã¤ã«çµãããã®ãææ¨ãã¯æ確ã«ã¯åºã¦ãã¾ããã
ã精度ã¯ãããã©è¦å å解ã®ãã©ã³ã¹ããã³ããè¦å å解ã®ãã©ã³ã¹ã¯ãããã©ç²¾åº¦ããªããã¨ããé¨åã§ã
人éã¨ãã¦è½ã¨ãæãæ¢ãã¦ãããã¨ããã¹ã¿ã³ã¹ã ã¨ãç¾ç¶ã®åã¯æãã¦ãã¾ãã
ä»åã¯ç¹å®ã®ã¢ãã«ãé¸ã³ãçµæãçºãã¦ã¿ã¾ãããã
ã¾ãå³ä¸ã®ã°ã©ãã確èªããã¨ã波形ã¯æ¦ããã£ãããã¦ããããã«è¦ãã¾ãã
ä¸é¨ã®ã¹ãã¤ã¯ã«ã¯å¯¾å¦ãããã¦ããªãã®ã§è¦èª¿æ´ããããã¾ãããã
ã¤ãã§å³ä¸ã®æ®å·®ã«ã¤ãã¦ããã»ã¼ã»ã¼ç¡ç¸é¢ã®ããã§ãã追å ã§å¶å¾¡ããã¹ãå¤æ°ã¯èããªãã¦ãè¯ãããã§ãã
å·¦ä¸ã®ã¦ã©ã¼ã¿ã¼ãã©ã¼ã«ã°ã©ããè¦ããã¨ã§ãã©ã®ã¡ãã£ã¢ãã©ã®ç¨åº¦å£²ä¸ã«å¯ä¸ãã¦ãããããããã¾ãã
ã©ããSpend_Brand_2_Ad_Group_2
ãè²¢ç®ãã¦ããæ§åããã®ãã¼ã¿ã§ã¯ãå
·ä½çã«ã©ããã£ãSpendãªã®ãã¯ããããªãã®ã§ããããã¨ãã°ãããTVCMã§ããã°ããã¬ãé¢ããé²ãã§ããã¨ã¯è¨ããTVåºåã®ç¸®å°ã¯ã¾ã é£ãããããã¨è§£éããäºãã§ããããããã¾ããã
å·¦å´2çªãã®ã°ã©ãã¯ãåã¡ãã£ã¢ã®ROIãç®åºããã¦ãã¾ããSpend_Brand_1_Ad_Group_6
ãé常ã«é«ã(é«ãããï¼)ROIãã¯ããåºãã¦ãã¾ãããããé«ããããã©ããã¯ãã¡ã¤ã³ã«ãããããããã¾ããã®ã§ãæ°å¤ã¨ããã®ã¡ãã£ã¢ãæ¬å½ã«å¹çã®è¯ãã¡ãã£ã¢ã§ãããã¯ç¢ºèªã®ä½å°ãããã¾ãã
ãã®å³ã®ã°ã©ããæè³æ²ç·ã§ããæ²ç·ã¨ããã®å¹³åçãªæè³é¡ãç®åºããã¦ãã¾ãã
å·¦ä¸ã¯Adstockå¹æã®æ¨è¨ã§ããã©ã®ç¨åº¦Adstockå¹æãããããææ¡åºæ¥ã¾ãã
ãã¡ãã®ã¨ãã¾ã¨ãã°ã©ãã¯ããããå¥ã§é¢æ°ãè¨è¨ããã¦ããã®ã§ã
ç¬ç«ã«å®è¡ãããã¨ãã§ããã®ã§ãç´°ããè¦ããå ´åã¯ãããã使ãã¨è¯ãã¨æãã¾ãã
additional: robyn_allocator
ããã¾ã§ã§å®è¡ã¯çµãããªãã§ããã©ãMMMã®å¼·ã¿ã¯ãåºåäºç®ãè¨å®ããä¸ã§ããããã¡ãã£ã¢ã«é©åã«é
åããã«ã¯ï¼ãã¨ããåé¡ã«ãä¸å®ã®çããåºãã¦ããã¾ãã
ãã¡ãã£ã¢ ã¢ãã±ã¼ã·ã§ã³ãã¨å¼ã°ãããã¨ãããã¾ãã
ãã¡ãã¯å®åã«ã«ããã¦ãçµ±è¨çãªè§£æã¨è¨ãããã¯æ°çæé©ååé¡ã解ãã¦ããå ´é¢ãå¤ãããªã¨æãã¾ãã
# allocation best_model <- "1_694_1" all_spend <- robyn_usedata %>% dplyr::ungroup() %>% dplyr::select(-Date, -Sales, -contains("Impressions")) %>% apply(., 1, sum) %>% sum AllocationCollect_01 <- Robyn::robyn_allocator( InputCollect = InputCollect, OutputCollect = OutputCollect, select_model = best_model, scenario = "max_historical_response", channel_constr_low = 0.7, export=TRUE, date_min="2022-01-01", date_max="2022-01-11" )
ä»åã¯ãéå»ã®äºç®ã¨åãéé¡ãåºåã«æè³ããã¨ãã¦ã æé©ãªã¡ãã£ã¢ã¸ã®é
åæ¯çã¯ãããã«ãªããï¼ãã«çããè¨å®( max_historical_response
)ã§è¨ç®ãã
çµæã表示ãã¾ãã
è¦ãã«ãSpend_Brand_2_Ad_Group_1ã®æ¯çãä¸ãã¦ãä¸æ¹ã§Group2ã®æ¯çãä¸ããã¨è¯ããçãªã·ãã¥ã¬ã¼ã·ã§ã³çµæãåºã¦ããããã§ãã
ãã¨ãã°TVCMã«äºç®ãå²ãããã¦ããã¨ããããåãããã«äºç®ãå¾ãããå ´åãWebã«ããå°ãæ¯çãå²ãã¦ãããã®ããªï¼ã¨ãããããªçµæãè°è«ã§ãããã§ããããããã¼ã
ææ³ã»ææ
ãã¨ããããMMMããã£ã¦ã¿ãããã¨ããã¹ã¿ã¼ãã®å ´åãRobynã®åå¨ã¯ã¨ã¦ãè¯ãã¨æãã¾ãã
Rã§åæã®ããã®ãã¼ã¿ãæºåãããã¨ãã§ããç¨åº¦ã®ã³ã¼ãã£ã³ã°ãã§ããã°ããã³ããã¼ã¯ã¢ãã«ããããã¿ã¤ãã³ã°ãååã§ããããã«æ´åããã¦ãããã¨ã¦ã使ããããããã±ã¼ã¸ã§ãã
ä¸æ¹ã§ç´°ããªã«ã¹ã¿ãã¤ãº(ãã¨ãã°Adstockã«ç¬èªã®é¢æ°ãå®ç¾©ããã¨ããé層æ§é ã®ã¢ãã«ã¨ã)ã¯ãRobynã§éããå®è£
ã¯é£ããããã§ãã
æ¡å¼µæ§ã¯ãªãããã§ã¯ãªãããã§ãããã¨ãã°æ§é æ¹ç¨å¼ã¢ããªã³ã°ãæ´ç¨ããã¢ãã«ã®æ¡å¼µã®ä¾ã¯ãã§ã«å®è£
ä¾ãããã¾ãã
devpost.com
å人çã«ã¯LightWeight MMMã«è¿ãã¢ããã¼ãã§MMMã®æ§ç¯ããããã¨ãå¤ãã£ãã®ã§ãRobynã®ææ³ã«ã¯æ°ãããæãã¦ãã¾ããç¹ã«è¨å¤§ãªã¢ãã«ãçæãã¦ãã®ä¸ã§ãè¯ããã¢ãã«ã3ã¤ã¾ã§é¸ã³ããããã人ã®æå¿ã§æ±ºããã¨ããé¨åã¯ãè¯ãæå³ã§äººã®æ¨è«è½åãä¿¡é ¼ãã¦ãããªã¨æãã¾ãã
ã§ãLightWeight MMMã®çè«çã«ç´ ç´ã«ç©ã¿ä¸ããè¨è¨ã好ããªã®ã§ããã¨ãã°Robynã§ä¸æããããªãå ´åã«ã¯LightWeight MMMã®åãåããã¨è¨ãã®ãããããããã¾ããã
ã¡ãªã¿ã«: LightWeight MMMãMaMiMo
Robyn以å¤ã«MMMãå®ç¾ããOSSã¨ãã¦ãGoogleã®éçºãã¦ããLightWeight MMMMãããã¾ãã
Googleã¯MMMã«å¯¾ãã¦ãããã¤ãè«æã¨ãã¦çºä¿¡ãã¦ãã¾ãã
- Challenges And Opportunities In Media Mix Modeling
- Bayesian Methods for Media Mix Modeling with Carryover and Shape Effects
LightWeight MMMã¯åºæ¬çã«Pythonã§å®è£
ããã¦ãã¦ãè£ã§jax
ãåãã¦ããé½åä¸ãWindowsã§ã®å®è£
ã¯ãµãã¼ãããã¦ãã¾ãã*5ã
R Advent Calendarã§ãããã®è¨äºã§ã¯å®è£
å«ãã解説ããã¾ããã
ãã ãWalkthroughèªä½ã¯ãã¦ããã®ã§ãä½åãããã°ãã¡ããè¨äºã§ç´¹ä»ãã¾ãã
Rã§å®è£ ã§ããMMMã¯ä»ã«ãMaMiMoãããã¾ãã詳ããã¯åãããã£ã¦ãã¾ããã®ã§ãè¿ã使ã£ã¦ã¿ããã¨æã£ã¦ãã¾ãã
å é§è è¨äº(in Japanese)
MMMã¯æ¨ä»æ³¨ç®ãããã¢ãã«ãªã®ã§ããããããªå人ãæ³äººãç´¹ä»è¨äºãæ¸ãã¦ãã¾ãã
- saltcockey: Metaã®MMMããã±ã¼ã¸ Robynã試ãã¦ã¿ã
- Crosstab.inc : ãã¼ã±ã¿ã¼ã®ããã®Robynãç¨ããèªåMarketing Mix Modeling (MMM)
- åå ±å DYãã¼ã«ãã£ã³ã°ã¹ï¼ãã¼ã±ãã£ã³ã°ã»ãµã¤ã¨ã³ã¹ã«ãããå票ãã¼ã¿ã®èª²é¡ã¨Marketing Mix Modeling ã®ãåçºè¦ã
ç´è¿ã ã¨åå ±å ãã¬ãã¥ã¼è«æå½¢å¼ã§MMMã«è¨åãã¦ãã¦ãRobynã¨LMMMMã«é¢ãã¦ã®æ¯è¼ã(ç°¡åãªè¨è¿°ã§ãã)ãã¦ãã¾ããå®è£
ã«ããã£ã¦ã®ææ³ãéãã¨ããç¹ã¯ã¾ãã«ããæã£ã¦ãã¦ãå人çã«ã¯MMMã¨ããã°LMMMã®ææ³ãèªç¶ã«æãæµ®ãã°ãã¾ãããã ãããã®ã¢ããã¼ãã¯ç¾å®åé¡ã¨ã®ä¹é¢ã«ã¤ãã¦ãåççãªä»®å®ãç½®ãã調æ´ãã·ãã¢ãªå°è±¡ãããã使ãã®ãé£ããããã«æãã¾ãã
ãã®æå³ã§Robynã¯ãã¢ãã«ã¨ãã¦ã®å®æ度ã精度ã説æå¯è½æ§ã®ã妥åç¹ããæ¢ãã¢ããã¼ããåã£ã¦ããã¨ããç¹ã§ãå®åã«å¯ãæ·»ã£ãMMMãã§ãããã¨ããã®ã¯é¢ç½ãã¨ããã ãªã¨æãã¾ãã
*1:æ¨å®å¤èªä½ã®ä¸è´æ§ã¯ãã£ãã¯ã
*2:ãã¨ãã°è¤æ°ã¡ãã£ã¢ã§åºåãæã¤ãã¨ã§èªç¥ã売ä¸ãä¸ãããã¨ããæ¦ç¥ã¯ååèããããã¨æãã¾ã
*3:ããã¾ã§ã¬ããå¿ è¦ã¯ãªãtrain-test splitãè¡ãã ãã§ãããã¨æãã¾ããã§ãã¬ãããªãã¡ããã¨ãã£ãæ¹ãããã
*5:WSL2ã使ããã¨ã«ããå®è£ ã¯å¯è½