如何对直方图进行归一化,使得概率密度函数下的面积等于1?
答案 0 :(得分:117)
我对此的回答与对earlier question的回答相同。对于概率密度函数,the integral over the entire space is 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
您可以自己查看哪种方法与正确答案一致(红色曲线)。
标准化直方图的另一种方法(比方法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
答案 1 :(得分:22)
自2014b以来,Matlab在histogram
函数中具有本地嵌入的规范化例程(有关此函数提供的6个例程,请参阅help file)。以下是使用 PDF规范化的示例(所有分档的总和为1)。
data = 2*randn(5000,1) + 5; % generate normal random (m=5, std=2)
h = histogram(data,'Normalization','pdf') % PDF normalization
相应的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));
两者合在一起
hold on;
plot(x,f,'LineWidth',1.5)
这一改进很可能是由于实际问题和成功答案的成功所致!
编辑 - 现在使用hist
和histc
为not recommended,而应使用histogram
。请注意,使用此新函数创建二进制文件的6种方法都不会产生条箱hist
和histc
。有一个Matlab脚本可以更新以前的代码以适应调用histogram
的方式(bin边缘而不是bin中心 - link)。通过这样做,可以比较@abcd(pdf
和trapz
)和Matlab(sum
)的pdf
规范化方法。
3 pdf
规范化方法提供几乎相同的结果(在eps
)范围内。
TEST:
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)
新PDF规范化与前者之间的最大差异为5.5511e-17。
答案 2 :(得分:11)
hist
不仅可以绘制直方图,还可以返回每个bin中元素的数量,因此您可以获得该计数,通过将每个bin除以总数并使用{{1绘制结果来对其进行标准化}}。例如:
bar
或者如果你想要一个单行:
Y = rand(10,1);
C = hist(Y);
C = C ./ sum(C);
bar(C)
编辑:此解决方案回答了问题如何使所有箱的总和等于1 。仅当您的bin大小相对于数据的方差较小时,此近似才有效。这里使用的和对应于一个简单的求积公式,可以使用更复杂的公式,如 R提出的bar(hist(Y) ./ sum(hist(Y)))
。米
答案 3 :(得分:5)
[f,x]=hist(data)
每个单独栏的区域是高度*宽度。由于MATLAB将为条形选择等距点,因此宽度为:
delta_x = x(2) - x(1)
现在,如果我们总结所有单个条形图,则总面积将为
A=sum(f)*delta_x
因此,通过
获得正确缩放的图bar(x, f/sum(f)/(x(2)-x(1)))
答案 4 :(得分:3)
abcd的PDF区域不是一个,这在许多评论中都是不可能的。 这里的许多答案都做了假设
pdf
下的概率应该是1.标准化应该在Normalization
probability
而不是Normalization
pdf
,在柱状图()中完成和hist()。 图。 1 hist()方法的输出,图2直方图()方法的输出
两种方法之间的最大振幅不同,这提出了hist()方法中存在一些错误,因为histogram()的方法使用标准规范化。
我假设在这里使用hist()方法的错误是关于标准化为部分pdf
,而不是完全为probability
。
一些评论
sum(f)/N
如果1
手动设置,则会Nbins
。 dx
g
)
醇>
代码
%http://stackoverflow.com/a/5321546/54964
N=10000;
Nbins=50;
[f,x]=hist(randn(N,1),Nbins); % create histogram from ND
%METHOD 4: Count Densities, not Sums!
figure(3)
dx=diff(x(1:2)); % width of bin
g=1/sqrt(2*pi)*exp(-0.5*x.^2) .* dx; % pdf of ND with dx
% 1.0000
bar(x, f/sum(f));hold on
plot(x,g,'r');hold off
输出见图1.
一些评论
sum(f)
1
如果Nbins
调整为histogram()的标准化为概率,则b)sum(f)/N
为1 Nbins
手动设置而不进行规范化。 dx
g
)
醇>
代码
%%METHOD 5: with histogram()
% http://stackoverflow.com/a/38809232/54964
N=10000;
figure(4);
h = histogram(randn(N,1), 'Normalization', 'probability') % hist() deprecated!
Nbins=h.NumBins;
edges=h.BinEdges;
x=zeros(1,Nbins);
f=h.Values;
for counter=1:Nbins
midPointShift=abs(edges(counter)-edges(counter+1))/2; % same constant for all
x(counter)=edges(counter)+midPointShift;
end
dx=diff(x(1:2)); % constast for all
g=1/sqrt(2*pi)*exp(-0.5*x.^2) .* dx; % pdf of ND
% Use if Nbins manually set
%new_area=sum(f)/N % diff of consecutive edges constant
% Use if histogarm() Normalization probability
new_area=sum(f)
% 1.0000
% No bar() needed here with histogram() Normalization probability
hold on;
plot(x,g,'r');hold off
图2中的输出和预期输出满足:面积1.0000。
Matlab:2016a
系统:Linux Ubuntu 16.04 64位
Linux内核4.6
答案 5 :(得分:1)
对于某些发行版,Cauchy我认为,我发现trapz会高估该区域,因此pdf将根据您选择的bin数量而改变。我在哪种情况下
[N,h]=hist(q_f./theta,30000); % there Is a large range but most of the bins will be empty
plot(h,N/(sum(N)*mean(diff(h))),'+r')
答案 6 :(得分:1)
Histogram Adjustments in MATLAB(broken original link,archive.org link)有一个很好的三部分指南, 第一部分是直方图拉伸。