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

时间:2011-03-16 03:19:48

标签: matlab histogram normalization

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

7 个答案:

答案 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

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

enter image description here

标准化直方图的另一种方法(比方法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)

enter image description here

这一改进很可能是由于实际问题和成功答案的成功所致!

编辑 - 现在使用histhistcnot recommended,而应使用histogram。请注意,使用此新函数创建二进制文件的6种方法都不会产生条箱histhistc。有一个Matlab脚本可以更新以前的代码以适应调用histogram的方式(bin边缘而不是bin中心 - link)。通过这样做,可以比较@abcd(pdftrapz)和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)

enter image description here

新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区域不是一个,这在许多评论中都是不可能的。 这里的许多答案都做了假设

  1. 假设连续边缘之间的距离恒定。
  2. pdf下的概率应该是1.标准化应该在Normalization probability而不是Normalization pdf,在柱状图()中完成和hist()。
  3. 图。 1 hist()方法的输出,图2直方图()方法的输出

    enter image description here enter image description here

    两种方法之间的最大振幅不同,这提出了hist()方法中存在一些错误,因为histogram()的方法使用标准规范化。 我假设在这里使用hist()方法的错误是关于标准化为部分pdf,而不是完全为probability

    带有hist()的代码[不建议使用]

    一些评论

    1. 首先检查:sum(f)/N如果1手动设置,则会Nbins
    2. pdf需要图表dx
    3. 中广告的宽度(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.

      直方图代码()

      一些评论

      1. 首先检查:a)sum(f) 1如果Nbins调整为histogram()的标准化为概率,则b)sum(f)/N为1 Nbins手动设置而不进行规范化。
      2. pdf需要图表dx
      3. 中广告的宽度(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 MATLABbroken original linkarchive.org link)有一个很好的三部分指南, 第一部分是直方图拉伸。