在Python中为不同的数据集拟合泊松分布

泊松概率分布显示了一个事件在一个固定时期或空间内发生的概率。这个数据可以用Python绘制成柱状图,观察事件的发生率。

分布是可以在直方图或其他结构上绘制的曲线,以找到数据集的最佳拟合曲线。本文将教你如何用Python在数据集上拟合泊松分布。

在Python中对不同的数据集拟合泊松分布

让我们了解如何在一组数据上绘制多个分布,并使用SciPy和Python拟合泊松分布。

用Python拟合泊松分布的分位最小二乘法

在这个例子中,创建了一个假的泊松数据集,用这个数据绘制了一个直方图。绘制直方图后,分档最小二乘法在直方图上拟合一条曲线,以拟合泊松分布。

程序的导入函数

本程序使用以下导入函数。

  1. Matplotlib的数学臂 –Numpy
  2. Matplotlib子库Pyplot ,用于绘制图表。
  3. SciPycurve_fit 用于导入曲线拟合。
  4. poisson 为数据集。

为泊松分布创建一个虚拟数据集,并用该数据集绘制直方图

通过使用函数np.random.poisson() ,用4-20,000范围内的泊松偏差数创建一个变量dataset_size 。它返回一个带有随机泊松值的数组。

data_set = np.random.poisson(4, 2000)

直方图数据中的差异被存储在一个新的变量中,bins 。它使用np.arrange() 函数来返回一个数组,其数值范围在-0.520 之间,0.5 为平均差异。

bins = np.arange(20) - 0.5

使用plt.hist() 函数绘制直方图,其中的参数为:

  1. data_set 为所使用的数据。
  2. bins 为差异。
  3. density,这被设置为真。
  4. label,在图上添加一个标签。

在绘制直方图的同时,从plt.hist() 函数中返回三个值,这些值被存储在三个新的变量中–entries ,用于直方图槽的值,bin_edges ,用于槽的边缘,patches ,用于直方图的单个斑块。

entries, bin_edges, patches = plt.hist(data_set, bins=bins, density=True, label='Data')

使用曲线拟合将曲线拟合到直方图上

一旦绘制了直方图,曲线拟合函数就被用来拟合泊松分布的数据。曲线函数从一个分散的数据集中绘制出最佳拟合线。

曲线拟合需要一个拟合函数,将一个数值数组转换为泊松分布,并将其作为参数返回,在此基础上绘制出曲线。创建了一个方法fit_function ,有两个参数:kparameters

SciPy库poisson.pmf 被用来获取参数。pmf 代表概率质量函数,这个函数返回随机分布的频率。

变量k 存储了事件发生的次数,变量lambpopt (缩小的平方之和),它被用来作为曲线函数的拟合参数。

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()

输出:

在Python中为不同的数据集拟合泊松分布

使用负二项式来拟合过度分散的数据集上的泊松分布

在这个例子中,我们用高度分散的数据创建了一个泊松分布数据框,我们将学习如何将泊松分布拟合到这个数据上。

与上一个例子不同的是,泊松分布是以其平均值为中心的,而这个数据是高度分散的,所以在下一节将对这个数据添加一个负二项式来改进泊松分布。

创建数据集

在这个例子中,我们创建了一个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)

拟合泊松分布曲线到直方图上

通过绘制分布曲线,需要数据集的平均值和大小来拟合泊松分布。在两个新的变量中,mun ,分别存储数据集的平均值和大小。

绘制泊松分布曲线的算法是:

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()

输出:

在Python中为不同的数据集拟合泊松分布

使用负二项式的高度分散数据的泊松分布

如前所述,这个数据集里面的数据过于分散,这就是为什么曲线并不完全像泊松分布曲线。下面的例子中使用了负二项来拟合泊松分布。

该数据集是通过注入一个负二项式创建的:

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(数据集中的总项目)

方差和平均数在两个变量中计算,variancemu

Var = dataset["Occurrence"].var()
mu = dataset["Occurrence"].mean()

下面的公式用来找出pr

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中为不同的数据集拟合泊松分布

结论

本文解释了在Python中对数据集拟合泊松分布的三种方法。读完这篇文章后,读者可以在假泊松数据集和过度分散的数据集上拟合泊松分布。