首页 > 解决方案 > 密度函数之和(基于直方图)不等于1

问题描述

我正在尝试生成密度函数,但生成的直方图的分量之和似乎并不接近 1。

这是什么原因以及如何使密度函数的总和接近(即使不完全等于)1?

最小的例子:

import numpy as np
x = np.random.normal(0, 0.5, 1000) # mu, sigma, num
bins = np.linspace(min(x), max(x), num=50) # lower and upper bounds
hist, hist_bins = np.histogram(x, bins=bins, density = True)

print(np.sum(hist))
>>> 10.4614

如果我没有指定 bin 边缘,则输出会更小但仍大于 1:

import numpy as np
x = np.random.normal(0, 0.5, 1000) # mu, sigma, num
hist, hist_bins = np.histogram(x, density = True)

print(np.sum(hist))
>>> 3.1332

标签: pythonnumpyhistogram

解决方案


文档中说明了这种行为的原因:

密度:布尔,可选

如果为 False,则结果将包含每个 bin 中的样本数。如果为 True,则结果是 bin 处的概率密度函数值,经过归一化处理,使得范围内的积分为 1。请注意,除非选择了统一宽度的 bin,否则直方图值的总和将不等于 1;它不是概率质量函数。

此外,还提供了一个样本,表明直方图的总和不等于 1.0:

import numpy as np

a = np.arange(5)
hist, bin_edges = np.histogram(a, density=True)

print(hist)
# hist --> [0.5, 0. , 0.5, 0. , 0. , 0.5, 0. , 0.5, 0. , 0.5]

print(hist.sum())
# --> 2.4999999999999996

print(np.sum(hist * np.diff(bin_edges)))
# --> 1.0

因此,我们可以将其应用于您的代码片段:

x = np.random.normal(0, 0.5, 1000) # mu, sigma, num
bins = np.linspace(min(x), max(x), num=50) # lower and upper bounds
hist, hist_bins = np.histogram(x, bins=bins, density=True)

print(hist)

print(np.sum(hist))

print(np.sum(hist * np.diff(hist_bins)))
# --> 1.0

此外,您应该考虑如何选择垃圾箱并确保使用 a.linspace()是一种合理的方式。


推荐阅读