如何有效地计算给定数据集的 pdf

How to effectively compute the pdf of a given dataset

我尝试使用 numpy.histogram

计算鸢尾花数据集的概率分布函数

我想绘制 setosa 花瓣长度的概率分布函数。不幸的是,我对 np.histogram returns 我们的实际情况感到困惑。 在下面的代码中,我使用我模糊的知识将 bins 设置为 10,将密度设置为 true。

任何人都可以就以下代码的作用以及 PDF 本质上是什么提供任何见解吗? 还有其他更好的方法来计算给定数据集的 PDF 吗?

import pandas as pd
import numpy as np

iris = pd.read_csv('iris.csv')
iris_setosa = iris[iris.species == 'setosa']

counts,bin_edges=np.histogram(iris_setosa["petal_length"],bins=10,density=True)

pdf=counts/sum(counts)

您可以使用 np.histogram 函数根据示例数据创建直方图,并使用 scipy.stats.rv_histogram 函数来处理它。有关说明,请参阅 rv_histogram here 的文档。

rv_histogram 存储分布的参数,除其他外,可用于计算 pdfcdf:

from scipy.stats import rv_histogram
import numpy as np

x = np.random.random(10000)
r = rv_histogram(np.histogram(x, bins=100))

r.pdf(np.linspace(0,1,5))  # 0, 0.25, 0.5, 0.75, 1
>> array([0.        , 0.96009784, 1.05010702, 0.97009886, 0.        ])

r.cdf(np.linspace(0,1,5))
>> array([0.        , 0.2554366 , 0.50824724, 0.75229438, 1.        ])

既然你设置了density=True,那么这里计算的是概率密度函数是最正确的。术语概率分布函数有点模棱两可,因为有多种方法可以量化数据的概率分布。

我将提供一个 link 概率密度函数的维基百科页面,但本质上它在给定范围内的积分给出了该范围的概率。

概率密度函数:https://en.wikipedia.org/wiki/Probability_density_function

所以如果我理解正确的话,在这一行中:

pdf=counts/sum(counts)

您试图规范化计数值。据我了解,density=True 已经为您完成了,因此无需执行上述代码行。

我不知道在这种情况下是否有更好的方法来计算 PDF,但据我所知,增加 bin 的数量会给你更好的 PDF 近似值。

numpy.histogram: https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html

让我这样说-

当您 运行 下面的行并打印出计数时,bin_edges 变量

counts, bin_edges = np.histogram(iris_setosa['petal_length'], bins=10,density=True)

结果会是

计数 --> [0.22222222 0.22222222 0.44444444 1.55555556 2.66666667 3.11111111 1.55555556 0.88888889 0. 0.44444444]

bin_edges --> [1. 1.09 1.18 1.27 1.36 1.45 1.54 1.63 1.72 1.81 1.9 ]

数据源 - Iris Data set 麻木的-Numpy

那么上面的代码在后端做的事情如下:

1.Firstly,根据setosa花瓣长度数据集中的bin宽度和最小值和最大值,首先计算出一定的bin宽度,然后创建一个直方图,其中X轴为花瓣长度, Y 轴是花的数量。这个你直接把上面代码的参数density去掉就可以看到了

counts_number, bin_edges = np.histogram(iris_setosa['petal_length'], bins=10)

这将导致—— counts_number --> [ 1 1 2 7 12 14 7 4 0 2] 所以这意味着容器中只有 1 朵花 [1-1.09]。

2.Next 它将计算每个数据点的相对频率,即它将 counts_number 除以总花数(这里是 50。我从 google).你可以通过这个看到这个:

rel_freq =counts_number/50
print(rel_freq)

这将导致 --> [0.02 0.02 0.04 0.14 0.24 0.28 0.14 0.08 0. 0.04]

这些是相对频率,也可以解释为概率值。这个解释是基于大数定律的概念([Law of large numbers])3

3.The 任何 PDF 中的 Y 值都不是实际概率,而是概率密度。因此,如果将 rel_freq 除以 bin 宽度,我们将得到

--> [0.22222222 0.22222222 0.44444444 1.55555556 2.66666667 3.11111111 1.55555556 0.88888889 0. 0.44444444]

如你所见,这与我们使用 density =True 参数得到的相同

因为您没有提供完整的代码作为您在计算变量 pdf 后尝试做的事情。让我做出假设并进一步解释。

任何 PDF will/can 中的 Y 轴值都大于 1,因为它们是密度而不是概率。你程序中的代码行

pdf=counts/sum(counts)

规范化 pdf numpy 数组。换一种更明智的方式,上面的代码行与将 counts 数组乘以 bin 宽度做同样的事情,即它从密度重新计算相对频率(a.k.a 概率)。所以,如果你 运行 下面的代码行

print(counts*0.09) -- > here 0.09 is the bin width for bin size of 10

它将给出 --- > [0.02 0.02 0.04 0.14 0.24 0.28 0.14 0.08 0. 0.04]

这与变量pdf完全相同

现在,您可以使用此 pdf 数组来计算 cdf,因为 CDF 是每个 bin 宽度处概率的累积和。在计算 CDF 时直接使用计数是没有意义的。

现在,如果我们借助以下代码行绘制 pdf。注意 - 确保你导入相关的库来绘制。下面只是一个示例代码

plt.plot(bin_edges[1:],pdf,label="normalised_pdf")
plt.plot(bin_edges[1:],counts,label="actual_pdf")

这将导致

Resulting graph

你可以在图中看到,它们只是彼此的缩放版本。