import%20marimo%0A%0A__generated_with%20%3D%20%220.18.4%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20seaborn%20as%20sns%0A%0A%20%20%20%20sns.set_style(%22whitegrid%22)%0A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Statistical%20Models%20Interactive%20Demo%0A%0A%20%20%20%20Explore%20the%20statistical%20distributions%20used%20in%20pyrf%3A%0A%20%20%20%20-%20**Poisson**%3A%20Univariate%20distribution%20for%20goal%20counts%0A%20%20%20%20-%20**Skellam**%3A%20Distribution%20for%20goal%20differences%0A%20%20%20%20-%20**BivariatePoisson**%3A%20Joint%20distribution%20for%20home%20and%20away%20goals%0A%20%20%20%20-%20**DixonColes**%3A%20Bivariate%20Poisson%20with%20Dixon-Coles%20low-score%20adjustment%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%20mo%2C%20pd%2C%20plt%2C%20sns%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Parameters%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20lambda_home%20%3D%20mo.ui.number(start%3D0.5%2C%20stop%3D3.5%2C%20step%3D0.1%2C%20value%3D1.5%2C%20label%3D%22%CE%BB_home%22)%0A%20%20%20%20lambda_away%20%3D%20mo.ui.number(start%3D0.5%2C%20stop%3D3.5%2C%20step%3D0.1%2C%20value%3D1.2%2C%20label%3D%22%CE%BB_away%22)%0A%20%20%20%20rho_input%20%3D%20mo.ui.number(start%3D-0.30%2C%20stop%3D0.10%2C%20step%3D0.01%2C%20value%3D-0.10%2C%20label%3D%22%CF%81%22)%0A%0A%20%20%20%20mo.hstack(%5Blambda_home%2C%20lambda_away%2C%20rho_input%5D%2C%20justify%3D%22start%22)%0A%20%20%20%20return%20lambda_away%2C%20lambda_home%2C%20rho_input%0A%0A%0A%40app.cell%0Adef%20_(lambda_away%2C%20lambda_home)%3A%0A%20%20%20%20import%20pyrf%20as%20rf%0A%0A%20%20%20%20grid%20%3D%20rf.GoalGrid(n%3D7)%0A%0A%20%20%20%20%23%20Create%20distributions%0A%20%20%20%20poisson_home%20%3D%20rf.Poisson(lambda_%3Dlambda_home.value)%0A%20%20%20%20poisson_away%20%3D%20rf.Poisson(lambda_%3Dlambda_away.value)%0A%20%20%20%20skellam%20%3D%20rf.Skellam(lambda_home%3Dlambda_home.value%2C%20lambda_away%3Dlambda_away.value)%0A%20%20%20%20bivariate%20%3D%20rf.BivariatePoisson(lambda_home%3Dlambda_home.value%2C%20lambda_away%3Dlambda_away.value)%0A%20%20%20%20return%20bivariate%2C%20grid%2C%20poisson_away%2C%20poisson_home%2C%20rf%2C%20skellam%0A%0A%0A%40app.cell%0Adef%20_(bivariate%2C%20rf%2C%20rho_input)%3A%0A%20%20%20%20adjusted%20%3D%20rf.models.DixonColes(dist%3Dbivariate%2C%20rho%3Drho_input.value)%0A%20%20%20%20return%20(adjusted%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Univariate%20Poisson%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(grid%2C%20lambda_away%2C%20lambda_home%2C%20pd%2C%20plt%2C%20poisson_away%2C%20poisson_home)%3A%0A%20%20%20%20import%20numpy%20as%20np%0A%0A%20%20%20%20goals%20%3D%20pd.Series(np.arange(grid.n%20%2B%201))%0A%0A%20%20%20%20fig1%2C%20ax1%20%3D%20plt.subplots(figsize%3D(10%2C%204))%0A%0A%20%20%20%20home_pmf%20%3D%20poisson_home.pmf(goals)%0A%20%20%20%20away_pmf%20%3D%20poisson_away.pmf(goals)%0A%0A%20%20%20%20width%20%3D%200.35%0A%20%20%20%20x%20%3D%20np.arange(len(goals))%0A%20%20%20%20ax1.bar(x%20-%20width%20%2F%202%2C%20home_pmf%2C%20width%2C%20label%3Df%22Home%20(%CE%BB%3D%7Blambda_home.value%3A.1f%7D)%22%2C%20alpha%3D0.7)%0A%20%20%20%20ax1.bar(x%20%2B%20width%20%2F%202%2C%20away_pmf%2C%20width%2C%20label%3Df%22Away%20(%CE%BB%3D%7Blambda_away.value%3A.1f%7D)%22%2C%20alpha%3D0.7)%0A%0A%20%20%20%20ax1.set_xlabel(%22Goals%22)%0A%20%20%20%20ax1.set_ylabel(%22Probability%22)%0A%20%20%20%20ax1.set_title(%22Poisson%20Goal%20Distributions%22)%0A%20%20%20%20ax1.legend()%0A%20%20%20%20ax1.set_xticks(x)%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20fig1%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Skellam%20(Goal%20Difference)%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(grid%2C%20lambda_away%2C%20lambda_home%2C%20plt%2C%20skellam)%3A%0A%20%20%20%20skellam_pmf%20%3D%20skellam.pmf(grid)%0A%0A%20%20%20%20fig2%2C%20ax2%20%3D%20plt.subplots(figsize%3D(10%2C%204))%0A%20%20%20%20skellam_pmf.plot.bar(ax%3Dax2%2C%20color%3D%22steelblue%22%2C%20alpha%3D0.7)%0A%20%20%20%20ax2.set_xlabel(%22Goal%20Difference%20(Home%20-%20Away)%22)%0A%20%20%20%20ax2.set_ylabel(%22Probability%22)%0A%20%20%20%20ax2.set_title(f%22Skellam%20Distribution%20(%CE%BB_home%3D%7Blambda_home.value%3A.1f%7D%2C%20%CE%BB_away%3D%7Blambda_away.value%3A.1f%7D)%22)%0A%20%20%20%20ax2.axvline(x%3Dlen(skellam_pmf)%20%2F%2F%202%2C%20color%3D%22red%22%2C%20linestyle%3D%22--%22%2C%20alpha%3D0.5)%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20fig2%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(%22%22%22%0A%20%20%20%20%23%23%20Bivariate%20Poisson%20Heatmap%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(bivariate%2C%20grid%2C%20lambda_away%2C%20lambda_home%2C%20plt%2C%20sns)%3A%0A%20%20%20%20pmf_base%20%3D%20bivariate.pmf(grid)%0A%0A%20%20%20%20fig3%2C%20ax3%20%3D%20plt.subplots(figsize%3D(8%2C%206))%0A%20%20%20%20sns.heatmap(pmf_base%2C%20annot%3DTrue%2C%20fmt%3D%22.3f%22%2C%20cmap%3D%22Blues%22%2C%20ax%3Dax3%2C%20cbar_kws%3D%7B%22label%22%3A%20%22Probability%22%7D)%0A%20%20%20%20ax3.set_xlabel(%22Home%20Goals%22)%0A%20%20%20%20ax3.set_ylabel(%22Away%20Goals%22)%0A%20%20%20%20ax3.set_title(f%22Bivariate%20Poisson%20PMF%20(%CE%BB_home%3D%7Blambda_home.value%3A.1f%7D%2C%20%CE%BB_away%3D%7Blambda_away.value%3A.1f%7D)%22)%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20fig3%0A%20%20%20%20return%20(pmf_base%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo%2C%20rho_input)%3A%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20%23%23%20Dixon-Coles%20Adjustment%0A%0A%20%20%20%20Dependence%20parameter%3A%20**%CF%81**%20%3D%20%7Brho_input.value%3A%2B.2f%7D%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(adjusted%2C%20grid%2C%20plt%2C%20pmf_base%2C%20rho_input%2C%20sns)%3A%0A%20%20%20%20pmf_adj%20%3D%20adjusted.pmf(grid)%0A%0A%20%20%20%20%23%20Show%20difference%0A%20%20%20%20pmf_diff%20%3D%20pmf_adj%20-%20pmf_base%0A%0A%20%20%20%20fig4%2C%20axes%20%3D%20plt.subplots(1%2C%202%2C%20figsize%3D(14%2C%205))%0A%0A%20%20%20%20sns.heatmap(pmf_adj%2C%20annot%3DTrue%2C%20fmt%3D%22.3f%22%2C%20cmap%3D%22Blues%22%2C%20ax%3Daxes%5B0%5D%2C%20cbar_kws%3D%7B%22label%22%3A%20%22Probability%22%7D)%0A%20%20%20%20axes%5B0%5D.set_xlabel(%22Home%20Goals%22)%0A%20%20%20%20axes%5B0%5D.set_ylabel(%22Away%20Goals%22)%0A%20%20%20%20axes%5B0%5D.set_title(%22Dixon-Coles%20PMF%22)%0A%0A%20%20%20%20sns.heatmap(%0A%20%20%20%20%20%20%20%20pmf_diff%2C%20annot%3DTrue%2C%20fmt%3D%22%2B.3f%22%2C%20cmap%3D%22RdBu_r%22%2C%20center%3D0%2C%20ax%3Daxes%5B1%5D%2C%20cbar_kws%3D%7B%22label%22%3A%20%22%CE%94%20Probability%22%7D%0A%20%20%20%20)%0A%20%20%20%20axes%5B1%5D.set_xlabel(%22Home%20Goals%22)%0A%20%20%20%20axes%5B1%5D.set_ylabel(%22Away%20Goals%22)%0A%20%20%20%20axes%5B1%5D.set_title(f%22Dixon-Coles%20Adjustment%20(%CF%81%3D%7Brho_input.value%3A%2B.2f%7D)%22)%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20fig4%0A%20%20%20%20return%20(pmf_adj%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(pd%2C%20plt%2C%20pmf_adj%2C%20pmf_base%2C%20rf%2C%20rho_input)%3A%0A%20%20%20%20%23%20Compare%20goal%20difference%20distributions%0A%20%20%20%20base_gd%20%3D%20rf.sum_diagonals(pmf_base.to_numpy())%0A%20%20%20%20adj_gd%20%3D%20rf.sum_diagonals(pmf_adj.to_numpy())%0A%0A%20%20%20%20fig5%2C%20ax5%20%3D%20plt.subplots(figsize%3D(10%2C%204))%0A%20%20%20%20comparison%20%3D%20pd.concat(%5Bbase_gd%2C%20adj_gd%5D%2C%20axis%3D1%2C%20keys%3D%5B%22Base%22%2C%20%22Dixon-Coles%22%5D)%0A%20%20%20%20comparison.plot.bar(ax%3Dax5%2C%20alpha%3D0.7)%0A%20%20%20%20ax5.set_xlabel(%22Goal%20Difference%22)%0A%20%20%20%20ax5.set_ylabel(%22Probability%22)%0A%20%20%20%20ax5.set_title(f%22Goal%20Difference%3A%20Base%20vs%20Dixon-Coles%20(%CF%81%3D%7Brho_input.value%3A%2B.2f%7D)%22)%0A%20%20%20%20ax5.legend()%0A%0A%20%20%20%20plt.tight_layout()%0A%20%20%20%20fig5%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
9fff547cfdf97d7ce00613a32d6b86cf