diff --git a/docs/source/example_notebooks/datasets/sale_attribution.csv b/docs/source/example_notebooks/datasets/sale_attribution.csv new file mode 100644 index 000000000..4459f38a3 --- /dev/null +++ b/docs/source/example_notebooks/datasets/sale_attribution.csv @@ -0,0 +1,548 @@ +,dsp_spend,sp_spend,dpv,discount,sale,activity_date,year,quarter,month,special_shopping_event,other_shopping_event +0,11864.79939007542,2609.702788651283,54954.82315031493,26167.824598765008,75554.4067306238,2023-01-01,2023,1,1,0,0 +1,11084.057109563157,2568.5405700077863,44907.06332439528,22340.00978019588,51372.31323039973,2023-01-02,2023,1,1,0,0 +2,16680.85094508223,2847.5766997879546,151643.91256440204,68301.74781275046,626394.8812144699,2023-01-03,2023,1,1,0,0 +3,15473.576264164849,2788.5158311368946,121173.34395492656,18906.05040207389,306000.2263379278,2023-01-04,2023,1,1,0,0 +4,10308.414301882533,2523.591011443533,36234.26733708955,18198.68956273316,34571.26049581097,2023-01-05,2023,1,1,0,0 +5,10232.30211262704,2528.959021650041,35453.504307967065,16288.18249725933,33723.320134863665,2023-01-06,2023,1,1,0,0 +6,18216.16798006628,2919.783223569294,197272.6279501113,8984.63606336424,744198.1045323798,2023-01-07,2023,1,1,0,0 +7,11668.72741723972,2600.899296446209,52302.8396910233,5347.027196956714,77628.33992848163,2023-01-08,2023,1,1,0,0 +8,17742.97177960391,2903.693774365427,182355.08294770832,61099.870067087,752215.4096822387,2023-01-09,2023,1,1,0,0 +9,19521.200436956075,2999.502631213432,242633.0504617637,68518.42881589451,1251600.909327514,2023-01-10,2023,1,1,0,0 +10,13072.598745355604,2661.3900465064344,73305.34724390542,18656.718008831747,125702.9974698234,2023-01-11,2023,1,1,0,0 +11,17761.2949817612,2898.8674525451147,182913.14446326287,18141.23748803216,643301.2362211496,2023-01-12,2023,1,1,0,0 +12,14509.752593369334,2738.228195643501,100020.673486747,29272.06627175945,219867.49623885463,2023-01-13,2023,1,1,0,0 +13,19230.29687085958,2984.0969155762773,231979.4219692092,114057.78461929904,1932066.0449237183,2023-01-14,2023,1,1,0,0 +14,11478.490998067044,2582.961976646522,49808.233523709685,20443.796680875414,62600.14600757819,2023-01-15,2023,1,1,0,0 +15,16786.622415122816,2842.926675693305,154525.16384653203,59376.57175928536,574744.6717199716,2023-01-16,2023,1,1,0,0 +16,12286.202707333829,2626.7037788916614,60954.2087830851,23692.934197452723,90031.05816948932,2023-01-17,2023,1,1,0,0 +17,18113.103822605663,2915.387206957196,193957.6320133564,11293.371081445184,719851.4748333456,2023-01-18,2023,1,1,0,0 +18,10847.299870870467,2568.480345484634,42130.9013296506,6369.218284557012,54017.2918878952,2023-01-19,2023,1,1,0,0 +19,13529.412597486313,2687.859027171765,81197.97102790904,17219.760865777374,150974.3200003951,2023-01-20,2023,1,1,0,0 +20,13297.682115449186,2687.484587511525,77136.29930230968,23834.09968108244,137163.91490532405,2023-01-21,2023,1,1,0,0 +21,13505.09815865617,2681.5393221371023,80762.53606162182,9221.420949534217,154421.4368663882,2023-01-22,2023,1,1,0,0 +22,10422.016675527972,2537.090082538033,37426.66054020553,8500.742821474036,42767.19908542279,2023-01-23,2023,1,1,0,0 +23,18109.20399297196,2929.292689247696,193841.7199383409,95327.59804197845,1239485.3795899283,2023-01-24,2023,1,1,0,0 +24,19495.868413942488,2984.9330347356404,241680.3390876149,28652.50067758249,1075118.6469193185,2023-01-25,2023,1,1,0,0 +25,18387.17976344641,2928.343351146349,202868.2922582592,93978.29645449486,1277437.139841997,2023-01-26,2023,1,1,0,0 +26,18072.976879964783,2925.151864839121,192686.27192183805,40717.693579269566,727864.1746053582,2023-01-27,2023,1,1,0,0 +27,19177.75808842361,2970.1450014755665,230077.09646720847,5324.767870304238,988735.2755026588,2023-01-28,2023,1,1,0,0 +28,17459.300970463046,2887.189246753852,173778.90086259515,20560.485211699604,585536.360776926,2023-01-29,2023,1,1,0,0 +29,16061.431060503195,2849.2923454484685,135472.4957954798,5001.300820144229,382963.7850829072,2023-01-30,2023,1,1,0,0 +30,12826.098207204155,2671.3973885640253,69288.28058330722,20627.503452125144,113283.6820311616,2023-01-31,2023,1,1,0,0 +31,16075.647775887195,2823.9773802631244,135800.54566311828,37843.72816183444,389555.48137490026,2023-02-01,2023,1,2,0,0 +32,13546.713834323898,2693.2794668641027,81513.58352231038,24392.778812971923,151302.4511161723,2023-02-02,2023,1,2,0,0 +33,18443.02568411344,2926.40463134506,204706.8715434989,74063.29186824437,1014372.0265444008,2023-02-03,2023,1,2,0,0 +34,13031.315973484836,2663.8362797810937,72620.14742615006,2125.614689977087,135476.70304998124,2023-02-04,2023,1,2,0,0 +35,14996.322031361808,2760.7691174029,110363.93301179436,34116.53311862405,266932.4863797552,2023-02-05,2023,1,2,0,0 +36,20276.101375521303,3037.996329471992,271791.0187736198,63541.64697730196,1464853.0295035124,2023-02-06,2023,1,2,0,0 +37,14000.737173415722,2716.6573208922805,89929.4716208581,38085.703829183134,194983.0274708129,2023-02-07,2023,1,2,0,0 +38,12661.12550217658,2656.4483029994767,66663.46465378284,31987.697196529905,111111.49965914476,2023-02-08,2023,1,2,0,0 +39,12567.68546924611,2645.043473694803,65203.20272138628,19329.51934720818,101866.31601359874,2023-02-09,2023,1,2,0,0 +40,12722.889371272577,2656.91872528128,67629.57008609171,30325.91295012124,112196.6715511802,2023-02-10,2023,1,2,0,0 +41,14919.745969622134,2769.116878368229,108703.21750958916,41073.59500988695,273590.3473290723,2023-02-11,2023,1,2,0,0 +42,16316.1608282432,2821.2456045346034,141950.69080248027,57992.24967813674,498715.0605461084,2023-02-12,2023,1,2,0,0 +43,17696.161080702044,2898.8601156039936,180921.6910941552,6400.309350191499,638345.823244303,2023-02-13,2023,1,2,0,0 +44,10555.849912395031,2539.909791733273,38870.3160743702,6049.248315125934,47539.70107595,2023-02-14,2023,1,2,0,0 +45,13931.477577863576,2711.2503153784965,88602.59812768851,19104.77596585267,175484.41888862776,2023-02-15,2023,1,2,0,0 +46,11698.233824478186,2605.688341096548,52702.421707527006,11175.189404276747,73556.83700200902,2023-02-16,2023,1,2,0,0 +47,10445.05453971149,2536.8414845877164,37669.46911564137,13198.7587750841,39571.82602997979,2023-02-17,2023,1,2,0,0 +48,14422.415059314482,2747.492969891934,98250.7696197148,33083.89481779225,216998.5494920225,2023-02-18,2023,1,2,0,0 +49,11784.046637208296,2592.510756867855,53842.59049373436,3823.610171729632,82809.80346490056,2023-02-19,2023,1,2,0,0 +50,15912.92447096838,2808.994964560031,131736.0206075616,64288.746016589655,490962.29641414376,2023-02-20,2023,1,2,0,0 +51,18440.875383941304,2945.142469764703,204653.82556438152,20419.00899659541,789542.4818763889,2023-02-21,2023,1,2,0,0 +52,16818.350189806464,2856.621555079898,155403.85425708417,7512.626077794378,485426.3412582249,2023-02-22,2023,1,2,0,0 +53,13822.971058619722,2704.5083968224126,86562.65063991075,42809.93640797532,194743.0963947549,2023-02-23,2023,1,2,0,0 +54,12615.044524803958,2659.0562622565567,65949.07358646176,15136.21795742132,105531.80763650234,2023-02-24,2023,1,2,0,0 +55,19582.877999353743,2998.268242241312,244929.3534708063,78737.22670278391,1376639.848604557,2023-02-25,2023,1,2,0,0 +56,13314.786144651727,2679.09688347003,77425.03345632256,11361.562984496177,142010.50335887677,2023-02-26,2023,1,2,0,0 +57,12500.483925965787,2637.0239046946526,64174.68963345611,5821.774362994604,107688.2445679445,2023-02-27,2023,1,2,0,0 +58,16470.183715350522,2841.0832324023904,146002.59286072702,42704.13997812481,453505.9903868763,2023-02-28,2023,1,2,0,0 +59,11192.564699099445,2563.3367125250743,46216.48371050753,7851.481336435534,61396.61740223998,2023-03-01,2023,1,3,0,0 +60,18410.461969863933,2948.827629658307,203646.06349207283,93613.2353808986,1276761.1162587996,2023-03-02,2023,1,3,0,0 +61,15382.814053587828,2778.556773993402,119063.19243782996,13884.77394907394,298697.41476447426,2023-03-03,2023,1,3,0,0 +62,15218.37881858589,2780.727763481268,115311.10420007331,14571.950730706783,281943.29254432843,2023-03-04,2023,1,3,0,0 +63,18241.57143227616,2930.0385740631204,198104.1082079558,76291.33215317283,992395.3612636012,2023-03-05,2023,1,3,0,0 +64,10669.97371038191,2547.259025164454,40118.8094032632,12847.870271258387,44801.99949720568,2023-03-06,2023,1,3,0,0 +65,15426.730313702496,2777.887768080937,120074.19143511802,46608.29481342147,339251.9930318989,2023-03-07,2023,1,3,0,0 +66,11138.47583858753,2578.4618577234182,45571.78693337313,13182.381069312254,55906.00453553141,2023-03-08,2023,1,3,0,0 +67,15806.084367185267,2815.233665413542,129122.3292101524,59030.75432821032,441623.8991178104,2023-03-09,2023,1,3,0,0 +68,15127.423225286808,2766.693619694508,113262.93301371323,27593.05587372291,272525.1146518174,2023-03-10,2023,1,3,0,0 +69,12939.505398534831,2665.162983826315,71113.12691181705,13874.644613204546,121066.52816538872,2023-03-11,2023,1,3,0,0 +70,15855.848764013175,2797.387271215214,130318.90213481108,59784.86082807257,452208.1100568039,2023-03-12,2023,1,3,0,0 +71,10547.563592596249,2544.400343106592,38777.41296202207,10701.878144788603,43489.20721273093,2023-03-13,2023,1,3,0,0 +72,15957.24755913394,2806.741400465455,132828.5982072106,55976.6824377499,441339.14015946497,2023-03-14,2023,1,3,0,0 +73,10290.727182137962,2532.438514279996,36049.29522097757,17637.49738999559,34449.605859722345,2023-03-15,2023,1,3,0,0 +74,13530.154207001,2692.264311135318,81214.53078954491,18497.10473204938,150413.1194952148,2023-03-16,2023,1,3,0,0 +75,12630.44318562225,2637.583652130219,66170.56153663639,12657.955041362957,107451.0390392414,2023-03-17,2023,1,3,0,0 +76,10681.93198581304,2545.5483945427704,40252.13368157131,15640.299267366909,43387.41694127486,2023-03-18,2023,1,3,0,0 +77,11274.945668686098,2576.4701064509,47238.88138617648,14966.59438968322,58379.60059082887,2023-03-19,2023,1,3,0,0 +78,16651.488103381602,2843.234540694281,150842.09675913482,67200.78617290665,612544.329617196,2023-03-20,2023,1,3,0,0 +79,17614.43330233067,2908.2274549979124,178449.9292243028,24740.486207543767,614860.8086578686,2023-03-21,2023,1,3,0,0 +80,15445.724959972817,2798.003548960506,120535.70782863908,7148.31127459362,310550.1781464028,2023-03-22,2023,1,3,0,0 +81,17446.47771716684,2882.1883016359734,173397.60979015206,9770.30242928656,588504.6191153652,2023-03-23,2023,1,3,0,0 +82,17797.665043290275,2914.703776422576,184045.71220563017,26626.974732505343,651303.2803783474,2023-03-24,2023,1,3,0,0 +83,14278.671622616792,2718.5870676261466,95344.85961460984,11637.62841841074,203550.2989575229,2023-03-25,2023,1,3,0,0 +84,10176.08517787648,2526.929049854561,34877.586646981166,2195.115698577836,43594.021454897615,2023-03-26,2023,1,3,0,0 +85,19824.518760738163,3002.241647162648,254074.70814131555,52623.70192730116,1241036.3991656953,2023-03-27,2023,1,3,0,0 +86,17300.120375733488,2882.046796350332,169090.07367217712,46680.114954082645,596180.8374987629,2023-03-28,2023,1,3,0,0 +87,15608.544317325272,2805.480691049104,124360.5901083492,34435.26106654667,328778.64224664023,2023-03-29,2023,1,3,0,0 +88,14240.176228040344,2723.645571573299,94582.45234254484,48042.84578437429,240572.3419546376,2023-03-30,2023,1,3,0,0 +89,17473.296936948256,2885.897725983263,174203.72209332045,57400.558005078245,677410.7771209874,2023-03-31,2023,1,3,0,0 +90,11530.142276238525,2591.231507435492,50482.40888692829,23882.137326387936,64158.69212168231,2023-04-01,2023,2,4,0,0 +91,13909.271758693329,2696.6008857456736,88171.16669982174,27856.24599558347,175346.80755253576,2023-04-02,2023,2,4,0,0 +92,16658.074311113232,2848.395493553576,151024.57988789663,56196.1486325087,536364.0409707661,2023-04-03,2023,2,4,0,0 +93,11640.33768834339,2584.6530156019635,51921.544066432536,20905.90014990672,67353.67970385434,2023-04-04,2023,2,4,0,0 +94,19452.3373911238,2982.444551976051,240071.4717053392,7694.110207657396,1066871.6102695498,2023-04-05,2023,2,4,0,0 +95,11721.863606201612,2625.202692967724,53028.86298339655,3942.747828759641,80680.84916045483,2023-04-06,2023,2,4,0,0 +96,14084.92948012886,2718.7029458998923,91542.33077183044,7368.115329991868,192969.92179395407,2023-04-07,2023,2,4,0,0 +97,11269.30183548332,2591.2587233528548,47176.17982520386,14529.27534796175,58573.54716729156,2023-04-08,2023,2,4,0,0 +98,18796.17079381625,2960.475981035944,216666.6842895663,42492.75149310147,902368.5479433454,2023-04-09,2023,2,4,0,0 +99,18416.99258959516,2928.2993583378284,203846.4013728909,82285.09932656371,1105594.0364351966,2023-04-10,2023,2,4,0,0 +100,11019.829811333026,2562.6105532128045,44136.28509626541,1400.461063688743,62812.80660505394,2023-04-11,2023,2,4,0,0 +101,18249.80711047113,2917.587142500988,198360.138947352,63159.10105517398,872932.7631089498,2023-04-12,2023,2,4,0,0 +102,15589.780730662587,2798.778381717195,123913.49368934042,41099.82507666839,340209.335010059,2023-04-13,2023,2,4,0,0 +103,11792.458774308208,2602.2451092210404,53964.30474935124,5297.01596245693,81688.89247074908,2023-04-14,2023,2,4,0,0 +104,14439.120060202697,2742.832819093503,98582.07559795296,11820.680430912593,215400.83531745608,2023-04-15,2023,2,4,0,0 +105,19555.69109154084,2989.806621895912,243903.8137683073,93935.07201297669,1591253.8481571798,2023-04-16,2023,2,4,0,0 +106,14156.112267655317,2728.608809431603,92931.8313542938,42640.77921630231,216679.6132221676,2023-04-17,2023,2,4,0,0 +107,16723.943405857008,2849.21970906308,152813.60652158182,68336.29184383912,633009.0506015444,2023-04-18,2023,2,4,0,0 +108,14984.025225268178,2761.082987147742,110085.73789151496,14243.848689314584,259958.07739673727,2023-04-19,2023,2,4,0,0 +109,16135.795717900935,2815.6269302832457,137313.39611432186,59410.02662171725,484003.89863521344,2023-04-20,2023,2,4,0,0 +110,12877.465260628278,2664.30304508452,70105.07044554866,11019.804936812568,120005.58879683766,2023-04-21,2023,2,4,0,0 +111,17872.69714402296,2921.804188633011,186376.4717325997,64250.023178389885,800886.7699220077,2023-04-22,2023,2,4,0,0 +112,18435.698905182373,2936.481650008607,204472.08159146423,101247.39077095588,1426909.5570265255,2023-04-23,2023,2,4,0,0 +113,16023.848515561263,2805.8698538581034,134489.86176819462,41442.34685372269,391164.9033160156,2023-04-24,2023,2,4,0,0 +114,19003.176276897346,2964.675594967593,223871.95995204087,67008.86081754284,1089172.785048267,2023-04-25,2023,2,4,0,0 +115,17523.986750251202,2880.8852759030187,175699.87152338328,38169.061872892606,612560.2116756208,2023-04-26,2023,2,4,0,0 +116,14227.38011359147,2721.365244217135,94338.09237971144,33482.895832123366,203011.77910239185,2023-04-27,2023,2,4,0,0 +117,18438.518101175978,2941.102441362834,204568.6282925311,2909.811662476893,800393.7569381781,2023-04-28,2023,2,4,0,0 +118,12172.816298529908,2634.024771592836,59309.39897152673,9049.28179194726,91585.90488902784,2023-04-29,2023,2,4,0,0 +119,12136.637374704202,2619.6822489827605,58776.13093125749,9493.34856054399,90052.96437137962,2023-04-30,2023,2,4,0,0 +120,17225.272806996647,2870.854784269861,166908.00138919885,13868.119794886814,546733.7947628682,2023-05-01,2023,2,5,0,0 +121,11247.22311083461,2600.46018463713,46913.53133152799,19467.11667645893,56162.9405972542,2023-05-02,2023,2,5,0,0 +122,17323.283512178063,2871.6614990984326,169756.68836581902,79214.59334016762,843929.003499603,2023-05-03,2023,2,5,0,0 +123,17000.188959017665,2865.639189036277,160481.75162139762,74727.00115666719,738021.8905505281,2023-05-04,2023,2,5,0,0 +124,16737.136081274602,2849.7300649201434,153176.01301956837,44466.49313210624,497266.8962887068,2023-05-05,2023,2,5,0,0 +125,11098.784554214724,2571.3127669444166,45087.05107031483,1648.145172374905,64697.64966375972,2023-05-06,2023,2,5,0,0 +126,19100.144889487143,2970.004656647697,227308.17123745583,77881.31709465497,1224847.934413988,2023-05-07,2023,2,5,0,0 +127,17077.78764587286,2880.140777017213,162687.57454620505,6057.225585072816,528127.5935585495,2023-05-08,2023,2,5,0,0 +128,16519.316876798057,2837.029717135952,147293.51486710669,50790.62298254375,489327.5979457785,2023-05-09,2023,2,5,0,0 +129,15742.254388248391,2793.709364525658,127557.13899154124,38596.45065246215,351176.58799903747,2023-05-10,2023,2,5,0,0 +130,12500.876109607054,2635.058964143491,64173.09557141788,12741.32860397467,102098.78797180545,2023-05-11,2023,2,5,0,0 +131,10807.342471856053,2547.716923314791,41663.08067248911,19275.0435201153,44903.21922176161,2023-05-12,2023,2,5,0,0 +132,19538.21208578541,3001.450280610775,243266.0364609208,55709.61827213061,1165721.5480891075,2023-05-13,2023,2,5,0,0 +133,13192.618677879876,2672.4320062886154,75327.60726392793,1158.499492469223,144755.86099705158,2023-05-14,2023,2,5,0,0 +134,18121.56401383737,2915.5711843606264,194232.82839258865,81641.59990683006,1030582.2256172546,2023-05-15,2023,2,5,0,0 +135,12359.3128047804,2634.438246250512,62045.95954907177,28801.606548313724,95514.69853235966,2023-05-16,2023,2,5,0,0 +136,13710.980004882924,2700.8963384274584,84490.88315413841,5664.3513674786645,169873.28523985806,2023-05-17,2023,2,5,0,0 +137,14717.731108564742,2758.821357982897,104361.88458645924,35330.40648940997,244320.91627033925,2023-05-18,2023,2,5,0,0 +138,15679.313873553076,2804.76300098966,126050.62700213466,8225.0716926524,334646.5955829722,2023-05-19,2023,2,5,0,0 +139,13078.340829861188,2662.6230815271474,73403.13750665677,37313.28256528759,138985.5715238371,2023-05-20,2023,2,5,0,0 +140,17571.45204039371,2894.146904397397,177133.87345489682,24040.65746675913,606537.4233560329,2023-05-21,2023,2,5,0,0 +141,14954.35712126238,2763.569941231514,109443.55055420412,25068.196401513604,255446.71439872627,2023-05-22,2023,2,5,0,0 +142,14332.121230780833,2727.7299280417133,96415.34597887092,20023.63438376866,203551.10748277453,2023-05-23,2023,2,5,0,0 +143,15998.493330213194,2825.2490379167584,133868.45091561653,15490.536972946653,366867.4858989834,2023-05-24,2023,2,5,0,0 +144,18668.13828617494,2936.9838055962123,212265.71892194703,12258.620340739471,847800.9988614026,2023-05-25,2023,2,5,0,0 +145,16077.66950281127,2808.8912767887023,135838.1509937302,61666.544130867616,491883.37802997255,2023-05-26,2023,2,5,0,0 +146,17202.938138940804,2874.9993914890715,166267.00277994917,29057.015633335184,542961.0679529211,2023-05-27,2023,2,5,0,0 +147,11656.611967744762,2587.8267322272623,52134.00394063981,25168.72486252534,68280.82225464782,2023-05-28,2023,2,5,0,0 +148,12583.150651437169,2676.2798601658,65466.3453081021,7261.913103213664,109745.12665998803,2023-05-29,2023,2,5,0,0 +149,13864.194806982214,2707.4893362427265,87344.6866525771,17530.067241321995,171534.2064924241,2023-05-30,2023,2,5,0,0 +150,17280.170412074924,2877.203436675503,168507.24123308816,40173.92235957972,573260.677304725,2023-05-31,2023,2,5,0,0 +151,12369.034501317825,2619.254656196872,62183.39464464643,6048.416764540098,102092.5155322807,2023-06-01,2023,2,6,0,0 +152,14197.469669161006,2738.3122189122955,93750.38169362556,28679.10899531393,195940.5193514432,2023-06-02,2023,2,6,0,0 +153,10458.612694472791,2536.4930656388324,37813.09041626065,13274.08998335508,39866.65264905818,2023-06-03,2023,2,6,0,0 +154,14932.608882243376,2775.755210068632,108976.72903738766,40271.22267560706,272850.5234296544,2023-06-04,2023,2,6,0,0 +155,19852.54123844096,3010.406127798933,255152.4262304588,80766.51822672845,1488590.0865889662,2023-06-05,2023,2,6,0,0 +156,18694.70035249052,2938.101029007794,213175.5940024836,40020.85064713905,870329.6520903526,2023-06-06,2023,2,6,0,0 +157,19599.831478775603,3002.5711537436464,245566.3523152908,106397.11803739789,1854934.254560565,2023-06-07,2023,2,6,0,0 +158,12490.104057642144,2650.364256195637,64027.16399733528,19704.955182071484,98499.03495510342,2023-06-08,2023,2,6,0,0 +159,10523.486529914124,2540.685340443743,38511.22982059314,10849.763781590333,42875.21587770166,2023-06-09,2023,2,6,0,0 +160,11104.41299156953,2567.241001699694,45158.96058042858,18015.492742940747,52599.71525365865,2023-06-10,2023,2,6,0,0 +161,15450.13441403785,2787.103852743307,120625.4999822687,6856.69964250108,311186.8742741625,2023-06-11,2023,2,6,0,0 +162,16743.22626802585,2847.1105140022537,153337.62724468473,52568.98597771433,530040.200288317,2023-06-12,2023,2,6,0,0 +163,13918.353666873129,2705.097606548035,88350.78469246291,3112.5669690579343,185609.66045975467,2023-06-13,2023,2,6,0,0 +164,14812.213475481927,2752.4449296234743,106364.28288738929,32924.84017709489,248773.3002814334,2023-06-14,2023,2,6,0,0 +165,17200.991152854138,2872.7697551528545,166212.59631152952,47404.99415782134,581455.5082443162,2023-06-15,2023,2,6,0,0 +166,15383.926045592812,2796.012262322265,119099.18938381436,47460.81421869122,338196.0324048956,2023-06-16,2023,2,6,0,0 +167,15841.725624496365,2803.043185884386,129977.27676546328,17232.297032843933,347405.5730620474,2023-06-17,2023,2,6,0,0 +168,17475.098214202735,2878.8183701459143,174241.28274543092,47486.99226248757,630220.8672824396,2023-06-18,2023,2,6,0,0 +169,10159.156703636712,2516.1335624578287,34700.91243953718,13647.564561805422,33802.63926894008,2023-06-19,2023,2,6,0,0 +170,17282.319267124185,2867.8497489173737,168558.40575619985,65280.739929727824,697701.3997426826,2023-06-20,2023,2,6,0,0 +171,14510.018616441725,2739.01454211475,100029.0944591822,47000.43954213679,257340.2724661749,2023-06-21,2023,2,6,0,0 +172,16162.876381875089,2835.033644135574,138017.82429034737,9768.645387591332,391344.08759364585,2023-06-22,2023,2,6,0,0 +173,15823.43162381674,2814.244516941196,129547.78142004252,21880.48957904192,344358.09273789544,2023-06-23,2023,2,6,0,0 +174,19203.09336802384,2967.778192370845,230996.0749753442,16956.67341934243,987643.1978494456,2023-06-24,2023,2,6,0,0 +175,18204.251858686777,2925.400641835543,196891.5655879397,25055.300894766955,735915.6896788268,2023-06-25,2023,2,6,0,0 +176,17235.69975192691,2870.704627312727,167206.73453970236,16243.509943678357,547104.9974462915,2023-06-26,2023,2,6,0,0 +177,11352.497807005902,2573.2036431616007,48200.45820256165,2867.246899460367,70519.57899217618,2023-06-27,2023,2,6,0,0 +178,20045.638751057337,3006.007829241778,262640.99686247605,61314.67234040087,1366494.615885821,2023-06-28,2023,2,6,0,0 +179,18746.99498436381,2954.633240913282,214970.61427347164,83357.5795846813,1200107.0124323235,2023-06-29,2023,2,6,0,0 +180,16118.63749659982,2839.565430702341,136896.03480481685,27889.179452338565,382038.7750928903,2023-06-30,2023,2,6,0,0 +181,11647.687358645511,2593.124996355884,52021.32671685675,7187.272661256549,75266.71096959058,2023-07-01,2023,3,7,0,0 +182,15735.618849604058,2797.2326866787803,127395.795537553,52268.58918159485,396318.5973424939,2023-07-02,2023,3,7,0,0 +183,18945.986175598035,2974.565961015085,221873.00336362087,23671.690122125525,916215.870849863,2023-07-03,2023,3,7,0,0 +184,15000.256868736416,2761.3371761153744,110445.09061525347,19018.82300880341,259403.55818297705,2023-07-04,2023,3,7,0,0 +185,11255.446836370576,2570.7259890508067,46992.7878861137,4599.908721130832,66054.96255416461,2023-07-05,2023,3,7,0,0 +186,18470.717466159167,2938.3870542972327,205634.22947364167,97739.96829138156,1365900.5025102978,2023-07-06,2023,3,7,0,0 +187,12965.76151963509,2661.307236045184,71539.79224679842,22578.14719509837,119753.41511538696,2023-07-07,2023,3,7,0,0 +188,13300.13161105611,2670.1241486236872,77164.77045856528,38314.90049350269,152722.61749650913,2023-07-08,2023,3,7,0,0 +189,18806.042663118013,2955.185189610094,216998.79793714324,15341.794370466108,881136.7856058207,2023-07-09,2023,3,7,0,0 +190,12153.006186093156,2639.348837004725,59028.65023729085,28866.547523696903,87532.68947196753,2023-07-10,2023,3,7,0,0 +191,11025.713271010727,2567.047264965501,44211.04210225624,1938.678895663871,62682.41857488162,2023-07-11,2023,3,7,0,0 +192,11661.12608883763,2588.183157892458,52195.46993044613,10135.265771960492,73080.9799336066,2023-07-12,2023,3,7,0,0 +193,16758.400587892927,2840.6644017909457,153754.41002602366,58415.64238402749,564232.2363995492,2023-07-13,2023,3,7,0,0 +194,13454.9329884879,2689.579334648932,79880.08797208051,9146.26437719481,151671.65841252738,2023-07-14,2023,3,7,0,0 +195,18858.24610805129,2944.651338081116,218795.4046541949,48591.3191803942,938965.6422377652,2023-07-15,2023,3,7,0,0 +196,16393.72552009653,2834.355053067119,143976.90971506038,16863.866428057543,417463.6775849069,2023-07-16,2023,3,7,0,0 +197,16279.420676288531,2823.786226480149,140996.9272868403,52795.1481656015,465742.80005019787,2023-07-17,2023,3,7,0,0 +198,13367.61645569566,2700.5947794277017,78363.02229023876,7851.014615376564,147973.0097260479,2023-07-18,2023,3,7,0,0 +199,16947.54599682392,2858.1405584107915,158993.53507303126,77402.81053972495,759368.8396595207,2023-07-19,2023,3,7,0,0 +200,14383.483037495138,2737.681710443333,97456.19185367844,10833.234882048431,212073.091739485,2023-07-20,2023,3,7,0,0 +201,15867.71934268762,2799.8216853741583,130618.50337392942,26507.141603067,350614.76922310673,2023-07-21,2023,3,7,0,0 +202,13338.01395902633,2677.347255597792,77825.40706651195,7222.489063042015,146738.99096312103,2023-07-22,2023,3,7,0,0 +203,16625.872644269475,2840.6341248798926,150155.06511441185,62714.17897889905,573459.2917504099,2023-07-23,2023,3,7,0,0 +204,17547.118984111054,2886.943892461939,176403.89990510058,32037.541748718893,607092.9644541375,2023-07-24,2023,3,7,0,0 +205,16560.076134141895,2836.506293008544,148380.89904388413,55818.75419381809,520034.0208155293,2023-07-25,2023,3,7,0,0 +206,13885.725230202572,2716.7021083575305,87743.16431045027,20625.69550078521,172171.12174295651,2023-07-26,2023,3,7,0,0 +207,11606.42981201497,2594.3765406398243,51482.49237536621,5158.252050961743,75696.1238530059,2023-07-27,2023,3,7,0,0 +208,16039.071376573507,2815.475849022623,134873.53797186748,48260.74118660409,415004.6208186623,2023-07-28,2023,3,7,0,0 +209,10718.577461942295,2547.131304118486,40664.87930481627,9909.037944820691,48002.335615976655,2023-07-29,2023,3,7,0,0 +210,10495.214219977408,2525.96857398576,38195.4643043126,7935.435635415078,44534.560076385824,2023-07-30,2023,3,7,0,0 +211,14798.575265857931,2762.7957825303565,106088.8920680396,50828.32406690267,296597.86405643536,2023-07-31,2023,3,7,0,0 +212,12827.412582152305,2662.769077681229,69299.91534927796,23013.30935821159,113166.23712179664,2023-08-01,2023,3,8,0,0 +213,10917.391269093128,2556.7560442020954,42935.51542341278,11806.7036700217,51272.847698206766,2023-08-02,2023,3,8,0,0 +214,18909.553593709134,2963.2007177410464,220594.23690704763,97188.7971433381,1465264.7926371803,2023-08-03,2023,3,8,0,0 +215,12702.617892137336,2678.3672672264483,67326.17253294392,9091.438004966432,113445.23978120124,2023-08-04,2023,3,8,0,0 +216,17923.11988000424,2911.04754433132,187948.48712049745,12150.545881316144,679110.8766818407,2023-08-05,2023,3,8,0,0 +217,20196.27611434892,3039.9256854043256,268607.841408798,130118.2029873399,2729732.4235094143,2023-08-06,2023,3,8,0,0 +218,12597.02926063482,2650.554367979511,65663.94295126307,12523.270920113466,106368.69500206248,2023-08-07,2023,3,8,0,0 +219,11588.873761188828,2586.477183638563,51247.13919546723,6992.221617500524,73450.4226995349,2023-08-08,2023,3,8,0,0 +220,13708.084068751208,2689.422309058713,84433.06932834222,15971.259974744966,162343.7057239838,2023-08-09,2023,3,8,0,0 +221,17742.669585580188,2894.0253845157035,182339.88581793776,22995.28117075969,639181.0353975537,2023-08-10,2023,3,8,0,0 +222,13009.367417335176,2692.162535305401,72279.27921509999,18887.900137383607,122531.86073445508,2023-08-11,2023,3,8,0,0 +223,17623.302604403296,2905.0793989553936,178716.01570878876,81598.16883978673,928766.7893613594,2023-08-12,2023,3,8,0,0 +224,14321.96880068566,2734.781460148489,96213.52411682456,14388.729863992765,205057.96254947947,2023-08-13,2023,3,8,0,0 +225,17611.5526986199,2896.054501206237,178345.43269358086,16544.66896565025,615030.2401074935,2023-08-14,2023,3,8,0,0 +226,14139.22439022604,2713.743180611385,92595.6935655136,23034.7892376463,189326.80535160296,2023-08-15,2023,3,8,0,0 +227,16972.768053440406,2861.7316760445165,159703.73326203742,21391.58868070242,502289.431878141,2023-08-16,2023,3,8,0,0 +228,11040.394548609283,2565.584425878248,44388.22536570521,15019.81667419851,52214.82659655199,2023-08-17,2023,3,8,0,0 +229,19841.06646565429,3027.868055896141,254730.15812190968,100942.74249052042,1815347.6158859327,2023-08-18,2023,3,8,0,0 +230,14987.223429609863,2777.6810118992653,110170.31602330122,50297.02790744006,311045.16167459066,2023-08-19,2023,3,8,0,0 +231,19988.74570088837,3009.893415884702,260418.17374528665,88860.82287732499,1648497.8410451806,2023-08-20,2023,3,8,0,0 +232,16319.549101055176,2830.089162407428,142043.5743113864,2907.2897990844194,418180.4926212353,2023-08-21,2023,3,8,0,0 +233,16658.127746802755,2847.193508926068,151028.18001346051,26082.23188876439,454711.2531656133,2023-08-22,2023,3,8,0,0 +234,12411.211994966432,2625.380842824816,62818.05196458266,26839.45938547132,96259.49500651972,2023-08-23,2023,3,8,0,0 +235,15419.881475817196,2797.547245900586,119931.6399755526,20590.70498276636,300014.5160234718,2023-08-24,2023,3,8,0,0 +236,17511.315901366455,2890.3043489156744,175330.1443749486,71038.33781316939,788986.8821455123,2023-08-25,2023,3,8,0,0 +237,17242.92511673886,2868.559783081004,167417.52086895908,17329.020472265438,547953.4593250835,2023-08-26,2023,3,8,0,0 +238,10800.9875248224,2553.537491287116,41592.32262681915,13757.329437563603,46979.78264372349,2023-08-27,2023,3,8,0,0 +239,15801.555124059323,2803.4062179216858,128999.6477866062,62622.07660624922,465574.8760579279,2023-08-28,2023,3,8,0,0 +240,15017.069490337004,2762.0664464682814,110812.75986714436,11006.503633180864,264895.2216785584,2023-08-29,2023,3,8,0,0 +241,19028.5279472106,2964.36924441376,224773.95427313683,23005.355567154413,938160.0659434008,2023-08-30,2023,3,8,0,0 +242,14912.614257990255,2783.001076999002,108547.94357449956,53575.672962884295,319751.4316459123,2023-08-31,2023,3,8,0,0 +243,13287.18553331647,2682.0220011917645,76951.61796118908,12737.657527334544,139784.3971998837,2023-09-01,2023,3,9,0,0 +244,13900.189161155107,2700.904301335273,88005.41094522423,32649.606759414623,179190.86596213278,2023-09-02,2023,3,9,0,0 +245,14424.110071468604,2742.846994744113,98283.5076972163,21193.83318762373,210610.5671375375,2023-09-03,2023,3,9,0,0 +246,19732.23123082815,2994.206883847153,250545.4360208247,15069.656212613292,1149030.4948696853,2023-09-04,2023,3,9,0,0 +247,18211.87965299924,2930.734323700983,197149.62991148327,26378.949324065707,738161.331586645,2023-09-05,2023,3,9,0,0 +248,12697.823568936969,2658.080332328086,67239.69163224717,14713.807935857858,109347.19097724992,2023-09-06,2023,3,9,0,0 +249,17281.975134356653,2888.650724921888,168564.79648202044,57510.92851237898,643953.2700403444,2023-09-07,2023,3,9,0,0 +250,19773.56526039858,3006.9616686929144,252127.4492786596,27941.832120270938,1162363.0955837965,2023-09-08,2023,3,9,0,0 +251,19720.47209268991,2993.4756908213794,250106.7504382381,6554.988795786852,1151448.212508672,2023-09-09,2023,3,9,0,0 +252,17189.25401392168,2874.525800679229,165868.18182168447,66339.40346498652,690322.370528609,2023-09-10,2023,3,9,0,0 +253,11834.905724811262,2603.280653517103,54548.70399852733,19162.627552705377,73880.33279161561,2023-09-11,2023,3,9,0,0 +254,15925.99856397794,2819.085408795025,132063.43111888957,48201.14649070631,401104.5387340423,2023-09-12,2023,3,9,0,0 +255,13791.739706337114,2696.402319101386,85978.99594149097,8556.677422596247,172503.7969719695,2023-09-13,2023,3,9,0,0 +256,16956.912536806838,2850.761701744844,159251.44551577198,64777.46510591103,639399.2851887431,2023-09-14,2023,3,9,0,0 +257,19206.13642209638,2997.9770332597195,231119.04843395177,26434.34722584166,988635.6338466324,2023-09-15,2023,3,9,0,0 +258,18887.873750116418,2963.568587551704,219841.31511699545,25459.50673967332,901143.5529472064,2023-09-16,2023,3,9,0,0 +259,19731.030230611326,2996.3193535175687,250503.2129925588,71216.20260186434,1342592.6250682962,2023-09-17,2023,3,9,0,0 +260,18911.22426370644,2965.478886436132,220652.59344725823,9538.053039892857,912303.3503977716,2023-09-18,2023,3,9,0,0 +261,13694.328120679498,2690.25616072448,84176.79172443654,13150.93785897344,162814.6122223096,2023-09-19,2023,3,9,0,0 +262,11604.1624903831,2581.944903810273,51442.38075564199,22166.59135788832,66075.4568975679,2023-09-20,2023,3,9,0,0 +263,16477.384755586838,2858.224627860587,146205.74718311863,8235.11831295197,434924.85988894186,2023-09-21,2023,3,9,0,0 +264,17119.22178979822,2871.532611098729,163858.94198165226,4480.2970395061975,536329.8798937509,2023-09-22,2023,3,9,0,0 +265,18147.759776902672,2933.654095747598,195084.55653163648,79432.77787232833,1008552.8680822948,2023-09-23,2023,3,9,0,0 +266,11964.97470241762,2609.229178993841,56344.2528805705,4343.737322388173,88403.04017067706,2023-09-24,2023,3,9,0,0 +267,14148.29593266436,2712.4287332650283,92768.67518962128,15620.21296580262,191706.2106764348,2023-09-25,2023,3,9,0,0 +268,14283.612220827665,2733.7225725378407,95452.4074546522,25404.262969287363,200380.0328482312,2023-09-26,2023,3,9,0,0 +269,19623.18106083465,2988.329032087268,246427.8060567837,117782.78010901816,2151171.727540931,2023-09-27,2023,3,9,0,0 +270,13052.64684167076,2662.20677647638,72972.64992392159,16374.343905816862,125364.16645036322,2023-09-28,2023,3,9,0,0 +271,14179.817590722523,2728.830594663715,93397.58435913788,40279.305035769634,212247.8018490545,2023-09-29,2023,3,9,0,0 +272,13327.596223072476,2682.379168812806,77647.34441387925,36135.822565822586,149940.78957150035,2023-09-30,2023,3,9,0,0 +273,18382.9378714516,2957.072919710631,202748.7666920794,27062.741324721595,777469.0843468456,2023-10-01,2023,4,10,0,0 +274,16723.970422588853,2848.862805151456,152818.47458227762,42010.91350640084,488240.7841009852,2023-10-02,2023,4,10,0,0 +275,11688.732103365524,2592.6647026593714,52564.69634560216,5666.551502351589,77908.6724201673,2023-10-03,2023,4,10,0,0 +276,12822.847380492003,2649.5496699594314,69217.8835429592,26615.167104290005,114195.74947687816,2023-10-04,2023,4,10,0,0 +277,16723.688440341735,2855.210492186303,152810.6452165964,20683.29382105044,463883.4676515869,2023-10-05,2023,4,10,0,0 +278,18145.62800219192,2919.5888362458154,195000.84343301627,87509.83950310503,1117917.268004638,2023-10-06,2023,4,10,0,0 +279,16857.692270078824,2851.471592666666,156488.3189660241,15691.28623052259,485586.4320482576,2023-10-07,2023,4,10,0,0 +280,19813.6334108303,3016.4558724344474,253671.5493663359,42322.85266712139,1199035.978334776,2023-10-08,2023,4,10,0,0 +281,16193.058075587724,2839.320973759835,138790.44255964202,5532.587260933421,398995.7091774846,2023-10-09,2023,4,10,0,0 +282,18340.982055971013,2938.00949264353,201358.1051811589,45354.02864837004,800838.1955733923,2023-10-10,2023,4,10,0,0 +283,12331.77894720218,2623.995882835748,61631.07974243811,4642.043502270773,101878.71863996242,2023-10-11,2023,4,10,0,0 +284,14431.27671780102,2731.4458596442314,98415.04164075766,10277.545134062806,216065.91871808143,2023-10-12,2023,4,10,0,0 +285,13935.100504057284,2711.270587748947,88672.65592514878,37273.84404184221,188962.6869904867,2023-10-13,2023,4,10,0,0 +286,11960.164634614415,2607.6128527486417,56274.82771102218,26447.02833219334,79133.54949462118,2023-10-14,2023,4,10,0,0 +287,11459.553257484364,2582.9544176241648,49567.37930473496,10613.09014525054,66627.02767756472,2023-10-15,2023,4,10,0,0 +288,10889.61578642423,2551.088357997578,42610.0367762452,19218.559593325343,46745.58853057618,2023-10-16,2023,4,10,0,0 +289,11617.364330429027,2613.9265628891326,51639.370867073216,1679.542233726913,79463.00208371624,2023-10-17,2023,4,10,0,0 +290,15889.412474468952,2808.542844404,131151.7636748882,52791.39079097375,416864.8000120563,2023-10-18,2023,4,10,0,0 +291,11787.233533048357,2615.4524743426823,53901.45976169017,16535.646350381347,73344.42084738884,2023-10-19,2023,4,10,0,0 +292,18578.09583111765,2948.254472573326,209234.54905084343,28701.338399586857,824552.4301795015,2023-10-20,2023,4,10,0,0 +293,11654.992875416374,2594.13124779796,52115.20548136946,22395.33474098997,67691.69194095086,2023-10-21,2023,4,10,0,0 +294,17935.45318638462,2916.973345999724,188337.3870624432,72958.82992124683,890968.9184266289,2023-10-22,2023,4,10,0,0 +295,18032.4242501514,2920.2678381426413,191397.2792652625,26677.13676914044,699469.3390314517,2023-10-23,2023,4,10,0,0 +296,12589.672687494867,2635.478780368377,65540.03557892736,32196.11457772016,108319.61758169143,2023-10-24,2023,4,10,0,0 +297,16147.51858826868,2808.862007234855,137608.29221880104,16593.83509597518,385002.2403450034,2023-10-25,2023,4,10,0,0 +298,15115.581910177223,2766.9588286195867,112995.92028008214,9532.692002833835,275397.77821717696,2023-10-26,2023,4,10,0,0 +299,17851.167520029197,2905.609871204044,185695.66952830213,75618.9788276735,901762.431236662,2023-10-27,2023,4,10,0,0 +300,18633.6814547566,2952.7645710774323,211115.49914850204,67647.16939486157,999255.778112828,2023-10-28,2023,4,10,0,0 +301,10446.455142410978,2548.512415169745,37693.90379291166,9796.60251810818,42033.343943898304,2023-10-29,2023,4,10,0,0 +302,15406.50058638425,2777.0327535928222,119613.51626171218,23040.08451267982,298620.39748067857,2023-10-30,2023,4,10,0,0 +303,18851.522151736903,2966.5686242938896,218582.42337444413,81184.00115389985,1198377.1179160113,2023-10-31,2023,4,10,0,0 +304,10143.584898977955,2515.5040275876404,34539.882858166915,10677.21072075594,35419.771787383885,2023-11-01,2023,4,11,0,0 +305,18933.15923509688,2969.778046581463,221424.7976276944,38894.402274768974,929346.8944925618,2023-11-02,2023,4,11,0,0 +306,12070.528695410254,2613.787012527785,57828.919759364784,10766.99514654736,86608.8626509824,2023-11-03,2023,4,11,0,0 +307,15613.098901672938,2787.8047133696377,124455.45671558948,55491.85254946095,399160.87546985486,2023-11-04,2023,4,11,0,0 +308,12440.860598609172,2654.5564829403647,63276.74620375545,5619.854874476661,105293.4899431363,2023-11-05,2023,4,11,0,0 +309,13347.8280288615,2678.398383458816,77995.44899416891,20719.49375857109,139815.1702873053,2023-11-06,2023,4,11,0,0 +310,15964.52295185562,2799.210556382558,133002.3760700704,48842.94254123249,408235.6801591589,2023-11-07,2023,4,11,0,0 +311,16136.459331039943,2828.4512173856847,137345.41646910433,30446.25688718561,386330.1379199166,2023-11-08,2023,4,11,0,0 +312,17954.870708757462,2921.1903281495297,188945.73655478624,28061.511463248626,684045.6648494821,2023-11-09,2023,4,11,0,0 +313,20229.785188731115,3030.0046787972124,269934.5278894667,131869.5944765487,2802960.479629692,2023-11-10,2023,4,11,0,0 +314,15716.182122154842,2812.4224145589496,126941.68798012518,35484.247297546906,342318.0245519161,2023-11-11,2023,4,11,0,0 +315,12290.896874818234,2624.0920861639243,61034.12104365228,29847.21633136793,93611.1455303304,2023-11-12,2023,4,11,0,0 +316,11906.39692699949,2609.8489261151344,55532.50629715312,10413.533885508996,81008.35560195518,2023-11-13,2023,4,11,0,0 +317,15435.522142153117,2787.2954548805774,120287.16631658406,20916.722612688565,301702.20021893195,2023-11-14,2023,4,11,0,0 +318,19969.168112092226,3002.888977301365,259655.40542109028,86522.00447425811,1606430.5602168995,2023-11-15,2023,4,11,0,0 +319,11469.42773358576,2598.0074402763385,49702.20666838935,11548.215973369146,66118.44822421222,2023-11-16,2023,4,11,0,0 +320,13798.235021311575,2710.2825677675623,86111.48876255788,10385.0902124141,171405.2489000874,2023-11-17,2023,4,11,0,0 +321,13623.450214686283,2703.9221844171034,82917.60533978797,41552.682734135225,178864.964690998,2023-11-18,2023,4,11,0,0 +322,19513.38350978566,3000.6192121206823,242339.85500060127,93767.45453212704,1575408.2741104194,2023-11-19,2023,4,11,0,0 +323,14459.976306107385,2735.280627138289,98998.47499459537,19923.04455939426,213231.55018492183,2023-11-20,2023,4,11,0,0 +324,13734.003185941536,2702.4178276811444,84914.54155882553,19592.963590955107,162501.37646446723,2023-11-21,2023,4,11,0,0 +325,11694.139733075644,2602.3293431274938,52653.7262580797,9498.395693899882,74636.47127403777,2023-11-22,2023,4,11,0,0 +326,14685.87743977528,2747.7426727544,103687.7183653977,36097.75088863007,242850.24999519635,2023-11-23,2023,4,11,0,0 +327,16238.7506292213,2838.0016995095166,139960.6726850215,14339.021992155242,398053.6993076788,2023-11-24,2023,4,11,0,0 +328,11173.852177257682,2581.225725155926,46003.4531442591,10884.1624502039,58415.0821295272,2023-11-25,2023,4,11,0,0 +329,11884.905942514551,2612.413552959777,55233.08379863483,28129.36510887675,77429.09900583976,2023-11-26,2023,4,11,0,0 +330,12670.803717373516,2657.5797155360187,66811.68553349709,31108.468746902057,110631.5748598384,2023-11-27,2023,4,11,0,0 +331,16236.646651045674,2821.9828240271045,139894.41103764297,27041.79277999772,396687.8227789781,2023-11-28,2023,4,11,0,0 +332,13692.546835152698,2699.1897655539133,84150.37856347073,13770.664089154803,162397.75469519207,2023-11-29,2023,4,11,0,0 +333,14211.826979447496,2725.522006274268,94034.13200495472,35564.19186024476,205080.54683185843,2023-11-30,2023,4,11,0,0 +334,12113.865010729663,2622.0481589608644,58455.999075157786,10932.85674184743,88161.64264511788,2023-12-01,2023,4,12,0,0 +335,12843.854557853065,2652.586798290643,69562.81609424195,21315.61509326509,114128.6501155256,2023-12-02,2023,4,12,0,0 +336,11224.033513358614,2578.982026640628,46610.59776391901,16034.288944749496,56497.00987346942,2023-12-03,2023,4,12,0,0 +337,15906.38653457539,2797.4739771346613,131566.47974830444,10007.3410645917,359270.85083713685,2023-12-04,2023,4,12,0,0 +338,15242.0295882724,2773.654789007021,115843.14813199412,14767.862228787297,284036.65698119294,2023-12-05,2023,4,12,0,0 +339,17717.48537228411,2889.960550739056,181562.9134101148,50245.2878355973,687188.8198187501,2023-12-06,2023,4,12,0,0 +340,13753.7839032966,2718.3173431994155,85289.8102262456,36781.815003972806,176349.98710434604,2023-12-07,2023,4,12,0,0 +341,18472.688470349363,2939.32221445958,205700.7077944369,9937.260173527908,802069.0197800506,2023-12-08,2023,4,12,0,0 +342,18863.25167900911,2972.926679248425,218992.7498099974,2311.1162498446324,906414.9810357396,2023-12-09,2023,4,12,0,0 +343,18102.32885314382,2923.71766203132,193618.9666017696,16297.814909436303,714609.1625739287,2023-12-10,2023,4,12,0,0 +344,19767.89806839977,2992.94829853224,251904.5405157072,50386.86499185325,1212097.0248597146,2023-12-11,2023,4,12,0,0 +345,10329.98846424464,2536.478336248847,36456.5329415576,2950.117827296005,46079.16517859782,2023-12-12,2023,4,12,0,0 +346,15346.302679285409,2780.216299702142,118219.6346790453,21417.50572232342,292515.3053555045,2023-12-13,2023,4,12,0,0 +347,16350.955980754352,2837.060999950021,142868.89083263016,41233.61023686083,433122.3782241905,2023-12-14,2023,4,12,0,0 +348,11062.068843824069,2561.555269084893,44643.877954606585,6492.6546704338425,59196.382088113874,2023-12-15,2023,4,12,0,0 +349,10022.082082651985,2501.8119449526234,33327.47043727003,12866.085447867885,31826.55958794992,2023-12-16,2023,4,12,0,0 +350,17889.74713015198,2915.140132017394,186914.0766486516,72819.99108061248,880303.5368097668,2023-12-17,2023,4,12,0,0 +351,14288.213710445538,2717.4106841065177,95526.77637587,6359.258203812723,208395.1489890275,2023-12-18,2023,4,12,0,0 +352,13288.852555754118,2684.7719420332046,76986.06852678503,35659.09591362423,147186.9278239012,2023-12-19,2023,4,12,0,0 +353,13546.824339791923,2690.8445862636418,81511.92277984093,29254.3885057888,153878.34247048604,2023-12-20,2023,4,12,0,0 +354,11384.533797324992,2594.259615316746,48617.414251429655,16871.79158447271,60564.2283093978,2023-12-21,2023,4,12,0,0 +355,11199.903262692118,2563.929744965353,46309.7144783998,21564.18418318424,54542.6429223455,2023-12-22,2023,4,12,0,0 +356,19994.64308894531,3018.693309202911,260654.5141809275,73716.9181055813,1455221.2895687865,2023-12-23,2023,4,12,0,0 +357,15711.536219423431,2799.533914382622,126829.39928430288,29960.897496203124,334942.2378775158,2023-12-24,2023,4,12,0,0 +358,16196.03316745022,2814.515599101631,138849.22274989288,35284.35416498658,400088.5200285696,2023-12-25,2023,4,12,0,0 +359,19155.84284442453,2980.920087456665,229304.66370311743,32046.8756038028,979014.931512059,2023-12-26,2023,4,12,0,0 +360,17162.458897469907,2870.5776569397804,165100.09437011776,11877.702367219144,537159.8204329332,2023-12-27,2023,4,12,0,0 +361,16063.086179669146,2837.134329060114,135495.04238697782,22546.06504806372,373429.5465681438,2023-12-28,2023,4,12,0,0 +362,10794.180809225192,2553.183239953835,41518.69433523475,6881.111223899316,52150.94639869857,2023-12-29,2023,4,12,0,0 +363,16843.92209856842,2866.8654898046143,156118.09107806013,32523.66967766781,488152.9536600131,2023-12-30,2023,4,12,0,0 +364,14287.773092199272,2749.3843327689165,95555.98829417976,43782.47790450857,229796.34845537567,2023-12-31,2023,4,12,0,0 +365,17031.95833178371,2857.3691433936824,137987.83094877942,29671.05014692801,429963.58243621,2024-01-01 00:00:00,2024,1,1,0,0 +366,15131.563942365445,3513.1970715504863,127828.39036454912,31546.282252959205,404507.63060354296,2024-01-02 00:00:00,2024,1,1,0,0 +367,16803.39057190455,2520.2402543320773,147587.41529209976,29759.48923714397,402786.703094528,2024-01-03 00:00:00,2024,1,1,0,0 +368,13991.809594504368,2722.591378650361,118232.96807655424,31351.93799736812,476043.4646612539,2024-01-04 00:00:00,2024,1,1,0,0 +369,13761.17263257386,3411.8603856445843,129334.64130188216,31663.05723420345,470785.8971573288,2024-01-05 00:00:00,2024,1,1,0,0 +370,15889.136597290822,2920.3049678634043,131066.9618843084,29797.848979450733,530047.8067328855,2024-01-06 00:00:00,2024,1,1,0,0 +371,15179.402072100846,3226.879393833515,130363.02502393554,32213.37186076595,568952.6357787589,2024-01-07 00:00:00,2024,1,1,0,0 +372,14614.37731872399,3799.918974140671,133853.60145294812,31990.747781584487,487453.3741120208,2024-01-08 00:00:00,2024,1,1,0,0 +373,14036.734190399804,3336.0861143191487,168810.4980848238,28992.9074363644,417574.7064915389,2024-01-09 00:00:00,2024,1,1,0,0 +374,16804.33957056895,3146.794395746216,144852.53146872707,33266.55149910744,447849.0343009056,2024-01-10 00:00:00,2024,1,1,0,0 +375,14461.135934735774,2855.748875530336,121661.32091898906,30947.17409664125,502585.3017893904,2024-01-11 00:00:00,2024,1,1,0,0 +376,18078.377846780066,3293.103721430764,148734.0199557054,32317.150383606266,413748.2062628244,2024-01-12 00:00:00,2024,1,1,0,0 +377,16503.974853524982,3059.527823804635,135031.30186192002,34499.87973606381,410255.0215936008,2024-01-13 00:00:00,2024,1,1,0,0 +378,15465.583950347447,3152.4685831350075,132679.04056940344,32367.422376547445,501779.41261839337,2024-01-14 00:00:00,2024,1,1,0,0 +379,15832.65962308464,3085.016912279857,133382.76072098708,31985.309031445628,534461.5240589792,2024-01-15 00:00:00,2024,1,1,0,0 +380,15196.009864162786,2654.786653265347,126649.41155895028,30574.43250063168,519514.4880571565,2024-01-16 00:00:00,2024,1,1,0,0 +381,14682.475632922034,3299.9138735601464,132662.3810616041,30462.169291024296,542174.8131833597,2024-01-17 00:00:00,2024,1,1,0,0 +382,16820.957974685913,3152.5982209514705,134989.0168826913,31307.19255271812,467887.5149871546,2024-01-18 00:00:00,2024,1,1,0,0 +383,17425.4597955102,3155.7200875330427,148529.82579710297,30438.715475574565,571782.4696628674,2024-01-19 00:00:00,2024,1,1,0,0 +384,15557.81847594486,3288.0542338968107,125691.22057222578,32203.15091313897,531632.8890649657,2024-01-20 00:00:00,2024,1,1,0,0 +385,13441.9613682541,2885.450481778528,134405.047962043,33191.38429423331,358450.0301278931,2024-01-21 00:00:00,2024,1,1,0,0 +386,15470.498315854924,2941.237696777878,173888.08656232755,32061.889116044647,510793.6443055968,2024-01-22 00:00:00,2024,1,1,0,0 +387,13516.149451820524,3232.6380461390736,141056.0463218349,30490.612730878456,497910.28012963495,2024-01-23 00:00:00,2024,1,1,0,0 +388,14101.39341843107,3040.85741169972,123866.20494697608,31384.87763137145,501988.6141117105,2024-01-24 00:00:00,2024,1,1,0,0 +389,14114.113014682838,3047.448571434452,121392.83312917904,33465.00569184012,452994.260893769,2024-01-25 00:00:00,2024,1,1,0,0 +390,19626.51599916445,2661.32591537439,113123.73623498622,35371.683945902594,492151.0028443366,2024-01-26 00:00:00,2024,1,1,0,0 +391,16494.152595837095,3234.895805217393,123839.994226995,30245.518644891483,584501.5586273029,2024-01-27 00:00:00,2024,1,1,0,0 +392,19106.803442684763,3034.6929058366145,137420.42309631626,32082.970697243665,346472.7152305052,2024-01-28 00:00:00,2024,1,1,0,0 +393,14383.012154297914,3067.138366752441,136847.7553148575,33301.90373920697,413908.0837500992,2024-01-29 00:00:00,2024,1,1,0,0 +394,15734.802557373234,3136.206999686079,118445.83609619588,33908.876612436005,467862.6475692211,2024-01-30 00:00:00,2024,1,1,0,0 +395,18130.626228420595,3084.1066381151622,116131.76651055024,29736.17148055951,501007.9507625399,2024-01-31 00:00:00,2024,1,1,0,0 +396,20038.442090286248,3304.087796756216,113155.76530940212,30022.51607017234,481095.8923330079,2024-02-01 00:00:00,2024,1,2,0,0 +397,15047.271008219172,3127.595710726884,138461.9099715733,32519.706968443115,486635.758553268,2024-02-02 00:00:00,2024,1,2,0,0 +398,14748.738525634484,3271.316129018521,158070.11170439803,30724.433077595408,416718.0187475818,2024-02-03 00:00:00,2024,1,2,0,0 +399,14772.570672161764,3163.0581143544764,144769.24427145414,30994.587797809018,504601.1758406212,2024-02-04 00:00:00,2024,1,2,0,0 +400,15674.674426394307,3157.4134825782508,131327.3574483408,31140.79686528554,401964.1179837827,2024-02-05 00:00:00,2024,1,2,0,0 +401,17299.80350998936,2993.651837727052,124468.943360037,30187.43045950713,466732.3306809018,2024-02-06 00:00:00,2024,1,2,0,0 +402,14757.500866595632,3058.816135234346,141632.36536434817,33676.67623971732,410182.0478502427,2024-02-07 00:00:00,2024,1,2,0,0 +403,17906.782628497644,3206.6364160063067,124488.58801506236,28342.253053681765,446423.184826235,2024-02-08 00:00:00,2024,1,2,0,0 +404,17770.587600535826,3144.523576752096,132640.2826114784,32802.23759440439,449150.5348964001,2024-02-09 00:00:00,2024,1,2,0,0 +405,13853.10279524292,3322.632567729218,132125.59215396098,32228.690585706376,578466.590595876,2024-02-10 00:00:00,2024,1,2,0,0 +406,13923.092587117117,2829.2375584314123,147489.30997720055,32335.97041393491,425742.5105774968,2024-02-11 00:00:00,2024,1,2,0,0 +407,16009.7761797946,2675.5425813836405,134007.81968298423,32082.704194487407,370886.0052330677,2024-02-12 00:00:00,2024,1,2,0,0 +408,16266.38491509551,3551.2478905255325,142385.7072666998,32239.42442197975,467917.38369361777,2024-02-13 00:00:00,2024,1,2,0,0 +409,17939.261269263014,2831.010965648643,134335.93000521333,30957.768069969625,540800.7221936603,2024-02-14 00:00:00,2024,1,2,0,0 +410,14382.839823303131,3057.3104505031447,152599.50089069144,33462.303640744496,530099.6522685864,2024-02-15 00:00:00,2024,1,2,0,0 +411,16850.521948224843,3045.7991290725777,123289.02849706504,30718.40761071803,473520.09149491886,2024-02-16 00:00:00,2024,1,2,0,0 +412,13404.137078534524,2820.276569751968,120537.35731099364,28228.045283846302,540113.0335215597,2024-02-17 00:00:00,2024,1,2,0,0 +413,18163.752571274552,2858.5323798706395,154811.86876779227,33456.69982127517,507184.5750239752,2024-02-18 00:00:00,2024,1,2,0,0 +414,16533.999904152468,3132.847283851472,109246.64094724644,32203.79829229557,493397.67615241953,2024-02-19 00:00:00,2024,1,2,0,0 +415,17073.874145100977,3185.0754736462604,148742.8668832133,31703.885902055103,480233.18552933366,2024-02-20 00:00:00,2024,1,2,0,0 +416,15244.071407139323,3130.556792349044,124158.25528554263,30283.452235065342,463122.0013770756,2024-02-21 00:00:00,2024,1,2,0,0 +417,16047.499080043934,3616.351311147828,116696.9077654436,29279.31806307957,526879.42814877,2024-02-22 00:00:00,2024,1,2,0,0 +418,13639.364066942358,3224.7946825316694,132829.98607772632,28290.862133262734,497689.89153904654,2024-02-23 00:00:00,2024,1,2,0,0 +419,14577.375281616616,3605.801673970114,122290.96118119208,30709.27132883296,525232.9355992562,2024-02-24 00:00:00,2024,1,2,0,0 +420,15236.086286785352,2874.358474930546,143361.20932764446,31761.913497795387,511684.4844840397,2024-02-25 00:00:00,2024,1,2,0,0 +421,15715.41755636237,3408.1375599936546,140752.53969546076,33307.203529071456,527110.6222117542,2024-02-26 00:00:00,2024,1,2,0,0 +422,18612.36496820888,2762.340644894183,116830.3444649366,30706.923759918573,437525.3663629764,2024-02-27 00:00:00,2024,1,2,0,0 +423,12668.741754580826,3302.5896677069336,116491.52678000684,33021.67899535603,485747.7713256424,2024-02-28 00:00:00,2024,1,2,0,0 +424,19249.91235916571,2901.94529723227,111317.21053906216,34451.39930399612,479110.0415454212,2024-02-29 00:00:00,2024,1,2,0,0 +425,14761.407231231698,2685.8438836399523,129332.0349024862,33544.03987238335,485588.2206094789,2024-03-01 00:00:00,2024,1,3,0,0 +426,17398.00440665823,3580.3019861090525,138318.1344035474,31864.566359634155,404675.2493236798,2024-03-02 00:00:00,2024,1,3,0,0 +427,16188.048813493411,2693.6363251428074,146922.47916412805,32462.649572723243,520504.35818243725,2024-03-03 00:00:00,2024,1,3,0,0 +428,15582.892515007936,3492.8738307258027,155097.1021830595,32177.821581682467,447249.3748059953,2024-03-04 00:00:00,2024,1,3,0,0 +429,17815.610691149323,2883.0136856520394,133327.7963579287,33648.09895579745,426573.4680326796,2024-03-05 00:00:00,2024,1,3,0,0 +430,16316.482908527814,3351.953541898221,133618.33121983387,28681.29744837966,490093.70200842497,2024-03-06 00:00:00,2024,1,3,0,0 +431,17449.0045591092,2804.7091271909285,136311.3412206153,33475.15858715393,493351.449650366,2024-03-07 00:00:00,2024,1,3,0,0 +432,18891.97728403364,2763.8216934886923,115263.9047521602,29574.442192309485,536886.8773878139,2024-03-08 00:00:00,2024,1,3,0,0 +433,15127.571528021372,2587.3570666860387,125134.94164031574,32850.47006085737,510521.6119137112,2024-03-09 00:00:00,2024,1,3,0,0 +434,16933.16765626324,3229.1315585306365,136080.04805467837,28816.136292406285,515471.7945047303,2024-03-10 00:00:00,2024,1,3,0,0 +435,17508.488282800816,2645.332266066157,137346.30790656374,32258.249137214643,526796.9598225388,2024-03-11 00:00:00,2024,1,3,0,0 +436,16096.750627163046,2842.078736003212,122993.61296917484,30959.99210113985,455936.28958576825,2024-03-12 00:00:00,2024,1,3,0,0 +437,18154.26997673033,2666.200181942662,136761.64255535396,34614.501737825405,502137.5922771881,2024-03-13 00:00:00,2024,1,3,0,0 +438,17814.114555263535,2780.591277985643,132727.0102261347,34082.65184216536,459274.97424277646,2024-03-14 00:00:00,2024,1,3,0,0 +439,15729.722477964644,3203.517797641133,118401.22040780878,29050.65438900579,453622.0272921645,2024-03-15 00:00:00,2024,1,3,0,0 +440,13542.563223443483,3150.825504588757,168869.5256836363,31318.22353244421,506888.06897873385,2024-03-16 00:00:00,2024,1,3,0,0 +441,16809.95017987185,3111.6112553152384,143857.09949429438,32421.621312499545,457114.4887213346,2024-03-17 00:00:00,2024,1,3,0,0 +442,15740.203370733005,3421.122524139384,128789.68389962954,30208.099439329097,436769.3807212245,2024-03-18 00:00:00,2024,1,3,0,0 +443,16334.41430193543,3257.8843482121406,131882.49162623892,33453.24151118658,518454.5146186393,2024-03-19 00:00:00,2024,1,3,0,0 +444,17184.345733988517,3370.6304510347622,128658.25252470598,32369.579123902546,504518.6856086968,2024-03-20 00:00:00,2024,1,3,0,0 +445,13419.340086424285,3229.82872194961,144496.03863248852,33277.21737730874,520042.0528882233,2024-03-21 00:00:00,2024,1,3,0,0 +446,14597.641371334375,2514.13222876626,147609.26581996918,31487.6890353343,482699.70955825824,2024-03-22 00:00:00,2024,1,3,0,0 +447,17590.612112292554,2737.7599362578267,144623.31175087672,32410.98880999377,387381.04256000987,2024-03-23 00:00:00,2024,1,3,0,0 +448,14409.682325441194,3627.115597778488,127973.4530610352,36853.56801075113,479290.5081939265,2024-03-24 00:00:00,2024,1,3,0,0 +449,16052.29266776082,3028.215299663384,131376.15077405842,32132.83659646184,429440.5478223064,2024-03-25 00:00:00,2024,1,3,0,0 +450,16839.72225530211,2946.890019345813,163767.09491258787,32910.12436403929,496484.3877418065,2024-03-26 00:00:00,2024,1,3,0,0 +451,15670.74250986361,3165.8726974831307,145857.1775624985,33905.37314770312,466839.72727773146,2024-03-27 00:00:00,2024,1,3,0,0 +452,16336.648308598576,2897.4260275800625,125063.75121334802,33233.57236482355,511863.1596219754,2024-03-28 00:00:00,2024,1,3,0,0 +453,13848.804017858256,3001.955006503513,149746.84879605542,28721.216881724984,566795.4816670693,2024-03-29 00:00:00,2024,1,3,0,0 +454,14430.2144497862,3267.4782892571498,146893.95442540507,34310.76325496878,595610.4494444608,2024-03-30 00:00:00,2024,1,3,0,0 +455,18312.697002856443,2614.499055003122,137416.5242668902,29858.577209785275,452095.1618817651,2024-03-31 00:00:00,2024,1,3,0,0 +456,14906.604253660273,2661.819016277132,112021.97230811502,33318.7769210384,437791.8586811947,2024-04-01 00:00:00,2024,2,4,0,0 +457,11329.14189350146,3698.622404422901,122046.63827698564,32306.377635901536,503372.07628614455,2024-04-02 00:00:00,2024,2,4,0,0 +458,14258.255980954747,3256.4908232883454,161044.01565770913,32647.98248575418,559668.9369361068,2024-04-03 00:00:00,2024,2,4,0,0 +459,18011.427838668133,2771.001615839157,133569.06568335812,31546.23327861344,403488.1222829415,2024-04-04 00:00:00,2024,2,4,0,0 +460,17663.94640318357,3559.0221902532894,144118.58779393212,31208.551993874786,452285.3848812348,2024-04-05 00:00:00,2024,2,4,0,0 +461,16744.878951766863,2824.5113003061947,120390.1046474759,32374.457290141243,486984.03500245325,2024-04-06 00:00:00,2024,2,4,0,0 +462,15367.94215774599,3188.142472033157,123014.3975694704,32212.54152521946,385779.3928520391,2024-04-07 00:00:00,2024,2,4,0,0 +463,16354.092935594936,3386.803388689916,137259.15422715843,33184.262250991174,504154.6138963048,2024-04-08 00:00:00,2024,2,4,0,0 +464,20730.078599366327,3320.197463698842,137922.65359305596,31316.605827597705,443197.7132045936,2024-04-09 00:00:00,2024,2,4,0,0 +465,13545.33008945874,3093.1155379907595,133791.72213235934,30498.68760242448,449310.866448618,2024-04-10 00:00:00,2024,2,4,0,0 +466,15586.54968066474,3261.939596116086,147192.45960115688,31010.232102497663,501030.6668797409,2024-04-11 00:00:00,2024,2,4,0,0 +467,14824.70702468034,2741.487912523325,117857.47782526874,30091.799155355537,456261.54992997,2024-04-12 00:00:00,2024,2,4,0,0 +468,14774.09899970738,3222.26430601546,148201.93355373104,31253.539986406653,477989.6782249444,2024-04-13 00:00:00,2024,2,4,0,0 +469,15103.507518953513,3087.0509403665046,125175.03542342364,31307.829747162643,486874.1997469828,2024-04-14 00:00:00,2024,2,4,0,0 +470,17689.793988170622,3015.4378359883945,147270.59188069674,32133.97891888037,520125.7096017007,2024-04-15 00:00:00,2024,2,4,0,0 +471,17444.15251403192,3051.204849412057,112341.77933332825,32169.24018410404,506116.62026613386,2024-04-16 00:00:00,2024,2,4,0,0 +472,15038.018210499544,3009.269136086484,154151.3038154046,31092.1306456126,487812.6409668831,2024-04-17 00:00:00,2024,2,4,0,0 +473,19185.590382944247,3555.586836220856,133026.30340197447,31595.07355499446,479675.9186901629,2024-04-18 00:00:00,2024,2,4,0,0 +474,17079.72015092683,2641.2912661598657,123064.98343544136,33901.627633208416,493844.2534733137,2024-04-19 00:00:00,2024,2,4,0,0 +475,15807.420568810494,2816.909967415085,137994.38137496653,26581.88494708745,385136.9109776784,2024-04-20 00:00:00,2024,2,4,0,0 +476,15746.975091982931,3406.090904490944,144605.0615338283,30302.435384491782,574486.3848124718,2024-04-21 00:00:00,2024,2,4,0,0 +477,16951.403362353532,2727.5694791267133,143340.75864430156,33134.530673987174,470085.8426979189,2024-04-22 00:00:00,2024,2,4,0,0 +478,17137.390137485512,3034.496418991682,134068.65005051522,32747.297947312647,490252.9087182828,2024-04-23 00:00:00,2024,2,4,0,0 +479,16989.81953153759,3113.486788201301,132662.47191964384,33765.769635396595,452672.16725774045,2024-04-24 00:00:00,2024,2,4,0,0 +480,17988.155688330004,3029.7805226867395,135773.72226963862,31196.50397168429,422756.2475488472,2024-04-25 00:00:00,2024,2,4,0,0 +481,16469.704734131006,3159.263844858064,138158.1774033076,31332.69906381442,445980.68658781366,2024-04-26 00:00:00,2024,2,4,0,0 +482,16151.723370436306,2585.4417151016155,133614.8910285366,30099.31166969833,361201.0838994372,2024-04-27 00:00:00,2024,2,4,0,0 +483,16437.4649992623,2768.365255215152,148383.303565349,32192.56933456065,509134.1351984708,2024-04-28 00:00:00,2024,2,4,0,0 +484,13330.432598962509,3658.561673748275,168520.79811256725,30962.43101064575,401041.8780564421,2024-04-29 00:00:00,2024,2,4,0,0 +485,17200.403934519156,3335.1705833259384,126542.00877397013,32006.026016996388,458051.5715989482,2024-04-30 00:00:00,2024,2,4,0,0 +486,18702.369706763347,2740.604086122569,116996.4907961237,35245.70987231829,527594.7530182286,2024-05-01 00:00:00,2024,2,5,0,0 +487,13874.214749468145,2817.4964547839336,127100.60172602964,31219.775950041672,433338.86121583526,2024-05-02 00:00:00,2024,2,5,0,0 +488,15706.353025956689,3086.078288772084,115195.57270749888,31228.120300566417,465657.2058469736,2024-05-03 00:00:00,2024,2,5,0,0 +489,17304.326513325508,2804.972051262224,163462.10707481808,31421.79540565196,455561.2394904943,2024-05-04 00:00:00,2024,2,5,0,0 +490,16609.89298540484,2578.7845578089264,138701.30317956244,29722.749401049543,468091.987136776,2024-05-05 00:00:00,2024,2,5,0,0 +491,17261.74885794885,2662.4727301528715,132451.9226033343,30669.90750043408,380298.9461034821,2024-05-06 00:00:00,2024,2,5,0,0 +492,17335.77320382819,3315.580226766967,145325.2075974947,29660.561290023183,518400.7491309124,2024-05-07 00:00:00,2024,2,5,0,0 +493,17622.44612780122,3011.704204717062,124802.30986510895,32962.23788085004,514732.00096137583,2024-05-08 00:00:00,2024,2,5,0,0 +494,17041.718634828205,3247.2519263349222,136592.4829400376,31585.62593578741,473349.4980110296,2024-05-09 00:00:00,2024,2,5,0,0 +495,17552.659340593455,3256.0379861323977,130553.99029375896,30680.67586898971,542802.7034943707,2024-05-10 00:00:00,2024,2,5,0,0 +496,16929.345064430712,2727.228059999636,127513.4759782716,33067.04550192179,455301.07060397294,2024-05-11 00:00:00,2024,2,5,0,0 +497,16732.20993062429,3017.477452293827,144964.9130427592,30477.67461692701,507751.8108693285,2024-05-12 00:00:00,2024,2,5,0,0 +498,14617.423250830569,3134.787411892172,148524.12371186342,35425.55789559303,514388.37621726753,2024-05-13 00:00:00,2024,2,5,0,0 +499,13632.623472684883,2858.9194065115544,123084.94087078766,30029.434825258657,476782.8289556896,2024-05-14 00:00:00,2024,2,5,0,0 +500,17588.607170661795,3023.4017436878407,130408.14728023724,30180.676550352888,474721.9438535684,2024-05-15 00:00:00,2024,2,5,0,0 +501,17170.575339652936,3263.202554422724,117925.70501397848,32896.943372511,529284.0430437287,2024-05-16 00:00:00,2024,2,5,0,0 +502,15311.083572561112,3200.5691168611056,139079.79402265468,35065.08702645494,517224.1774359062,2024-05-17 00:00:00,2024,2,5,0,0 +503,15548.9983608871,3010.8672046084184,138345.216736843,33368.44604157319,438005.6634036925,2024-05-18 00:00:00,2024,2,5,0,0 +504,15722.94948543981,2807.5708382751754,134627.33714333284,28112.888382629342,444930.2808231571,2024-05-19 00:00:00,2024,2,5,0,0 +505,19309.285176556263,3003.0913747294853,164438.60981567798,30439.796698689566,542832.0133289007,2024-05-20 00:00:00,2024,2,5,0,0 +506,13909.67647996396,2323.855148008197,137991.48851320017,34379.109906618,481184.6039810896,2024-05-21 00:00:00,2024,2,5,0,0 +507,12781.185717788609,2843.143670862026,137742.34974222595,31706.7802346251,602959.4578656267,2024-05-22 00:00:00,2024,2,5,0,0 +508,17049.00233525565,2760.5000975565194,136730.52737215685,31972.292779846604,448607.1952366976,2024-05-23 00:00:00,2024,2,5,0,0 +509,14916.27432309301,3422.6770959950595,125232.02882175894,30623.905473305906,481025.9698251159,2024-05-24 00:00:00,2024,2,5,0,0 +510,15922.67493247505,2786.026468738916,155791.7805890024,31066.81128546724,475814.7218620404,2024-05-25 00:00:00,2024,2,5,0,0 +511,18145.622698274947,2675.669805061841,126676.20823882466,30249.13972472653,402852.2598338522,2024-05-26 00:00:00,2024,2,5,0,0 +512,13849.226345759478,2911.13532974624,133328.45639950654,34474.91621540193,495057.2923840943,2024-05-27 00:00:00,2024,2,5,0,0 +513,14162.866686028772,3502.6786238799023,144549.64402365772,30855.09982906232,413366.0364330122,2024-05-28 00:00:00,2024,2,5,0,0 +514,14442.041110163424,2888.3451568439323,135376.20838288576,31550.37284895944,502528.6042764047,2024-05-29 00:00:00,2024,2,5,0,0 +515,14944.87675462174,3120.776436776723,127500.01924669118,30699.76132960285,417506.729119414,2024-05-30 00:00:00,2024,2,5,0,0 +516,18453.89030238001,3462.863660146038,141125.04305480543,28380.783849880565,504038.1781164353,2024-05-31 00:00:00,2024,2,5,0,0 +517,17477.326228469898,3256.912029110312,144842.7003084169,29403.75666381481,572351.0104504596,2024-06-01 00:00:00,2024,2,6,0,0 +518,15215.222020084662,3080.6460486856868,128176.82423080254,34008.673224265774,428662.0168061218,2024-06-02 00:00:00,2024,2,6,0,0 +519,17798.409357291246,3042.9470436384227,137005.43478861803,32640.081902804704,531638.875117744,2024-06-03 00:00:00,2024,2,6,0,0 +520,15310.7394911942,2401.3236077823603,109749.24602737576,33136.909100074045,476046.3829280656,2024-06-04 00:00:00,2024,2,6,0,0 +521,18463.320403477745,3265.359796126504,140700.15040995897,31396.457701865023,431112.60668828513,2024-06-05 00:00:00,2024,2,6,0,0 +522,16861.817476222546,2888.582933617436,147893.12305368757,30896.811654794827,501013.3225776395,2024-06-06 00:00:00,2024,2,6,0,0 +523,16960.237935214347,3135.197822891953,131214.15543186953,32994.855504087594,454322.1536800256,2024-06-07 00:00:00,2024,2,6,0,0 +524,15989.234719087028,3196.750148862323,120082.96007321228,30650.01010397283,459179.4816635855,2024-06-08 00:00:00,2024,2,6,0,0 +525,17615.968890337685,3486.873906518458,117594.91006465782,30840.80397904954,567570.5777489252,2024-06-09 00:00:00,2024,2,6,0,0 +526,17113.940231497058,2651.958004691425,133839.9026993554,27940.56590702207,538486.803222622,2024-06-10 00:00:00,2024,2,6,0,0 +527,15789.209349026918,2866.984857051415,145387.16346588242,30961.0800832682,517781.1174301044,2024-06-11 00:00:00,2024,2,6,0,0 +528,15125.431137468418,2948.019133604276,116593.85349497428,33709.37599120076,515446.9532222614,2024-06-12 00:00:00,2024,2,6,0,0 +529,14507.612588265894,3163.7343788286003,146379.8832101092,32372.821737939783,429058.1552362567,2024-06-13 00:00:00,2024,2,6,0,0 +530,15769.349562173578,3350.4595462338057,136901.1953158221,30962.49515837201,482467.0977660645,2024-06-14 00:00:00,2024,2,6,0,0 +531,16869.105930518468,2849.855697218661,133602.79233289903,30792.62707643318,446807.5295797924,2024-06-15 00:00:00,2024,2,6,0,0 +532,15362.4771085293,2854.0439931243136,118361.8302857952,32089.624140553507,510561.7020154484,2024-06-16 00:00:00,2024,2,6,0,0 +533,17940.149940865667,2765.9930533230327,149236.5818888811,30490.67462868605,463582.58931866975,2024-06-17 00:00:00,2024,2,6,0,0 +534,15829.953670132209,3476.6866816245715,125018.05348924252,32213.58420981864,426598.1581973629,2024-06-18 00:00:00,2024,2,6,0,0 +535,14663.611508647791,2919.356525452366,144218.68460314942,31944.319353969546,422570.3510425733,2024-06-19 00:00:00,2024,2,6,0,0 +536,14458.622669501605,2841.6809974766134,113724.39769325126,33689.76665274606,418494.99559362215,2024-06-20 00:00:00,2024,2,6,0,0 +537,13467.995203672584,3196.617107780249,139387.7722671624,28905.939685632555,513769.3389000001,2024-06-21 00:00:00,2024,2,6,0,0 +538,16395.62019012106,3533.8108209181974,115175.0009210384,34376.955566831,469623.37440250296,2024-06-22 00:00:00,2024,2,6,0,0 +539,16657.532923147108,3007.709523786926,131246.31886572344,28630.88058979301,444660.2365600213,2024-06-23 00:00:00,2024,2,6,0,0 +540,15398.081395373683,3178.694363059269,157975.52223052498,31242.243016228203,476867.380019899,2024-06-24 00:00:00,2024,2,6,0,0 +541,15704.73595117928,2674.739101757693,133067.36723282147,32028.76636839493,518293.5299279518,2024-06-25 00:00:00,2024,2,6,0,0 +542,14667.917955397552,3384.46321295907,142532.3005014633,30767.489558186808,514882.3755848785,2024-06-26 00:00:00,2024,2,6,0,0 +543,15114.345005889105,3189.5389261128125,136912.9634086988,30140.218096708653,448386.7701824556,2024-06-27 00:00:00,2024,2,6,0,0 +544,16295.416420857964,2318.7797754593225,138215.2209935118,32710.285704958867,463942.5591566077,2024-06-28 00:00:00,2024,2,6,0,0 +545,18165.75212048323,3003.761967989752,134484.54464989054,30921.81576916633,511696.1838626112,2024-06-29 00:00:00,2024,2,6,0,0 +546,12339.875378623436,2944.4308047380523,109477.25960453524,33037.56754792266,424571.1978770118,2024-06-30 00:00:00,2024,2,6,0,0 diff --git a/docs/source/example_notebooks/sales_attribution_intervention.ipynb b/docs/source/example_notebooks/sales_attribution_intervention.ipynb new file mode 100644 index 000000000..7ecc87fb3 --- /dev/null +++ b/docs/source/example_notebooks/sales_attribution_intervention.ipynb @@ -0,0 +1,809 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "d1b60604", + "metadata": { + "tags": [] + }, + "source": [ + "# Causal attribution to sales growth and spend intervention" + ] + }, + { + "cell_type": "markdown", + "id": "6140025d-504e-4500-83cb-7b31643f546f", + "metadata": {}, + "source": [ + "## The Scenario " + ] + }, + { + "cell_type": "markdown", + "id": "e1a090e0-b5da-4835-9cfe-9bf1e53aef4e", + "metadata": {}, + "source": [ + "Suppose we have an advertiser selling products online. To promote sales, they give out discounts through price promotions, and advertise online through both display ads and sponsored ads in search results pages. To prepare for an upcoming business review, the advertiser compares 2024 and 2023 data and observes steady KPI growth such as sales, and product page views. However, the analytics team wonders what factors drive that growth, is it advertising, price promotion, or simply organic growth due to shopper trends? Answers to this question are key to understanding past growth. Furthermore, this advertiser wants actionable suggestions for business planning, such as spending on areas with higher returns on investment to double down next.
In the following scenario, we will use DoWhy two-fold: first to causally attribute KPI growth drivers properly, so the analytics team understands what fueled past growth in a data-driven way. Second, we conduct interventions based on causal impact estimates to derive incremental return on investment (iROI), so the advertiser can forecast future KPI growth with additional investment. These factors and KPIs are: \n", + "* **dsp_spend**: Ad spend on Demand Side Platform (DSP) through display ads\n", + "* **sp_spend**: Ad spend on search results pages to bump up product rankings for easy discovery \n", + "* **discount**: Discounts given through price reductions\n", + "* **special_shopping_event**: A binary variable indicating whether a shopping event hosted by the ecommerce platform took place, such as Black Friday or Cyber Monday \n", + "* **other_shopping_event**: A binary variable indicating other shopping events off the ecommerce platform. It can be from the advertiser itself, or its advertising with other platforms. \n", + "* **dpv**: Number of product detail page views\n", + "* **sale**: Daily revenue on the focal ecommerce platform" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "671dc59b", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import networkx as nx\n", + "import numpy as np\n", + "import pandas as pd\n", + "from functools import partial\n", + "from dowhy import gcm\n", + "from dowhy.utils.plotting import plot\n", + "\n", + "from scipy import stats\n", + "from statsmodels.stats.multitest import multipletests\n", + "\n", + "%matplotlib inline" + ] + }, + { + "cell_type": "markdown", + "id": "de1ed2e1", + "metadata": {}, + "source": [ + "## 1. Explore the data\n", + "\n", + "First, let's load our data representing the spending, discounts, sale and other information for 2023 and 2024. Note that for this simulated data, we didn't change the distribution of price discounts over periods of comparison and shouldn't detect as such in the later attribution model. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "81bc8978", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "df = pd.read_csv('datasets/sale_attribution.csv', index_col=0)\n", + "df.head()" + ] + }, + { + "cell_type": "markdown", + "id": "29af43df-4406-44ef-b44f-77d6cdaf1cc2", + "metadata": {}, + "source": [ + "To causally attribute factors of interests to changes, we first need to define time periods for comparisons. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "502a8f3f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def generate_new_old_dataframes(df, new_year, new_quarters, new_months, old_year, old_quarters, old_months):\n", + " # Filter new data based on year, quarters, and months\n", + " new_conditions = (df['year'] == new_year) & (df['quarter'].isin(new_quarters)) & (df['month'].isin(new_months))\n", + " df_new = df[new_conditions].copy()\n", + "\n", + " # Filter old data based on year, quarters, and months\n", + " old_conditions = (df['year'] == old_year) & (df['quarter'].isin(old_quarters)) & (df['month'].isin(old_months))\n", + " df_old = df[old_conditions].copy()\n", + "\n", + " return df_new, df_old\n", + "\n", + "df_new, df_old = generate_new_old_dataframes(df, new_year=2024, new_quarters=[1,2], new_months=[1,2,3,4,5,6], old_year=2023, old_quarters=[1,2], old_months=[1,2,3,4,5,6])" + ] + }, + { + "cell_type": "markdown", + "id": "5c3b2dfe", + "metadata": {}, + "source": [ + "Then we define cumulative distribution functions to eyeball changes in metrics across two periods. Let's plot them:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cc8b8a7d", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def plot_metric_distributions(df_new, df_old, metric_columns):\n", + " for metric_column in metric_columns:\n", + " fig, ax = plt.subplots()\n", + " \n", + " kde_new = stats.gaussian_kde(df_new[metric_column].dropna())\n", + " kde_old = stats.gaussian_kde(df_old[metric_column].dropna())\n", + " \n", + " x_range = np.linspace(\n", + " min(df_new[metric_column].min(), df_old[metric_column].min()),\n", + " max(df_new[metric_column].max(), df_old[metric_column].max()),\n", + " 1000\n", + " )\n", + " ax.plot(x_range, kde_new(x_range), color='#FF6B6B', lw=2, label='After')\n", + " ax.plot(x_range, kde_old(x_range), color='#4ECDC4', lw=2, label='Before')\n", + " \n", + " ax.fill_between(x_range, kde_new(x_range), alpha=0.3, color='#FF6B6B')\n", + " ax.fill_between(x_range, kde_old(x_range), alpha=0.3, color='#4ECDC4')\n", + "\n", + " ax.set_xlabel(metric_column)\n", + " ax.set_ylabel('Density')\n", + " ax.set_title(f'Comparison of {metric_column} distribution')\n", + "\n", + " ax.spines['top'].set_visible(False)\n", + " ax.spines['right'].set_visible(False)\n", + " \n", + " ax.grid(True, linestyle='--', alpha=0.7)\n", + " ax.legend(fontsize=10)\n", + "\n", + " plt.tight_layout()\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "37904e2e-ae77-4a24-b5aa-a0769f6fe541", + "metadata": {}, + "source": [ + "Here, we are interested in the 'dpv' and 'sale' variables." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "402264f5", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Define KPI\n", + "metric_columns = ['dpv', 'sale'] \n", + "plot_metric_distributions(df_new, df_old, metric_columns)" + ] + }, + { + "cell_type": "markdown", + "id": "ddaecc17", + "metadata": {}, + "source": [ + "We can further quantify the magnitude of changes by comparing mean, median and variance of both KPIs and potential drivers. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2e932e4c-af36-4083-ad78-036cd39433c2", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def compare_metrics(df_new, df_old, metrics):\n", + " comparison_data = []\n", + "\n", + " for metric in metrics:\n", + " try:\n", + " mean_old = df_old[metric].mean()\n", + " median_old = df_old[metric].median()\n", + " variance_old = df_old[metric].var()\n", + " \n", + " mean_new = df_new[metric].mean()\n", + " median_new = df_new[metric].median()\n", + " variance_new = df_new[metric].var()\n", + " \n", + " if mean_old == 0:\n", + " print(f\"Mean for {metric} in the old data is zero. Skipping mean change calculation.\")\n", + " mean_change = None\n", + " else:\n", + " mean_change = ((mean_new - mean_old) / mean_old) * 100\n", + "\n", + " if median_old == 0:\n", + " print(f\"Median for {metric} in the old data is zero. Skipping median change calculation.\")\n", + " median_change = None\n", + " else:\n", + " median_change = ((median_new - median_old) / median_old) * 100\n", + "\n", + " if variance_old == 0:\n", + " print(f\"Variance for {metric} in the old data is zero. Skipping variance change calculation.\")\n", + " variance_change = None\n", + " else:\n", + " variance_change = ((variance_new - variance_old) / variance_old) * 100\n", + " \n", + " comparison_data.append({\n", + " 'Metric': metric,\n", + " 'Δ mean': mean_change,\n", + " 'Δ median': median_change,\n", + " 'Δ variance': variance_change\n", + " })\n", + " except KeyError as e:\n", + " print(f\"Metric {metric} not found in one of the DataFrames: {e}\")\n", + " pass\n", + "\n", + " comparison_df = pd.DataFrame(comparison_data)\n", + " return comparison_df" + ] + }, + { + "cell_type": "markdown", + "id": "c9e55350-6582-4baa-b707-f92f53e8f979", + "metadata": { + "tags": [] + }, + "source": [ + "For simplicity, below we assume KPIs are revenue (sale), and product views (DPV), with potential drivers including ad spend on demand side platform (dsp_spend) and search results (sp_spend), and price promotion (discount)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6ed87c2d-1766-4a22-89e5-72f5ebeaef75", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "comparison_df = compare_metrics(df_new, df_old, ['sale', 'dpv', 'dsp_spend', 'sp_spend', 'discount'])\n", + "print(comparison_df)" + ] + }, + { + "cell_type": "markdown", + "id": "1ffd24ec", + "metadata": {}, + "source": [ + "## 2. Draw causal graph" + ] + }, + { + "cell_type": "markdown", + "id": "a26f4482", + "metadata": {}, + "source": [ + "### 2.1.Set up basic causal graphs \n", + "\n", + "In the first step, we make use of our domain knowledge that all the ad investment and the shopping events can be potential causes of product page views and sale, but not vice versa. Further, detail page views can also lead to sales, regardless of ad investment. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6be2afc6", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "edges = []\n", + "for col in df.columns:\n", + " if 'spend' in col:\n", + " edges.append((col, 'dpv'))\n", + " edges.append((col, 'sale'))\n", + "edges.append(('special_shopping_event', 'dpv')) \n", + "edges.append(('other_shopping_event', 'dpv'))\n", + "edges.append(('special_shopping_event', 'sale')) \n", + "edges.append(('other_shopping_event', 'sale'))\n", + "edges.append(('discount', 'sale')) \n", + "edges.append(('dpv', 'sale'))\n", + "\n", + "causal_graph = nx.DiGraph(edges)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bed7a9e2", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "plot(causal_graph)" + ] + }, + { + "cell_type": "markdown", + "id": "96cf0a02", + "metadata": {}, + "source": [ + "It is unlikely that all these edges are significant. Let's prune some potential causes in the next step. This is to have a more refined causal graph. i.e, closer to the truth. " + ] + }, + { + "cell_type": "markdown", + "id": "d3fd49f7", + "metadata": { + "tags": [] + }, + "source": [ + "### 2.2. Prune nodes and edges " + ] + }, + { + "cell_type": "markdown", + "id": "a66222c5", + "metadata": {}, + "source": [ + "One way to prune insignificant causal connections is conducting causal minimality tests through statistical dependence tests. The causality minimality test rules out any parent-child edge ($X\\to Y$) for a node $Y$ if $Y$ is conditionally independent of $X$ given other parents of $Y$. If that is the case, node $X$ does not provide additional information on top of the other parents of $Y$. In layman's language, some ads may not provide incremental information in the presence of others. Thus, we can remove those edges of $X \\to Y$. Note that the test is adjusted for multihypothesis testing to guarantee a consistent false discovery rate." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bb612e8e", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def test_causal_minimality(graph, target, data, method='kernel', significance_level=0.10, fdr_control_method='fdr_bh'):\n", + " p_vals = []\n", + " all_parents = list(graph.predecessors(target))\n", + " for node in all_parents:\n", + " tmp_conditioning_set = list(all_parents)\n", + " tmp_conditioning_set.remove(node)\n", + " p_vals.append(gcm.independence_test(data[target].to_numpy(), data[node].to_numpy(), data[tmp_conditioning_set].to_numpy(), method=method)) \n", + " \n", + " if fdr_control_method is not None:\n", + " p_vals = multipletests(p_vals, significance_level, method=fdr_control_method)[1]\n", + " \n", + " nodes_above_threshold = []\n", + " nodes_below_threshold = []\n", + " for i, node in enumerate(all_parents):\n", + " if p_vals[i] < significance_level:\n", + " nodes_above_threshold.append(node) \n", + " else:\n", + " nodes_below_threshold.append(node)\n", + " \n", + " print(\"Significant connection:\", [(n, target) for n in sorted(nodes_above_threshold)])\n", + " print(\"Insignificant connection:\", [(n, target) for n in sorted(nodes_below_threshold)])\n", + " \n", + " return sorted(nodes_below_threshold)" + ] + }, + { + "cell_type": "markdown", + "id": "d1ca09a1-9dd0-41fe-8884-576e510a2daf", + "metadata": { + "tags": [] + }, + "source": [ + "Then we remove insignificant edges and their associated nodes, resulting a refined causal graph. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a24b69ad", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "for insignificant_parent in test_causal_minimality(causal_graph, 'sale', df):\n", + " causal_graph.remove_edge(insignificant_parent, 'sale')\n", + "\n", + "cols_to_remove=[]\n", + "cols_to_remove.extend([node for node in causal_graph.nodes if causal_graph.in_degree(node) + causal_graph.out_degree(node) == 0])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34b2eda5", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "causal_graph.remove_nodes_from(cols_to_remove)\n", + "plot(causal_graph)" + ] + }, + { + "cell_type": "markdown", + "id": "630fed0a", + "metadata": {}, + "source": [ + "## 3. Fit causal graph " + ] + }, + { + "cell_type": "markdown", + "id": "4d7468ec", + "metadata": {}, + "source": [ + "Next, we need to assign functional causal models (FCMs) to each node, which describe the data generation process from x to y with an error term. The auto assignment method compares different prediction models for each node and takes the one with the smallest error. The `quality` parameter controls the set of model types that are tested, where `BETTER` indicates some of the most common regression and classification models, such as trees, support vector regression etc. You can also use 'Good' which fits fewer models to speed up, or 'Best' that is computationally heavy. After assigning the models, we can fit them to the data:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ecc52227", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "causal_model = gcm.StructuralCausalModel(causal_graph)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "36362ed7", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "print(gcm.auto.assign_causal_mechanisms(causal_model, df, quality=gcm.auto.AssignmentQuality.BETTER))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ea648e8c", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "gcm.fit(causal_model, df)" + ] + }, + { + "cell_type": "markdown", + "id": "83d92578", + "metadata": {}, + "source": [ + "## 4. Identify causal drivers for KPI changes " + ] + }, + { + "cell_type": "markdown", + "id": "202e06e5", + "metadata": {}, + "source": [ + "To answer the question on drivers for past growth, we test if any of the potential drivers lead to KPI changes by comparing the data from 2023 and 2024. Below we quantify the contribution to changes in the mean of our KPI, but one can similarly estimate the contributions with respect to the median or variance etc. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "70afd219-707f-4c73-a4fe-807920b78613", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def calculate_difference_estimation(causal_model, df_old, df_new, target_column, difference_estimation_func, num_samples=2000, confidence_level=0.90, num_bootstrap_resamples=10):\n", + "\n", + " difference_contribs, uncertainty_contribs = gcm.confidence_intervals(\n", + " lambda : gcm.distribution_change(causal_model, \n", + " df_old, \n", + " df_new, \n", + " target_column, \n", + " num_samples=num_samples,\n", + " independence_test=lambda x, y: gcm.kernel_based(x.astype(float), y.astype(float)),\n", + " conditional_independence_test=lambda x, y, z: gcm.kernel_based(x.astype(float), y.astype(float), z.astype(float)),\n", + " difference_estimation_func=difference_estimation_func,\n", + " shapley_config=gcm.shapley.ShapleyConfig(approximation_method=gcm.shapley.ShapleyApproximationMethods.PERMUTATION, num_permutations=20)),\n", + " confidence_level=confidence_level,\n", + " num_bootstrap_resamples=num_bootstrap_resamples\n", + " )\n", + "\n", + " return difference_contribs, uncertainty_contribs\n", + "\n", + "median_diff_contribs, median_diff_uncertainty = calculate_difference_estimation(causal_model, df_old, df_new, 'sale', lambda x1, x2: np.mean(x2) - np.mean(x1))" + ] + }, + { + "cell_type": "markdown", + "id": "18a8208a-2e1b-4048-a15b-56d8bd9e7768", + "metadata": {}, + "source": [ + "Then we plot drivers' contribution to KPI changes visually, followed by a tabular format. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c7e42600", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "gcm.util.bar_plot(median_diff_contribs, median_diff_uncertainty, 'Contribution', figure_size=(10,5))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4cc6ac14", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def show_tabular(median_contribs, uncertainty_contribs):\n", + " rows = []\n", + " for node, median_contrib in median_contribs.items():\n", + " rows.append(dict(node=node, median=median_contrib, lb=uncertainty_contribs[node][0], ub=uncertainty_contribs[node][1]))\n", + " df = pd.DataFrame(rows).set_index('node')\n", + " df.rename(columns=dict(median='median', lb='lb', ub='ub'), inplace=True)\n", + " return df\n", + " \n", + "# show_tabular(median_contribs, uncertainty_contribs)\n", + "result_df = pd.DataFrame(show_tabular(median_diff_contribs, median_diff_uncertainty))\n", + "result_df" + ] + }, + { + "cell_type": "markdown", + "id": "d2ab2655-0d80-4112-8e65-1a27a3622b37", + "metadata": {}, + "source": [ + "Here, we see that 'sp_spend' has the larges contrigution to the change in the mean of 'sale', while the 'discount', 'other_shopping_event' and 'special_shopping_event' has little to none contribution. This aligns with the way how the data was generated.\n", + "\n", + "Next, we remove all variables that have a 0 as part of their confidence interval or are negative, i.e., do not have a clear significant positive contribution:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "85396307-7dee-4606-909b-b0c24900a7a9", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def filter_significant_rows(result_df, direction, ub_col, lb_col):\n", + "\n", + " if direction == 'positive':\n", + " significant_rows = result_df[(result_df[ub_col] > 0) & (result_df[lb_col] > 0)]\n", + " elif direction == 'negative':\n", + " significant_rows = result_df[(result_df[ub_col] < 0) & (result_df[lb_col] < 0)]\n", + " else:\n", + " raise ValueError(\"Invalid direction. Choose 'positive' or 'negative'.\")\n", + "\n", + " return significant_rows" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "81e7ce4c-3a6e-49df-a636-5fd226f5dfd9", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "positive_significant_rows = filter_significant_rows(result_df, 'positive', 'ub', 'lb')\n", + "positive_significant_rows" + ] + }, + { + "cell_type": "markdown", + "id": "65649c3b-a290-49f3-af4b-5086dc9a156f", + "metadata": {}, + "source": [ + "This tells us, 'dsp_spend' and 'sp_spend' had a significantly positive contribution to the shift in 'sale'." + ] + }, + { + "cell_type": "markdown", + "id": "221a3f07-f04c-4f0d-95bf-7cb0199b3e48", + "metadata": { + "tags": [] + }, + "source": [ + "## 5. Optimal intervention" + ] + }, + { + "cell_type": "markdown", + "id": "5908d58e-a928-4a85-9a72-2ec2a53fa3d0", + "metadata": {}, + "source": [ + "Section 4 above helps us to understand drivers for past growth. Now, looking forward to business planning, we conduct interventions to understand incremental contributions to KPIs. Intuitively, the spend types resulting in higher returns should be doubled down on. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b6bee9e7-ed99-4cbc-9c70-6b0552de4338", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "def intervention_influence(causal_model, target, data=None, step_size=1, non_interveneable_nodes=None, confidence_level=0.90, cap_value=None, prints=False):\n", + " progress_bar_was_on = gcm.config.show_progress_bars\n", + "\n", + " if progress_bar_was_on:\n", + " gcm.config.disable_progress_bars()\n", + " \n", + " causal_effects = {}\n", + " causal_effects_confidence_interval = {}\n", + " capped_effects = []\n", + "\n", + " if non_interveneable_nodes is None:\n", + " non_interveneable_nodes = []\n", + " \n", + " for node in causal_model.graph.nodes:\n", + " if node in non_interveneable_nodes:\n", + " continue\n", + "\n", + " # Define interventions\n", + " def intervention(x):\n", + " return x + step_size\n", + "\n", + " def non_intervention(x):\n", + " return x\n", + " \n", + " interventions_alternative = {node: intervention}\n", + " interventions_reference = {node: non_intervention}\n", + "\n", + " # Compute causal effects\n", + " if data is not None:\n", + " effect = gcm.confidence_intervals(\n", + " gcm.fit_and_compute(gcm.average_causal_effect,\n", + " causal_model,\n", + " auto_assign_quality=gcm.auto.AssignmentQuality.GOOD,\n", + " bootstrap_training_data=data,\n", + " target_node=target,\n", + " interventions_alternative=interventions_alternative,\n", + " interventions_reference=interventions_reference,\n", + " observed_data=data),\n", + " n_jobs=1,\n", + " num_bootstrap_resamples=10,\n", + " confidence_level=confidence_level)\n", + " else:\n", + " effect = gcm.confidence_intervals(\n", + " partial(gcm.average_causal_effect,\n", + " causal_model=causal_model,\n", + " target_node=target,\n", + " interventions_alternative=interventions_alternative,\n", + " interventions_reference=interventions_reference,\n", + " observed_data=data,\n", + " num_samples_to_draw=10000),\n", + " n_jobs=-1,\n", + " num_bootstrap_resamples=20,\n", + " confidence_level=confidence_level)\n", + "\n", + "\n", + " causal_effects[node] = effect[0][0]\n", + " causal_effects_confidence_interval[node] = effect[1].squeeze()\n", + " \n", + " # Apply capping constraint\n", + " if cap_value is not None and node.endswith('_spend'):\n", + " if causal_effects[node] > cap_value:\n", + " causal_effects[node] = cap_value\n", + " capped_effects.append(node)\n", + " elif causal_effects[node] < -cap_value:\n", + " causal_effects[node] = -cap_value\n", + " capped_effects.append(node)\n", + "\n", + " # Apply non-negativity constraint\n", + " if node.endswith('_spend') and causal_effects[node] < 0:\n", + " causal_effects[node] = 0\n", + " causal_effects_confidence_interval[node] = [np.nan, np.nan]\n", + "\n", + " if progress_bar_was_on:\n", + " gcm.config.enable_progress_bars()\n", + "\n", + " if prints:\n", + " for node in sorted(causal_effects, key=causal_effects.get, reverse=True):\n", + " if causal_effects[node] == 0:\n", + " print(f\"{'Increasing' if step_size > 0 else 'Decreasing'} {node} by {step_size} has no effect on {target}.\")\n", + " else:\n", + " print(f\"{'Increasing' if step_size > 0 else 'Decreasing'} {node} by {step_size} {'increases' if causal_effects[node] > 0 else 'decreases'} {target} \"\n", + " f\"by around {causal_effects[node]} with a confidence interval ({confidence_level * 100}%) of {causal_effects_confidence_interval[node]}.\")\n", + "\n", + " all_variables = list(causal_effects.keys())\n", + " all_causal_effects = [causal_effects[key] for key in all_variables]\n", + " all_lower_bounds = [causal_effects_confidence_interval[key][0] for key in all_variables]\n", + " all_upper_bounds = [causal_effects_confidence_interval[key][1] for key in all_variables]\n", + " result_df = pd.DataFrame({'Variable': all_variables, \n", + " 'Causal Effect': all_causal_effects, \n", + " 'Lower CI': all_lower_bounds, \n", + " 'Upper CI': all_upper_bounds},\n", + " index = all_variables)\n", + " \n", + " return result_df" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5c42552e-9349-4182-b404-eab91ab70a8f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "interv_result = intervention_influence(causal_model=causal_model, target='sale', non_interveneable_nodes=['dpv', 'sale'], confidence_level=0.85, cap_value=20, prints=True)\n", + "interv_result" + ] + }, + { + "cell_type": "markdown", + "id": "8bce37de-ca68-42ce-aac1-6a86d7834320", + "metadata": {}, + "source": [ + "We similarly filter to positively significant interventions, i.e., the spending with statistically significant positive returns. Note that with capping, 'causal effect' may not fall between lower and upper CI. The interpretation is, for each dollar spent on one type of ad, we receive X amount in return, with X indicated in the 'Causal Effect' column. " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f5f2e83a-3fed-4a75-9936-fd817153367a", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "interv_result_v2= filter_significant_rows(interv_result, 'positive', 'Upper CI', 'Lower CI')\n", + "interv_result_v2" + ] + }, + { + "cell_type": "markdown", + "id": "bb5a679d-b0c9-48c0-ba2d-9f9654491370", + "metadata": {}, + "source": [ + "## Summary" + ] + }, + { + "cell_type": "markdown", + "id": "532c4ee0-9b9a-48c0-9e49-d7b093116bb9", + "metadata": {}, + "source": [ + "This advertiser comes to us to understand what drove past growth. Starting with a causal graph drawn from domain knowledge, we refined the graph to prune unnecessary nodes and edges. Then we fit a causal attribution model in Section 4 to test which types of investment changes lead to KPI growth. We find that increases in both dsp_spend and sp_spend contribute to KPIs growth in 2024 vs. 2023. This conclusion helps the analytics team to understand root causes of past sales growth. Looking forward to future budget planning, we conducted interventions to understand incremental return on investment (iROI), and identify those types of spend way above $1 to double down on." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.18" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}