import%20marimo%0A%0A__generated_with%20%3D%20%220.25.0%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20coeftable%20as%20ct%0A%20%20%20%20import%20ibis%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20from%20_seed%20import%20seed_event_log%0A%0A%20%20%20%20from%20increment%20import%20Analysis%0A%20%20%20%20from%20increment.tables%20import%20estimates_to_readout%2C%20readout_table%0A%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20Analysis%2C%0A%20%20%20%20%20%20%20%20ct%2C%0A%20%20%20%20%20%20%20%20estimates_to_readout%2C%0A%20%20%20%20%20%20%20%20ibis%2C%0A%20%20%20%20%20%20%20%20mo%2C%0A%20%20%20%20%20%20%20%20readout_table%2C%0A%20%20%20%20%20%20%20%20seed_event_log%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Breakouts%3A%20per-segment%20lifts%20and%20metric%20trends%20over%20time%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20DEFINITIONS%20%3D%20%22examples%2Fdefinitions%2F%22%0A%20%20%20%20EXPERIMENT%20%3D%20%22new_onboarding_v2%22%0A%20%20%20%20return%20DEFINITIONS%2C%20EXPERIMENT%0A%0A%0A%40app.cell%0Adef%20_(ibis%2C%20seed_event_log)%3A%0A%20%20%20%20con%20%3D%20ibis.duckdb.connect()%0A%20%20%20%20%23%20Keep%20this%20documentation%20example%20compact%20while%20retaining%20every%20displayed%0A%20%20%20%20%23%20daily%2C%20as-of%2C%20and%20country-breakout%20path.%20The%20generator%20default%20remains%0A%20%20%20%20%23%204%2C000%20units%20for%20production-like%20examples%3B%20this%20fixed%20seed%20and%20800-unit%0A%20%20%20%20%23%20slice%20are%20for%20informative%20API%2Ffigure%20rendering%2C%20not%20power%20claims.%0A%20%20%20%20seed_event_log(con%2C%20n_units%3D800%2C%20seed%3D2025)%0A%20%20%20%20return%20(con%2C)%0A%0A%0A%40app.cell%0Adef%20_(Analysis%2C%20DEFINITIONS%2C%20EXPERIMENT%2C%20con)%3A%0A%20%20%20%20analysis%20%3D%20Analysis(experiment_name%3DEXPERIMENT%2C%20definitions_path%3DDEFINITIONS%2C%20con%3Dcon)%0A%20%20%20%20return%20(analysis%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%20Segment%20and%20Date%20Breakout%0A%0A%20%20%20%20While%20its%20typically%20ideal%20to%20have%20a%20well%20planned%20and%20well%20powered%20experiment%20with%20a%20set%20duration%20and%20minimal%20peeking%2C%20lifes%20not%20always%20so%20simple.%20There%20could%20be%20issues%20with%20a%20hashing%20algorithm%2C%20interactions%20with%20another%20experiment%20or%20a%20bug%2C%20novelty%20effects%2C%20segment%20level%20effects%20(maybe%20the%20feature%20doesnt%20render%20well%20on%20mobile)%2C%20or%20even%20just%20a%20stakeholder%20who%20wants%20to%20dive%20deeper.%0A%0A%20%20%20%20This%20notebook%20highlights%20metric%20breakouts%20for%20daily%2C%20segment%2C%20and%20daily-segment%20level%20views.%20It%20uses%20a%20compact%20deterministic%20800-unit%20seed%20so%20every%20view%20stays%20quick%20and%20informative%3B%20the%20generated%20data%20is%20for%20demonstrating%20the%20APIs%20and%20figures%2C%20not%20for%20making%20a%20power%20or%20significance%20claim.%0A%0A%20%20%20%20%23%23%20Per-segment%20lift%3A%20does%20the%20effect%20vary%20by%20country%3F%0A%0A%20%20%20%20%60new_onboarding_v2%60%20declares%20one%20breakout%2C%20%60country%60%0A%20%20%20%20(%60examples%2Fdefinitions%2Fexperiments.yaml%60).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(analysis%2C%20estimates_to_readout%2C%20readout_table)%3A%0A%20%20%20%20%23%20new_onboarding_v2%20declares%20Bonferroni%20segmented%20views%20in%0A%20%20%20%20%23%20examples%2Fdefinitions%2Fexperiments.yaml%3B%20its%20plan%20keeps%20fixed-horizon%0A%20%20%20%20%23%20inference%20because%20the%20declared%20retention%20guardrail%20carries%20a%20prior.%0A%20%20%20%20breakout_estimates%20%3D%20analysis.run_breakout()%0A%20%20%20%20breakout_table%20%3D%20readout_table(%0A%20%20%20%20%20%20%20%20estimates_to_readout(breakout_estimates)%2C%0A%20%20%20%20%20%20%20%20title%3D%22new_onboarding_v2%20readout%2C%20by%20country%22%2C%0A%20%20%20%20%20%20%20%20subtitle%3D%22Relative%20lift%20vs%20control%2C%20Bonferroni-adjusted%20intervals%20(95%25%20family-wise%20coverage%20per%20metric)%22%2C%0A%20%20%20%20%20%20%20%20nest_by%3D%22segment%22%2C%0A%20%20%20%20%20%20%20%20show_interval_level%3DFalse%2C%0A%20%20%20%20%20%20%20%20%23%20visualize%20time%20series%0A%20%20%20%20%20%20%20%20trend%3Danalysis.run_asof_lift(dimension%3D%22country%22)%2C%0A%20%20%20%20%20%20%20%20trend_label%3D%22As-of%20lift%20trend%22%2C%0A%20%20%20%20)%0A%20%20%20%20breakout_table%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Metric%20values%20over%20time%0A%0A%20%20%20%20The%20section%20above%20focused%20on%20the%20running%20lift.%20Below%2C%20we're%20focusing%20on%20the%20actual%20metric%20values%20over%20time%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(analysis%2C%20ct)%3A%0A%20%20%20%20daily_values%20%3D%20analysis.run_daily()%0A%20%20%20%20daily_frame%20%3D%20daily_values.to_frame()%0A%0A%20%20%20%20value_table%20%3D%20(%0A%20%20%20%20%20%20%20%20ct.CoefTable(daily_frame%5B%5B%22metric%22%5D%5D.drop_duplicates()%2C%20rows%3D%22metric%22)%0A%20%20%20%20%20%20%20%20.sparkline(%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Value%20over%20time%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20value%3D%22value%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ci%3D(%22lb%22%2C%20%22ub%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D%22ds%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20data%3Ddaily_frame%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ref%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20series%3D%22group_id%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20show_ribbon%3DTrue%2C%20%20%23%202%20overlapping%20arms%20at%20low%20opacity%20stays%20legible%0A%20%20%20%20%20%20%20%20%20%20%20%20axis_fmt%3Dct.DateAxis()%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20.header(%22Metric%20values%20over%20time%22%2C%20%22One%20line%20per%20arm%2C%20per%20metric%22)%0A%20%20%20%20)%0A%20%20%20%20value_table%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Metric%20values%20over%20time%2C%20by%20segment%0A%0A%20%20%20%20%60Analysis.run_daily(dimension%3D%22country%22)%60%20breaks%20the%20view%0A%20%20%20%20above%20out%20by%20%60new_onboarding_v2%60's%20declared%20%60country%60%20breakout%20instead%20of%0A%20%20%20%20collapsing%20across%20it%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(analysis%2C%20ct)%3A%0A%20%20%20%20segment_daily_values%20%3D%20analysis.run_daily(dimension%3D%22country%22)%0A%20%20%20%20segment_daily_frame%20%3D%20segment_daily_values.to_frame()%0A%20%20%20%20segment_daily_frame%20%3D%20segment_daily_frame%5B%0A%20%20%20%20%20%20%20%20segment_daily_frame%5B%22group_id%22%5D%20!%3D%20analysis.experiment.control_group%0A%20%20%20%20%5D%0A%0A%20%20%20%20segment_value_table%20%3D%20(%0A%20%20%20%20%20%20%20%20ct.CoefTable(segment_daily_frame%5B%5B%22metric%22%5D%5D.drop_duplicates()%2C%20rows%3D%22metric%22)%0A%20%20%20%20%20%20%20%20.sparkline(%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Value%20by%20segment%20(treatment%20arm)%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20value%3D%22value%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ci%3D(%22lb%22%2C%20%22ub%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D%22ds%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20data%3Dsegment_daily_frame%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ref%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20series%3D%22dimension_value%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20axis_fmt%3Dct.DateAxis()%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20.header(%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Metric%20values%20over%20time%2C%20by%20segment%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Treatment%20arm%20only%2C%20one%20line%20per%20country%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20)%0A%20%20%20%20segment_value_table%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20As-of%20metric%20values%20over%20time%0A%0A%20%20%20%20This%20view%20shows%20the%20same%20per-arm%20credible-interval%20band%20as%20the%20section%20above%2C%20but%20each%0A%20%20%20%20day's%20value%20is%20a%20RUNNING%20TOTAL%20%22as%20of%20day%20N%22%20instead%20of%20that%20day's%20independent%20snapshot.%0A%0A%20%20%20%20This%20is%20%20particularly%20useful%20to%20see%20how%20a%20metric%20within%20the%20experiment%20is%20changing%20over%20time%20based%20on%20time%2C%20enrollment%2C%20or%20window%20dynamics.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(analysis%2C%20ct)%3A%0A%20%20%20%20%23%20its%20series%20starts%20late%2C%20absent%20until%20the%20first%20cohort%20matures.%0A%20%20%20%20asof_values%20%3D%20analysis.run_asof()%0A%20%20%20%20asof_frame%20%3D%20asof_values.to_frame()%0A%0A%20%20%20%20asof_table%20%3D%20(%0A%20%20%20%20%20%20%20%20ct.CoefTable(asof_frame%5B%5B%22metric%22%5D%5D.drop_duplicates()%2C%20rows%3D%22metric%22)%0A%20%20%20%20%20%20%20%20.sparkline(%0A%20%20%20%20%20%20%20%20%20%20%20%20%22As-of%20value%20over%20time%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20value%3D%22value%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ci%3D(%22lb%22%2C%20%22ub%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20x%3D%22ds%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20data%3Dasof_frame%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ref%3DNone%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20series%3D%22group_id%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20show_ribbon%3DTrue%2C%20%20%23%202%20overlapping%20arms%20at%20low%20opacity%20stays%20legible%0A%20%20%20%20%20%20%20%20%20%20%20%20axis_fmt%3Dct.DateAxis()%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20.header(%22As-of%20metric%20values%20over%20time%22%2C%20%22One%20line%20per%20arm%2C%20per%20metric%2C%20running%20total%22)%0A%20%20%20%20)%0A%20%20%20%20asof_table%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Lift%20over%20time%0A%0A%20%20%20%20This%20view%20shows%20the%20independent%20daily%20lift%20each%20day.%20Note%2C%20this%20is%20different%20than%20the%20running%20lift%20(%60analysis.run_asof_lift()%60)%2C%20as%20this%20approach%20just%20looks%20at%20only%20data%20from%20a%20single%20day.%20It%20is%20particularly%20useful%20for%20identifying%20**novelty%20effects**%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(analysis%2C%20estimates_to_readout%2C%20readout_table)%3A%0A%20%20%20%20daily_lift%20%3D%20analysis.run_daily_lift()%0A%20%20%20%20calendar_daily_lift%20%3D%20%5Be%20for%20e%20in%20daily_lift%20if%20e.ds_basis%20%3D%3D%20%22calendar%22%5D%0A%20%20%20%20estimates%20%3D%20analysis.run()%0A%20%20%20%20lift_table%20%3D%20readout_table(%0A%20%20%20%20%20%20%20%20estimates_to_readout(estimates)%2C%0A%20%20%20%20%20%20%20%20title%3D%22new_onboarding_v2%20readout%22%2C%0A%20%20%20%20%20%20%20%20subtitle%3D%22Relative%20lift%20vs%20control%2C%2095%20%25%20credible%20interval%22%2C%0A%20%20%20%20%20%20%20%20trend%3Dcalendar_daily_lift%2C%0A%20%20%20%20%20%20%20%20trend_label%3D%22Daily%20lift%22%2C%0A%20%20%20%20)%0A%20%20%20%20lift_table%0A%20%20%20%20return%20(estimates%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Running%20lift%20over%20time%0A%0A%20%20%20%20The%20running-total%20counterpart%20to%20the%20section%20above%3A%20%60Analysis.run_asof_lift()%60%20tells%20us%20%22what%20was%20the%20experiment%20lift%20as%20of%20a%20certain%20date%3F%22%0A%0A%20%20%20%20It%20is%20typically%20the%20best%20starting%20point%20for%20diving%20into%20an%20experiment%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(analysis%2C%20estimates%2C%20estimates_to_readout%2C%20readout_table)%3A%0A%20%20%20%20readout_table(%0A%20%20%20%20%20%20%20%20estimates_to_readout(estimates)%2C%0A%20%20%20%20%20%20%20%20title%3D%22new_onboarding_v2%20readout%2C%20as-of%20trend%22%2C%0A%20%20%20%20%20%20%20%20subtitle%3D%22Relative%20lift%20vs%20control%2C%2095%20%25%20credible%20interval%22%2C%0A%20%20%20%20%20%20%20%20trend%3Danalysis.run_asof_lift()%2C%0A%20%20%20%20%20%20%20%20trend_label%3D%22As-of%20lift%20trend%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
a3ab120bf50c49c17595bbbd89f426a8