pylab.hist(数据,规范=1)。规范化似乎工作不正确

Posted

技术标签:

【中文标题】pylab.hist(数据,规范=1)。规范化似乎工作不正确【英文标题】:pylab.hist(data, normed=1). Normalization seems to work incorrect 【发布时间】:2011-07-26 18:17:29 【问题描述】:

我正在尝试使用参数 normed=1 创建直方图

例如:

import pylab

data = ([1,1,2,3,3,3,3,3,4,5.1])    
pylab.hist(data, normed=1)
pylab.show()

我预计 bin 的总和为 1。但是,其中一个 bin 比 1 大。这个标准化做了什么?以及如何创建一个直方图的归一化使得直方图的积分等于 1?

【问题讨论】:

也可以试试pylab.hist(data, bins=5, range=(1, 6), normed=1)。这将导致 bin 宽度为 1。 "bin 的总和为 1。但是,其中一个 bin 大于 1" -> 这并不矛盾! 【参考方案1】:

请参阅我的另一篇文章,了解如何使直方图中所有 bin 的总和等于 1: https://***.com/a/16399202/1542814

复制和粘贴:

weights = np.ones_like(myarray)/float(len(myarray))
plt.hist(myarray, weights=weights)

myarray 包含您的数据的位置

【讨论】:

如果你在做频率直方图,这是最好的方法! 仅供参考,如果您使用上述方法,请务必保留normed=0 与this example 中的格式化程序完美结合使用(使用normed 代替权重;权重的工作原理与bin 大小无关,而normed/density 需要大小统一的bin,来自documentation)。 太棒了!最好的方式【参考方案2】:

根据documentation normed:如果为 True,则结果是 bin 处的概率密度函数的值,归一化使得范围内的积分为 1。请注意,直方图值的总和将不等于 1,除非选择了统一宽度的 bin;它不是概率质量函数。这是来自 numpy doc,但对于 pylab 应该是相同的。

In []: data= array([1,1,2,3,3,3,3,3,4,5.1])
In []: counts, bins= histogram(data, normed= True)
In []: counts
Out[]: array([ 0.488,  0.,  0.244,  0.,  1.22,  0.,  0.,  0.244,  0.,  0.244])
In []: sum(counts* diff(bins))
Out[]: 0.99999999999999989

所以简单的标准化是根据以下文档完成的:

In []: counts, bins= histogram(data, normed= False)
In []: counts
Out[]: array([2, 0, 1, 0, 5, 0, 0, 1, 0, 1])
In []: counts_n= counts/ sum(counts* diff(bins))
In []: counts_n
Out[]: array([ 0.488,  0.,  0.244,  0.,  1.22 ,  0.,  0.,  0.244,  0.,  0.244])

【讨论】:

@smirnoffs:你认为它不能大于 1 的理由是什么?谢谢 @eat 归一化直方图,据我所知,是一个概率密度函数。概率不能超过 1。 @smirnoffs:你能提供一些链接来备份你对标准化直方图的定义吗? FWIW 从文档中可以看出标准化是如何工作的。 counts* diff(bins) 为您提供所需的内容。谢谢 概率 densities 可以是任何非负数,只要该范围内的 integral(不是总和)等于 1。跨度> 这个答案是指numpy.histogram,而不是pylab.hist【参考方案3】:

我认为您将垃圾箱高度与垃圾箱内容混淆了。您需要添加每个 bin 的内容,即所有 bin 的 height*width。那应该 = 1。

【讨论】:

所以为了澄清大家,你会在 OP 的直方图上放置什么作为 y 轴标签?【参考方案4】:

这个标准化做了什么?

为了规范化序列,您必须考虑 bin 大小。 根据documentation,bin 的默认数量为 10。因此,bin 大小为(data.max() - data.min() )/10,即 0.41。 如果是normed=1,那么条形的高度就是这样的总和,乘以 0.41,得到 1。这就是积分时发生的情况。

以及如何创建一个直方图的归一化使得直方图的积分等于 1?

我认为您希望直方图的总和(而不是其积分)等于 1。在这种情况下,最快的方法似乎是:

h = plt.hist(data)
norm = sum(data)
h2 = [i/norm for i in h[0]]
plt.bar(h[1],h2)

【讨论】:

【参考方案5】:

我遇到了同样的问题,在解决它的同时又出现了另一个问题:如何将归一化的 bin 频率绘制为百分比,并在 rounded 值上加上刻度。我在这里发布它以防它对任何人有用。在我的示例中,我选择 10% (0.1) 作为 y 轴的最大值,并选择 10 个步骤(一个从 0% 到 1%,一个从 1% 到 2%,依此类推)。诀窍是在 data 计数处设置刻度(这是plt.hist 的输出列表n),接下来将使用FuncFormatter 类将其转换为百分比。这是我所做的:

import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter

fig, ax = plt.subplots()

# The required parameters
num_steps = 10
max_percentage = 0.1
num_bins = 40

# Calculating the maximum value on the y axis and the yticks
max_val = max_percentage * len(data)
step_size = max_val / num_steps
yticks = [ x * step_size for x in range(0, num_steps+1) ]
ax.set_yticks( yticks )
plt.ylim(0, max_val)

# Running the histogram method
n, bins, patches = plt.hist(data, num_bins)

# To plot correct percentages in the y axis     
to_percentage = lambda y, pos: str(round( ( y / float(len(data)) ) * 100.0, 2)) + '%'
plt.gca().yaxis.set_major_formatter(FuncFormatter(to_percentage))

plt.show()

地块

标准化之前:y 轴单位是 x 轴上 bin 间隔内的样本数:

标准化后:y 轴单位是 bin 值的频率,作为所有样本的百分比

【讨论】:

【参考方案6】:

还有numpy.histogram。如果设置density=True,输出会被归一化。

normed : bool, optional

由于令人困惑/错误的行为,该关键字在 Numpy 1.6 中已弃用。它将在 Numpy 2.0 中删除。请改用密度关键字。如果为 False,则结果将包含每个 bin 中的样本数。如果为 True,则结果是 bin 处的概率密度函数的值,归一化以使范围内的积分为 1。改用密度。

density : bool, optional

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

【讨论】:

【参考方案7】:

你的期望是错误的

垃圾箱高度的总和乘以它的宽度等于一。或者,正如您所说的正确,integral 必须是一个,不是您要集成的功能

是这样的:概率(如“人在 20 到 40 岁之间的概率是……%”)是积分(“从 20 到 40 岁” ) 在概率密度上。 bins 高度显示概率密度,而宽度乘以高度显示某个点在此 bin 中的概率(您将常数假设函数、bin 的高度、从 bin 的开头到 bin 的结尾积分)。高度本身就是密度,不是概率。这是一个每个宽度的概率,当然可以高于一个。

简单示例:想象一个从 0 到 1 的概率密度函数,其值为 0 从 0 到 0.9。函数可能在 0.9 和 1 之间?如果您整合它,请尝试一下。它会高于 1。

顺便说一句:根据粗略的猜测,您的 hist 的高度乘以宽度的总和似乎大约为 1,不是吗?

【讨论】:

以上是关于pylab.hist(数据,规范=1)。规范化似乎工作不正确的主要内容,如果未能解决你的问题,请参考以下文章

2.13生成可控的随机数据集合 模拟色子

sklearn StandardScaler 似乎无法正常工作

如何说服某人规范化数据库?

发送 POST 数据时阻止 Safari 规范化 Unicode?

路线规范似乎与生成的方法不匹配

Numpy 规范化代码异常缓慢