【问题标题】:numpy histogram cumulative density does not sum to 1numpy histogram 累积密度之和不等于 1
【发布时间】:2014-02-27 06:03:30
【问题描述】:

从另一个线程(@EnricoGiampieri's answercumulative distribution plots python)那里得到一个提示,我写道:

# plot cumulative density function of nearest nbr distances
# evaluate the histogram
values, base = np.histogram(nearest, bins=20, density=1)
#evaluate the cumulative
cumulative = np.cumsum(values)
# plot the cumulative function
plt.plot(base[:-1], cumulative, label='data')

我在 np.histogram 上的文档中输入了密度=1,其中说:

"请注意,除非选择了统一宽度的 bin,否则直方图值的总和不会等于 1;它不是概率质量函数。"

嗯,确实,当绘制它们时,它们的总和不等于 1。但是,我不理解“单位宽度的箱”。当然,当我将 bin 设置为 1 时,我得到一个空图表;当我将它们设置为人口规模时,总和不会为 1(更像是 0.2)。当我使用建议的 40 个垃圾箱时,它们的总和约为 0.006。

谁能给我一些指导?谢谢!

【问题讨论】:

  • 面积之和是一吗?
  • 我猜是的。保罗,我很抱歉——我的统计数据很弱。我正在从一个 R 示例开始工作,其中 y 轴值从 0 到 1,CDF 上限为 1。
  • (如果我知道怎么做,我会发布一个屏幕截图。)曲线上限为 0.2,但超过 2000-8000 的 x 值,所以我相信该区域会是 1。
  • 对我来说,当我有来自np.arange(0, 1005, 10) 的垃圾箱时,我只需要全部乘以 10。我还没有检查过,但似乎你只需要将密度乘以差异因子,即 10在我的场合

标签: python numpy


【解决方案1】:

您可以像这样简单地自己标准化您的 values 变量:

unity_values = values / values.sum()

完整的示例如下所示:

import numpy as np
import matplotlib.pyplot as plt

x = np.random.normal(size=37)
density, bins = np.histogram(x, normed=True, density=True)
unity_density = density / density.sum()

fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, sharex=True, figsize=(8,4))
widths = bins[:-1] - bins[1:]
ax1.bar(bins[1:], density, width=widths)
ax2.bar(bins[1:], density.cumsum(), width=widths)

ax3.bar(bins[1:], unity_density, width=widths)
ax4.bar(bins[1:], unity_density.cumsum(), width=widths)

ax1.set_ylabel('Not normalized')
ax3.set_ylabel('Normalized')
ax3.set_xlabel('PDFs')
ax4.set_xlabel('CDFs')
fig.tight_layout()

【讨论】:

  • 谢谢你,保罗。实际上,几天前我确实尝试过划分(标准化)我的“最近”向量。不记得为什么我对结果不满意。可能做错了。
  • density, bins = np.histogram(x, normed=True, density=True)这一行,为什么normeddensity都设置为True? numpy 文档说 normed 已弃用;我问是因为我试图通过numpy histogram 获得归一化的累积直方图。
  • @mikey 这个答案是在 2014 年写的,在 numpy 弃用 normed 之前。标准化是什么意思?有些人的意思是,在标准化直方图中,最高条的值应该是 1。其他人希望条形的面积总和为 1。我很确定 density 为您提供后者,而您必须自己计算前者。
  • @mikey(numpy 文档比我能更好地解释密度 kwarg,顺便说一句)
  • @PaulH 归一化,我的意思是曲线下的面积总和为 1。我问了一个 new question about it in this post
【解决方案2】:

您需要确保您的垃圾箱的宽度都是 1。即:

np.all(np.diff(base)==1)

为此,您必须手动指定您的垃圾箱:

bins = np.arange(np.floor(nearest.min()),np.ceil(nearest.max()))
values, base = np.histogram(nearest, bins=bins, density=1)

你会得到:

In [18]: np.all(np.diff(base)==1)
Out[18]: True

In [19]: np.sum(values)
Out[19]: 0.99999999999999989

【讨论】:

  • 万岁!谢谢——现在曲线更像我的目标。
  • 来自文档:If `bins` is an int, it defines the number of equal-width bins in the given range (10, by default) - 所以 OP 的示例应该默认工作,不是吗?看起来像一个错误。
  • 宽度相等,但不一定宽度为 1。
  • 啊,我明白了,它与 bin 宽度相加,因此对于等宽的 bin,您可以通过除以 base[1]-base[0] 来获得统一。
【解决方案3】:

其实声明

"请注意,除非选择了统一宽度的 bin,否则直方图值的总和不会等于 1;它不是概率质量函数。"

表示我们得到的输出是各个 bin 的概率密度函数, 现在因为在pdf中,两个值之间的概率说'a'和'b'由'a'和'b'范围之间的pdf曲线下的面积表示。 因此,要获得各个 bin 的概率值,我们必须 将该 bin 的 pdf 值乘以其 bin 宽度,然后获得的概率序列可以直接用于计算累积概率(因为它们现在已标准化)。

请注意,新计算的概率之和将为 1,这满足了总概率之和为 1 的事实,或者换句话说,我们可以说我们的概率是归一化的。

见下面的代码, 这里我使用了不同宽度的垃圾箱,有些宽度为 1,有些宽度为 2,

import numpy as np
import math
rng = np.random.RandomState(10)   # deterministic random data
a = np.hstack((rng.normal(size=1000),
               rng.normal(loc=5, scale=2, size=1000))) # 'a' is our distribution of data
mini=math.floor(min(a))
maxi=math.ceil(max(a))
print(mini)
print(maxi)
ar1=np.arange(mini,maxi/2)
ar2=np.arange(math.ceil(maxi/2),maxi+2,2)
ar=np.hstack((ar1,ar2))
print(ar)  # ar is the array of unequal widths, which is used below to generate the bin_edges
counts, bin_edges = np.histogram(a, bins=ar, 
                             density = True)
print(counts)    # the pdf values of respective bin_edges
print(bin_edges) # the corresponding bin_edges
print(np.sum(counts*np.diff(bin_edges)))  #finding total sum of probabilites, equal to 1
print(np.cumsum(counts*np.diff(bin_edges))) #to get the cummulative sum, see the last value, it is 1.

现在我认为他们试图通过说 bin 的宽度应该为 1 来提及的原因可能是因为 如果 bin 的宽度等于 1,那么 pdf 的值和任何 bin 的概率都是相等的,因为如果我们计算 bin 下的面积,那么我们基本上是将 1 乘以该 bin 的相应 pdf,它再次等于该 pdf 值。 所以在这种情况下,pdf 的值等于各个 bin 概率的值,因此已经归一化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-31
    • 1970-01-01
    • 2021-06-09
    • 2017-07-20
    • 1970-01-01
    相关资源
    最近更新 更多