如何在MATLAB中标准化直方图?

cMi*_*nor 45 matlab normalization histogram

如何对直方图进行归一化,使概率密度函数下的面积等于1?

abc*_*bcd 121

我对此的回答与对前一个问题的回答相同.对于概率密度函数,整个空间的积分为1.除以总和不会给你正确的密度.要获得正确的密度,您必须除以面积.为了说明我的观点,请尝试以下示例.

[f, x] = hist(randn(10000, 1), 50); % Create histogram from a normal distribution.
g = 1 / sqrt(2 * pi) * exp(-0.5 * x .^ 2); % pdf of the normal distribution

% METHOD 1: DIVIDE BY SUM
figure(1)
bar(x, f / sum(f)); hold on
plot(x, g, 'r'); hold off

% METHOD 2: DIVIDE BY AREA
figure(2)
bar(x, f / trapz(x, f)); hold on
plot(x, g, 'r'); hold off
Run Code Online (Sandbox Code Playgroud)

您可以自己查看哪种方法与正确答案一致(红色曲线).

在此输入图像描述

用于归一化直方图的另一种方法(比方法2更简单)是除以sum(f * dx)表示概率密度函数的积分,即

% METHOD 3: DIVIDE BY AREA USING sum()
figure(3)
dx = diff(x(1:2))
bar(x, f / sum(f * dx)); hold on
plot(x, g, 'r'); hold off
Run Code Online (Sandbox Code Playgroud)

  • @Rich条形图比1更薄,因此您的计算错误.考虑三角形从(-2,0)到(0,0.4)到(2,0)的曲线,以估计面积.该三角形的面积为0.5*4*0.4 = 0.8 <1.0 (9认同)
  • "按面积除以数字"的总和不等于1.我看到至少10个条形图点大于0.3.0.3*10 = 3.0一个更简单的解决方案不是将f除以样本数吗?在这种情况下,10000. (2认同)
  • 要使总和等于1,您需要将新的二进制数乘以二进制数的宽度 (2认同)

mar*_*sei 24

自2014b以来,Matlab将这些规范化例程本机嵌入histogram函数中(请参阅此函数提供的6个例程的帮助文件).以下是使用PDF规范化的示例(所有分箱的总和为1).

data = 2*randn(5000,1) + 5;             % generate normal random (m=5, std=2)
h = histogram(data,'Normalization','pdf')   % PDF normalization
Run Code Online (Sandbox Code Playgroud)

相应的PDF是

Nbins = h.NumBins;
edges = h.BinEdges; 
x = zeros(1,Nbins);
for counter=1:Nbins
    midPointShift = abs(edges(counter)-edges(counter+1))/2;
    x(counter) = edges(counter)+midPointShift;
end

mu = mean(data);
sigma = std(data);

f = exp(-(x-mu).^2./(2*sigma^2))./(sigma*sqrt(2*pi));
Run Code Online (Sandbox Code Playgroud)

两者一起给出了

hold on;
plot(x,f,'LineWidth',1.5)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

一个改进很可能是由于实际问题的成功和接受的答案!


编辑-使用histhistc不建议现在,和histogram应改为使用.请注意,使用这个新功能创建分档的6种方法都不会产生分档 histhistc产生.有一个Matlab脚本来更新以前的代码以适应 histogram调用方式(bin边缘而不是bin中心 - 链接).通过这样做,可以比较pdf @abcd(trapzsum)和Matlab(pdf)规范化方法.

3 pdf归一化方法给出几乎相同的结果(在范围内eps).

测试:

A = randn(10000,1);
centers = -6:0.5:6;
d = diff(centers)/2;
edges = [centers(1)-d(1), centers(1:end-1)+d, centers(end)+d(end)];
edges(2:end) = edges(2:end)+eps(edges(2:end));

figure;
subplot(2,2,1);
hist(A,centers);
title('HIST not normalized');

subplot(2,2,2);
h = histogram(A,edges);
title('HISTOGRAM not normalized');

subplot(2,2,3)
[counts, centers] = hist(A,centers); %get the count with hist
bar(centers,counts/trapz(centers,counts))
title('HIST with PDF normalization');


subplot(2,2,4)
h = histogram(A,edges,'Normalization','pdf')
title('HISTOGRAM with PDF normalization');

dx = diff(centers(1:2))
normalization_difference_trapz = abs(counts/trapz(centers,counts) - h.Values);
normalization_difference_sum = abs(counts/sum(counts*dx) - h.Values);

max(normalization_difference_trapz)
max(normalization_difference_sum)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

新PDF规范化与前者之间的最大差异为5.5511e-17.


Sim*_*mon 11

hist不仅可以绘制直方图,还可以返回每个bin中元素的数量,因此您可以获得该计数,通过将每个bin除以总计并使用绘制结果来对其进行标准化bar.例:

Y = rand(10,1);
C = hist(Y);
C = C ./ sum(C);
bar(C)
Run Code Online (Sandbox Code Playgroud)

或者如果你想要一个单行:

bar(hist(Y) ./ sum(hist(Y)))
Run Code Online (Sandbox Code Playgroud)

文档:

编辑:此解决方案回答问题如何使所有箱的总和等于1.仅当您的bin大小相对于数据的方差较小时,此近似才有效.这里使用的总和对应于简单的求积公式,可以像RMtrapz提出的那样使用更复杂的公式


小智 5

[f,x]=hist(data)
Run Code Online (Sandbox Code Playgroud)

每个单独栏的区域是高度*宽度.由于MATLAB将为条形选择等距点,因此宽度为:

delta_x = x(2) - x(1)
Run Code Online (Sandbox Code Playgroud)

现在,如果我们总结所有单个条形图,总面积将会出现

A=sum(f)*delta_x
Run Code Online (Sandbox Code Playgroud)

因此,通过获得正确缩放的图

bar(x, f/sum(f)/(x(2)-x(1)))
Run Code Online (Sandbox Code Playgroud)