将泊松分布拟合到 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 的平均值外,他的直方图显示了与上述相同的行为。
我有数据分布,我想对其进行泊松分布。我的数据是这样的:
我试着合身:
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 的平均值外,他的直方图显示了与上述相同的行为。