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%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%2C%20Method%0A%20%20%20%20from%20increment.results%20import%20LiftEstimate%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%20LiftEstimate%2C%0A%20%20%20%20%20%20%20%20Method%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%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20CUPED%20variance%20reduction%0A%0A%20%20%20%20CUPED%20uses%20pre-exposure%20activity%20as%20a%20covariate%20to%20reduce%20outcome%20variance.%0A%20%20%20%20This%20notebook%20runs%20the%20same%20experiment%20unadjusted%20and%20CUPED-adjusted%2C%20then%0A%20%20%20%20compares%20the%20estimates%20in%20one%20coeftable.%20The%20gain%20is%20clearest%20for%20continuous%0A%20%20%20%20metrics%3B%20binary%20metrics%20usually%20have%20less%20variance%20to%20remove.%0A%0A%20%20%20%20The%20method%20is%20derived%20in%20%5B%60docs%2Fguides%2Fcuped.md%60%5D(..%2Fdocs%2Fguides%2Fcuped.md).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Method)%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%0A%20%20%20%20UNADJUSTED%20%3D%20Method(name%3D%22unadjusted%22)%0A%20%20%20%20CUPED%20%3D%20Method(name%3D%22cuped%22%2C%20variance_reduction%3D%22cuped%22)%0A%0A%20%20%20%20%23%20Put%20the%20continuous%20metric%20first%3A%20it%20shows%20the%20clearest%20variance%20reduction.%0A%20%20%20%20METRIC_ORDER%20%3D%20(%22avg_session_duration%22%2C%20%22purchase_rate%22%2C%20%22d7_retention%22)%0A%20%20%20%20return%20CUPED%2C%20DEFINITIONS%2C%20EXPERIMENT%2C%20METRIC_ORDER%2C%20UNADJUSTED%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(LiftEstimate)%3A%0A%20%20%20%20def%20interval_width(estimate%3A%20LiftEstimate)%20-%3E%20float%3A%0A%20%20%20%20%20%20%20%20%22%22%22Width%20of%20a%20lift%20interval.%20%20%60%60lb%60%60%2F%60%60ub%60%60%20are%20always%20populated%20here.%22%22%22%0A%20%20%20%20%20%20%20%20lift%20%3D%20estimate.lift%0A%20%20%20%20%20%20%20%20assert%20lift.lb%20is%20not%20None%20and%20lift.ub%20is%20not%20None%2C%20%22run()%20always%20returns%20an%20interval%22%0A%20%20%20%20%20%20%20%20return%20lift.ub%20-%20lift.lb%0A%0A%20%20%20%20return%20(interval_width%2C)%0A%0A%0A%40app.cell%0Adef%20_(Analysis%2C%20DEFINITIONS%2C%20EXPERIMENT%2C%20ibis%2C%20seed_event_log)%3A%0A%20%20%20%20con%20%3D%20ibis.duckdb.connect()%0A%0A%20%20%20%20%23%20generate%20events%0A%20%20%20%20seed_event_log(con%2C%20with_pre_period%3DTrue)%0A%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_(CUPED%2C%20UNADJUSTED%2C%20analysis)%3A%0A%20%20%20%20%23%20One%20run%20computes%20both%20methods%20from%20the%20same%20queried%20moments.%0A%20%20%20%20estimates%20%3D%20analysis.run(decision_method%3DUNADJUSTED%2C%20sensitivity_methods%3D(CUPED%2C))%0A%0A%20%20%20%20by_method%20%3D%20%7B(est.metric%2C%20est.group_id%2C%20est.method)%3A%20est%20for%20est%20in%20estimates%7D%0A%20%20%20%20arms%20%3D%20sorted(%7Best.group_id%20for%20est%20in%20estimates%7D)%0A%20%20%20%20return%20arms%2C%20by_method%2C%20estimates%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(CUPED%2C%20METRIC_ORDER%2C%20UNADJUSTED%2C%20arms%2C%20by_method%2C%20interval_width%2C%20mo)%3A%0A%20%20%20%20_metric%20%3D%20METRIC_ORDER%5B0%5D%0A%20%20%20%20_widths%20%3D%20%5B%0A%20%20%20%20%20%20%20%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20interval_width(by_method%5B_metric%2C%20arm%2C%20UNADJUSTED.name%5D)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20interval_width(by_method%5B_metric%2C%20arm%2C%20CUPED.name%5D)%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20for%20arm%20in%20arms%0A%20%20%20%20%5D%0A%20%20%20%20_reductions%20%3D%20%5B1%20-%20adjusted%20%2F%20plain%20for%20plain%2C%20adjusted%20in%20_widths%5D%0A%0A%20%20%20%20_width_text%20%3D%20%22%3B%20%22.join(%0A%20%20%20%20%20%20%20%20f%22treatment%3A%20%7Bplain%3A.2%25%7D%20%E2%86%92%20%7Badjusted%3A.2%25%7D%22%20for%20plain%2C%20adjusted%20in%20_widths%0A%20%20%20%20)%0A%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20%23%23%20Readout%0A%0A%20%20%20%20CUPED%20reduces%20the%20%60%7B_metric%7D%60%20interval%20width%20by%0A%20%20%20%20**%7B_reductions%5B0%5D%3A.1%25%7D**%20(%7B_width_text%7D).%20The%20coeftable%20below%20shows%20the%20full%0A%20%20%20%20unadjusted-versus-CUPED%20estimate%20and%20interval%20comparison.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(estimates%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%22Unadjusted%20vs%20CUPED%22%2C%0A%20%20%20%20%20%20%20%20subtitle%3D%22Relative%20lift%20vs%20control%2C%2095%25%20credible%20interval%22%2C%0A%20%20%20%20%20%20%20%20nest_by%3D%22method%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Takeaway%0A%0A%20%20%20%20CUPED%20is%20most%20useful%20for%20continuous%20outcomes%20such%20as%20duration%2C%20revenue%2C%20and%0A%20%20%20%20counts.%20Binary%20outcomes%20such%20as%20conversion%20and%20retention%20usually%20see%20a%20smaller%0A%20%20%20%20reduction%20because%20less%20of%20their%20variance%20is%20predictable%20from%20pre-period%20data.%0A%20%20%20%20%22%22%22)%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
3c96c3390a74117ad162a99033915227