将泊松分布拟合到 python 中的数据

fitting Poisson distribution to data in python

我有数据分布,我想对其进行泊松分布。我的数据是这样的:

我试着合身:

 mu = herd_size["COW_NUM"].mean() 
ax=sns.displot(data=herd_size["COW_NUM"], kde=True)
ax.set(xlabel='Size',title='Herd size distribution & poisson distribution')
plt.plot(np.arange(0, 2000, 80), [st.poisson.pmf(np.arange(i, i+80), mu).sum()*len(herd_size["COW_NUM"])
                                  for i in np.arange(0, 2000, 80)], color='red')
#every bin contain approximatly 80 observes
plt.show()

但我得到的东西不在同一个范围内:

更新 我尝试使用代码应用负二项分布:

n=len(herd_size["COW_NUM"])
p =herd_size["COW_NUM"].mean()/(herd_size["COW_NUM"].mean()+2) 
ax=sns.displot(data=herd_size["COW_NUM"], kde=True)
ax.set(xlabel='Size',title='Herd size distribution & geometry distribution')
plt.plot(np.arange(0, 2000, 80), [st.nbinom.pmf(np.arange(i, i+80), n,p).sum()*len(herd_size["COW_NUM"])
                                  for i in np.arange(0, 2000, 80)], color='red')
#every bin contain approximatly 80 observes
plt.show()

但我得到了这个: nbinom

对于您需要绘制的内容,提供 bin 来制作直方图可能更容易:

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import poisson

herd_size = pd.DataFrame({'COW_NUM':np.random.poisson(200,2000)})
binwidth = 10
xstart = 150
xend = 280
bins = np.arange(xstart,xend,binwidth)

o = sns.histplot(data=herd_size["COW_NUM"], kde=True,bins = bins)

然后计算你的平均值和总数:

mu = herd_size["COW_NUM"].mean() 
n = len(herd_size)

预期频率是cdf在你的左右间隔开始和结束的差异:

plt.plot(bins + binwidth/2 , n*(poisson.cdf(bins+binwidth,mu) - poisson.cdf(bins,mu)), color='red')

您的数据过于分散,因为对于泊松分布,您不希望数据如此分散。所以你需要做的是使用伽玛或负二项式来拟合它,例如:

from scipy.stats import nbinom
herd_size = pd.DataFrame({'COW_NUM':nbinom.rvs(n=2,p=0.1,loc=240,size=2000)})
binwidth = 50
xstart = 0
xend = 2000
bins = np.arange(xstart,xend,binwidth)

herd_size = pd.DataFrame({'COW_NUM':nbinom.rvs(n=1,p=0.004,size=2000)})

Var = herd_size["COW_NUM"].var()
mu = herd_size["COW_NUM"].mean()
p =  (mu/Var)
r = mu**2 / (Var-mu)
n = len(herd_size)

o = sns.histplot(data=herd_size["COW_NUM"], kde=True,bins=bins)

plt.plot(bins + binwidth/2 , 
         n*(nbinom.cdf(bins+binwidth,r,p) - nbinom.cdf(bins,r,p)), 
         color='red')

您的绘图(至少大致)正确,问题在于将您的数据建模为泊松分布。随着 lambda 变大,泊松看起来越来越像正态分布——请参阅维基百科的 this plot。泊松分布的方差等于其均值,因此均值约为 240 左右,标准差为 15.5 左右。最终结果是 Poisson(240) 的结果应该绝大多数落在 210 和 270 之间,这就是您的红色图所示。尝试为您的数据拟合不同的分布。


我刚看到 StupidWolf 的回答。除了使用 200 而不是 240 的平均值外,他的直方图显示了与上述相同的行为。