Spaces:
Sleeping
Sleeping
| import math | |
| import gradio as gr | |
| def ab_test_analysis( | |
| n_a, | |
| resp_a, | |
| n_b, | |
| resp_b, | |
| ): | |
| # Basic validation | |
| try: | |
| n_a = int(n_a) | |
| resp_a = int(resp_a) | |
| n_b = int(n_b) | |
| resp_b = int(resp_b) | |
| except (TypeError, ValueError): | |
| return "β Please enter valid integers for all inputs." | |
| if n_a <= 0 or n_b <= 0: | |
| return "β Group sizes must be positive." | |
| if not (0 <= resp_a <= n_a and 0 <= resp_b <= n_b): | |
| return "β Responders must be between 0 and group size for each group." | |
| # Conversion rates | |
| rate_a = resp_a / n_a | |
| rate_b = resp_b / n_b | |
| abs_lift = rate_b - rate_a | |
| rel_lift = abs_lift / rate_a if rate_a > 0 else float("nan") | |
| # Two-sample z-test for proportions | |
| # H0: rate_a == rate_b ; H1: rate_a != rate_b | |
| pooled = (resp_a + resp_b) / (n_a + n_b) | |
| se = math.sqrt(pooled * (1 - pooled) * (1 / n_a + 1 / n_b)) | |
| if se == 0: | |
| z_val = 0.0 | |
| p_val = 1.0 | |
| else: | |
| z_val = (rate_b - rate_a) / se | |
| # normal CDF using erf | |
| cdf = 0.5 * (1 + math.erf(z_val / math.sqrt(2))) | |
| # two-sided p-value | |
| p_val = 2 * (1 - cdf) if z_val >= 0 else 2 * cdf | |
| # Interpretation | |
| significance = "statistically significant at Ξ± = 0.05" if p_val < 0.05 else "NOT statistically significant at Ξ± = 0.05" | |
| summary = f""" | |
| ## A/B Test Results β Pharmaceutical Refill Campaign | |
| **Input** | |
| - Group A (Control): **{n_a}** patients, **{resp_a}** refilled | |
| - Group B (Treatment): **{n_b}** patients, **{resp_b}** refilled | |
| **Conversion Rates** | |
| - Group A: **{rate_a:.2%}** | |
| - Group B: **{rate_b:.2%}** | |
| **Lift** | |
| - Absolute lift: **{abs_lift:.2%}** (percentage point difference) | |
| - Relative lift: **{rel_lift:.2%}** vs Group A | |
| **Statistical Test (Two-sample z-test for proportions)** | |
| - z-value: **{z_val:.3f}** | |
| - p-value: **{p_val:.4f}** | |
| - Result: The difference is **{significance}**. | |
| --- | |
| ### Interpretation | |
| In this example, Group B represents a **new intervention** (for example, a more personalized SMS reminder or additional pharmacist counseling), and Group A is the **current standard approach**. | |
| - If the p-value is below 0.05, you can say that the new strategy (Group B) **meaningfully improves** refill adherence. | |
| - If the p-value is above 0.05, the observed difference could be due to random variation, and you may need **more data** or a **different intervention**. | |
| You can update the inputs above with any A/B test from: | |
| - Different patient education materials | |
| - Different reminder frequency | |
| - Portal vs. SMS outreach | |
| - Pharmacist counseling vs. usual care | |
| """ | |
| return summary | |
| with gr.Blocks() as demo: | |
| gr.Markdown( | |
| """ | |
| # Pharmaceutical A/B Testing β Refill Adherence Example | |
| This demo compares two groups of patients: | |
| - **Group A (Control)** β current reminder process | |
| - **Group B (Treatment)** β new intervention (e.g., personalized SMS, educational content, or pharmacist counseling) | |
| Enter the number of patients and the number who refilled their prescription in each group. | |
| The app will calculate conversion rates, lift, and a simple statistical test. | |
| """ | |
| ) | |
| with gr.Row(): | |
| with gr.Column(): | |
| gr.Markdown("### Group A β Control") | |
| n_a = gr.Number(label="Number of patients in Group A", value=2000) | |
| resp_a = gr.Number(label="Number of refills in Group A", value=520) | |
| with gr.Column(): | |
| gr.Markdown("### Group B β Treatment") | |
| n_b = gr.Number(label="Number of patients in Group B", value=1900) | |
| resp_b = gr.Number(label="Number of refills in Group B", value=608) | |
| run_button = gr.Button("Run A/B Analysis") | |
| output = gr.Markdown() | |
| run_button.click( | |
| fn=ab_test_analysis, | |
| inputs=[n_a, resp_a, n_b, resp_b], | |
| outputs=output, | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch(share=True) |