在Python中为不同的数据集拟合泊松分布
泊松概率分布显示了一个事件在一个固定时期或空间内发生的概率。这个数据可以用Python绘制成柱状图,观察事件的发生率。
分布是可以在直方图或其他结构上绘制的曲线,以找到数据集的最佳拟合曲线。本文将教你如何用Python在数据集上拟合泊松分布。
在Python中对不同的数据集拟合泊松分布
让我们了解如何在一组数据上绘制多个分布,并使用SciPy和Python拟合泊松分布。
用Python拟合泊松分布的分位最小二乘法
在这个例子中,创建了一个假的泊松数据集,用这个数据绘制了一个直方图。绘制直方图后,分档最小二乘法在直方图上拟合一条曲线,以拟合泊松分布。
程序的导入函数
本程序使用以下导入函数。
- Matplotlib的数学臂 –
Numpy
。 - Matplotlib子库
Pyplot
,用于绘制图表。 - SciPy
curve_fit
用于导入曲线拟合。 -
poisson
为数据集。
为泊松分布创建一个虚拟数据集,并用该数据集绘制直方图
通过使用函数np.random.poisson()
,用4-20,000范围内的泊松偏差数创建一个变量dataset_size
。它返回一个带有随机泊松值的数组。
data_set = np.random.poisson(4, 2000)
直方图数据中的差异被存储在一个新的变量中,bins
。它使用np.arrange()
函数来返回一个数组,其数值范围在-0.5
到20
之间,0.5
为平均差异。
bins = np.arange(20) - 0.5
使用plt.hist()
函数绘制直方图,其中的参数为:
-
data_set
为所使用的数据。 -
bins
为差异。 -
density
,这被设置为真。 -
label
,在图上添加一个标签。
在绘制直方图的同时,从plt.hist()
函数中返回三个值,这些值被存储在三个新的变量中–entries
,用于直方图槽的值,bin_edges
,用于槽的边缘,patches
,用于直方图的单个斑块。
entries, bin_edges, patches = plt.hist(data_set, bins=bins, density=True, label='Data')
使用曲线拟合将曲线拟合到直方图上
一旦绘制了直方图,曲线拟合函数就被用来拟合泊松分布的数据。曲线函数从一个分散的数据集中绘制出最佳拟合线。
曲线拟合需要一个拟合函数,将一个数值数组转换为泊松分布,并将其作为参数返回,在此基础上绘制出曲线。创建了一个方法fit_function
,有两个参数:k
和parameters
。
SciPy库poisson.pmf
被用来获取参数。pmf
代表概率质量函数,这个函数返回随机分布的频率。
变量k
存储了事件发生的次数,变量lamb
是popt
(缩小的平方之和),它被用来作为曲线函数的拟合参数。
SciPycurve_fit
函数接收了三个参数,fit_function
,middle_bins
, 和entries
,并返回两个值–parameters
(减少平方残差之和的最佳值)和cov_matrix
(parameters
估计的共同方差)。
parameters, cov_matrix = curve_fit(fit_function, middles_bins, entries)
创建一个由15个上升值组成的数据集来绘制曲线,并使用fit_function
方法拟合这些上升值的泊松分布。提供了该图的属性,并显示了结果。
x_plot = np.arange(0, 15)
plt.plot(
x_plot,
fit_function(x_plot, *parameters),
marker='D', linestyle='-',
color='red',
label='Fit result',
)
完整的代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.stats import poisson
# get random numbers that are poisson deviated
data_set = np.random.poisson(4, 2000)
# the bins have to be kept as a positive integer because poisson is a positive integer distribution
bins = np.arange(20) - 0.5
entries, bin_edges, patches = plt.hist(data_set, bins=bins, density=True, label='Data')
# calculate bin centers
middles_bins = (bin_edges[1:] + bin_edges[:-1]) * 0.5
def fit_function(k, lamb):
# The parameter lamb will be used as the fit parameter
return poisson.pmf(k, lamb)
# fit with curve_fit
parameters, cov_matrix = curve_fit(fit_function, middles_bins, entries)
# plot poisson-deviation with fitted parameter
x_plot = np.arange(0, 15)
plt.plot(
x_plot,
fit_function(x_plot, *parameters),
marker='D', linestyle='-',
color='red',
label='Fit result',
)
plt.legend()
plt.show()
输出:
使用负二项式来拟合过度分散的数据集上的泊松分布
在这个例子中,我们用高度分散的数据创建了一个泊松分布数据框,我们将学习如何将泊松分布拟合到这个数据上。
与上一个例子不同的是,泊松分布是以其平均值为中心的,而这个数据是高度分散的,所以在下一节将对这个数据添加一个负二项式来改进泊松分布。
创建数据集
在这个例子中,我们创建了一个Pandas数据框,并存储在变量dataset
。这个数据集有一列,Occurrence
,其中有2000
泊松值,lambda的值设置为200
。
dataset = pd.DataFrame({'Occurrence': np.random.poisson(200, 2000)})
用数据集绘制直方图
为了绘制直方图,我们需要提供三个值,即bin的间隔(bucket of values)、bin的开始和bin的结束。这可以通过以下方式完成:
width_of_bin = 15
xstart = 150
xend = 280
bins = np.arange(xstart, xend, width_of_bin)
一旦设置了分仓的值,就绘制直方图。
hist = sns.histplot(data=dataset["Occurrence"], kde=True, bins=bins)
拟合泊松分布曲线到直方图上
通过绘制分布曲线,需要数据集的平均值和大小来拟合泊松分布。在两个新的变量中,mu
和n
,分别存储数据集的平均值和大小。
绘制泊松分布曲线的算法是:
bins + width_of_bin / 2, n * (poisson.cdf(bins + width_of_bin, mu) - poisson.cdf(bins, mu))
最后,将曲线绘制在柱状图上。
完整的代码:
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import poisson
dataset = pd.DataFrame({'Occurrence': np.random.poisson(200, 2000)})
width_of_bin = 15
xstart = 150
xend = 280
bins = np.arange(xstart, xend, width_of_bin)
hist = sns.histplot(data=dataset["Occurrence"], kde=True, bins=bins)
mu = dataset["Occurrence"].mean()
n = len(dataset)
plt.plot(bins + width_of_bin / 2, n * (poisson.cdf(bins + width_of_bin, mu) - poisson.cdf(bins, mu)), color='red')
plt.show()
输出:
使用负二项式的高度分散数据的泊松分布
如前所述,这个数据集里面的数据过于分散,这就是为什么曲线并不完全像泊松分布曲线。下面的例子中使用了负二项来拟合泊松分布。
该数据集是通过注入一个负二项式创建的:
dataset = pd.DataFrame({'Occurrence': nbinom.rvs(n=1, p=0.004, size=2000)})
直方图的二进制开始于0
,结束于2000
,共同区间为100
。
binwidth = 100
xstart = 0
xend = 2000
bins = np.arange(xstart, xend, binwidth)
在创建了二进制和数据集之后,直方图被绘制出来:
hist = sns.histplot(data=dataset["Occurrence"], kde=True, bins=bins)
该曲线需要五个参数,方差(Var
)、平均值(mu
)、p
(平均值/方差)、r
(考虑的项目)和n
(数据集中的总项目)
方差和平均数在两个变量中计算,variance
和mu
。
Var = dataset["Occurrence"].var()
mu = dataset["Occurrence"].mean()
下面的公式用来找出p
和r
:
p = (mu / Var)
r = mu ** 2 / (Var - mu)
通过将数据集的长度保存在一个新的变量n
,来存储项目的总数。
n = len(dataset)
最后,将曲线绘制在直方图上。
plt.plot(bins + binwidth / 2, n * (nbinom.cdf(bins + binwidth, r, p) - nbinom.cdf(bins, r, p)))
完整的代码:
import numpy as np
from scipy.stats import nbinom
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
dataset = pd.DataFrame({'Occurrence': nbinom.rvs(n=1, p=0.004, size=2000)})
binwidth = 100
xstart = 0
xend = 2000
bins = np.arange(xstart, xend, binwidth)
hist = sns.histplot(data=dataset["Occurrence"], kde=True, bins=bins)
Var = dataset["Occurrence"].var()
mu = dataset["Occurrence"].mean()
p = (mu / Var)
r = mu ** 2 / (Var - mu)
n = len(dataset)
plt.plot(bins + binwidth / 2,
n * (nbinom.cdf(bins + binwidth, r, p) - nbinom.cdf(bins, r, p)),
color='red')
plt.show()
输出:
结论
本文解释了在Python中对数据集拟合泊松分布的三种方法。读完这篇文章后,读者可以在假泊松数据集和过度分散的数据集上拟合泊松分布。