如何在Python中基于足球角球数据集计算负二项分布
基于角球数据集拟合负二项分布的解决方案
首先验证你的数据集确实存在过度离散:
数据集[7,8,7,12,14,9,6,15,5]的均值约为9.22,样本方差约为12.94,方差大于均值,符合负二项分布的适用场景。以下是三种可行的拟合方法:
1. 矩估计手动计算参数
负二项分布有两种常用参数化方式,可通过均值和方差直接推导:
- 参数化方式A(对应scipy的nbinom):
设均值为μ,方差为σ²,则参数p=μ/σ²,n=μ²/(σ²-μ)
代入你的数据:p≈9.22/12.94≈0.712,n≈9.22²/(12.94-9.22)≈22.85 - 参数化方式B(均值+离散度):
离散参数α=(σ²-μ)/μ²,代入得α≈(12.94-9.22)/9.22²≈0.0438
得到参数后,即可用负二项分布的概率质量函数计算任意角球数的概率。
2. scipy.stats稳定拟合参数
你遇到的拟合参数不稳定问题,是因为小样本下最大似然估计的初始值敏感,固定位置参数并指定矩估计结果为初始值即可解决:
import numpy as np from scipy import stats corners = np.array([7,8,7,12,14,9,6,15,5]) mu = np.mean(corners) var = np.var(corners, ddof=1) # 样本方差 # 矩估计得到初始参数 init_n = mu**2 / (var - mu) init_p = mu / var # 固定loc=0(角球数非负),传入初始值拟合 n_fit, p_fit, _ = stats.nbinom.fit(corners, loc=0, p0=[init_n, init_p]) # 示例:计算角球数为7的概率 prob_7 = stats.nbinom.pmf(7, n_fit, p_fit) print(f"角球数为7的概率:{prob_7:.4f}")
3. statsmodels正确拟合(解决报错)
你遇到的ValueError是因为GLM需要传入设计矩阵(即使无其他变量,也要构造常数项矩阵),以下两种方式均可:
方式3.1 使用专门的NegativeBinomial模型
import numpy as np import statsmodels.api as sm corners = np.array([7,8,7,12,14,9,6,15,5]) # 构造常数项设计矩阵 X = sm.add_constant(np.ones_like(corners)) model = sm.NegativeBinomial(corners, X) result = model.fit() print(result.summary()) # 提取参数并转换为scipy兼容格式 mu_est = np.exp(result.params[0]) alpha_est = result.params[1] n_scipy = 1 / alpha_est p_scipy = n_scipy / (n_scipy + mu_est)
方式3.2 使用GLM配合负二项Family
import numpy as np import statsmodels.api as sm from statsmodels.genmod.families import NegativeBinomial from statsmodels.genmod.families.links import log corners = np.array([7,8,7,12,14,9,6,15,5]) X = sm.add_constant(np.ones_like(corners)) model = sm.GLM(corners, X, family=NegativeBinomial(link=log())) result = model.fit() print(result.summary()) # 提取参数 mu_est = np.exp(result.params[0]) alpha_est = result.scale
内容的提问来源于stack exchange,提问作者Niccolò Simoni
相关产品推荐
相关产品推荐

