如何在MATLAB中规范化直方图?

如何在MATLAB中规范化直方图?,matlab,histogram,normalization,Matlab,Histogram,Normalization,如何规范化直方图,使概率密度函数下的面积等于1?hist不仅可以绘制直方图,还可以返回每个存储单元中的元素计数,因此您可以获得该计数,通过将每个存储单元除以总面积并使用bar绘制结果来规范化它。例如: Y = rand(10,1); C = hist(Y); C = C ./ sum(C); bar(C) 或者,如果您想要一行: bar(hist(Y) ./ sum(hist(Y))) 文档: 编辑:此解决方案回答了如何使所有箱子的总和等于1的问题。只有当您的仓位大小相对于数据方差较

如何规范化直方图,使概率密度函数下的面积等于1?

hist
不仅可以绘制直方图,还可以返回每个存储单元中的元素计数,因此您可以获得该计数,通过将每个存储单元除以总面积并使用
bar
绘制结果来规范化它。例如:

Y = rand(10,1);
C = hist(Y);
C = C ./ sum(C);
bar(C)
或者,如果您想要一行:

bar(hist(Y) ./ sum(hist(Y)))
文档:

编辑:此解决方案回答了如何使所有箱子的总和等于1的问题。只有当您的仓位大小相对于数据方差较小时,此近似值才有效。这里使用的和对应于一个简单的求积公式,更复杂的可以使用,如R.M.

提出的
trapz
。我对这一点的回答与你的答案相同。对于概率密度函数。除以总和将得到正确的密度。要获得正确的密度,必须除以面积。为了说明我的观点,请尝试以下示例

[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更简单)是除以表示概率密度函数积分的
和(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

对于一些分布,我认为Cauchy,我发现trapz会高估面积,因此pdf会根据您选择的垃圾箱数量而变化。如果是这样的话,我会的

[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')
每个单条的面积为高度*宽度。由于MATLAB将为条形选择等距点,因此宽度为:

delta_x = x(2) - x(1)
现在,如果我们把所有的单条线加起来,总面积会变成

A=sum(f)*delta_x
因此,通过以下方法获得正确的比例图:

bar(x, f/sum(f)/(x(2)-x(1)))

关于(,)有一个优秀的三部分指南,
第一部分是关于直方图拉伸。

自2014b以来,Matlab在
直方图
函数中嵌入了这些标准化例程(有关该函数提供的6个例程,请参阅)。下面是一个使用PDF规范化的示例(所有箱子的总和为1)

相应的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
,而应该使用
histogram
。请注意,使用此新功能创建存储箱的6种方法都不会生成存储箱
hist
histc
product。有一个Matlab脚本更新以前的代码,以适应调用
直方图
的方式(bin边而不是bin中心-)。通过这样做,可以比较@abcd(
trapz
sum
)和Matlab(
pdf
)的
pdf
标准化方法

3
pdf
标准化方法给出了几乎相同的结果(在
eps
范围内)

测试:


新PDF规范化与前一个PDF规范化之间的最大差异为5.5511e-17。

abcd的PDF区域不是一个,这是不可能的,就像许多评论中指出的那样。 这里的许多答案中都有假设

  • 假设连续边之间的距离恒定
  • pdf
    下的概率应为1。在直方图()和hist()中,标准化应按
    标准化
    概率
    进行,而不是按
    标准化
    pdf
    进行 图1 hist()方法输出,图2 histogram()方法输出

    两种方法的最大振幅不同,这表明hist()的方法存在一些错误,因为histogram()的方法使用标准归一化。 我认为hist()方法的错误在于部分地将规范化为
    pdf
    ,而不是完全地将规范化为
    probability

    使用hist()编码[已弃用] 一些评论

  • 第一次检查:
    sum(f)/N
    给出
    1
    如果
    Nbins
    手动设置
  • pdf需要图形
    g
  • 代码

    输出如图1所示

    用直方图()编码 一些评论

  • 第一次检查:a)
    sum(f)
    1
    如果
    Nbins
    以直方图()的归一化作为概率进行调整,b)
    sum(f)/N
    为1如果
    Nbins
    未进行归一化手动设置
  • pdf需要图形
    g
  • 代码

    满足图2中的输出和预期输出:面积1.0000

    Matlab:2016a
    系统:Linux Ubuntu 16.04 64位

    Linux内核4.6

    除以面积的总和不等于1。我看到至少10个大于0.3的条形图点。0.3*10=3.0一个更简单的解决方案不是将f除以样本的#吗?在本例中,这些条比1细,因此您的计算是错误的。考虑从(--2,0)到(0,0.4)到(2, 0)的曲线的三角形,以估计面积。这个三角形的面积为0.5*4*0.4=0.8<1.0要使总和等于1,需要将新的箱子总和乘以箱子的宽度bin@abcd:但这篇文章说,我们可以除以归一化的总和:如何使用histcounts而不是hist进行此操作?PDF下的区域不在直方图中,这在概率论中是不可能的。请参阅stackoverflow.com/a/38813376/54964的答案,其中有一些更正。要匹配
    pdf
    下的区域1,您应该将标准化设置为
    概率
    ,而不是
    pdf
    。我很困惑,为什么要使用
    pdf
    而不是
    概率
    ,使条形区域总和为1?当您使用
    sum(h.values)时,
    不是
    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)
    
    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)
    
    %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
    
    %%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