Как нормализовать гистограмму в MATLAB? - PullRequest
43 голосов
/ 16 марта 2011

Как нормализовать гистограмму так, чтобы площадь под функцией плотности вероятности была равна 1?

Ответы [ 7 ]

119 голосов
/ 16 марта 2011

Мой ответ на этот вопрос такой же, как и в ответе на предыдущий вопрос .Для функции плотности вероятности интеграл по всему пространству равен 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
23 голосов
/ 22 декабря 2015

Начиная с 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

Соответствующий 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

Улучшение, которое вполне может быть связано с успехом самого вопроса и принятого ответа!


РЕДАКТИРОВАТЬ - Использование hist и histc сейчас не рекомендуется , и вместо него следует использовать histogram. Помните, что ни один из 6 способов создания ячеек с помощью этой новой функции не приведет к получению ячеек hist и histc. Существует скрипт Matlab для обновления прежнего кода, чтобы он соответствовал способу вызова histogram (края бинов вместо центров бинов - ссылка ). Таким образом можно сравнить pdf методы нормализации @abcd (trapz и sum) и Matlab (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.

11 голосов
/ 16 марта 2011

hist может не только построить гистограмму, но и вернуть вам количество элементов в каждом бине, так что вы можете получить это количество, нормализовать его, разделив каждый бин на общую сумму и построив график с помощью bar.Пример:

Y = rand(10,1);
C = hist(Y);
C = C ./ sum(C);
bar(C)

или, если вам нужен однострочный:

bar(hist(Y) ./ sum(hist(Y)))

Документация:

Редактировать: Это решение отвечает на вопрос Как сделать сумму всех бинов равной 1 .Это приближение действительно только в том случае, если размер вашей корзины небольшой по сравнению с дисперсией ваших данных.Используемая здесь сумма соответствует простой квадратурной формуле, можно использовать более сложные, например trapz, как предложено в RM

5 голосов
/ 22 сентября 2012
[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)))
3 голосов
/ 07 августа 2016

Область PDF abcd не одна, что невозможно, как указано во многих комментариях.Допущения, сделанные во многих ответах здесь

  1. Предполагают постоянное расстояние между последовательными ребрами.
  2. Вероятность при pdf должна быть 1. Нормализация должна быть выполнена как Normalization с probability, а не как Normalization с pdf, в гистограмме () и Hist ().

Рис.1 Выходной сигнал исторических данных (), Рис. 2 Выходной сигнал гистограммы ()

enter image description here enter image description here

Максимальная амплитудаотличается между двумя подходами, которые предполагают, что есть некоторая ошибка в подходе hist (), потому что подход histogram () использует стандартную нормализацию.Я полагаю, что ошибка с подходом hist () заключается в том, что нормализация частично pdf, а не полностью probability.

Код с историей () [устарел]

Некоторые замечания

  1. Первая проверка: sum(f)/N дает 1, если Nbins установлено вручную.
  2. pdf требует ширины ячейки (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.

Код с гистограммой ()

Некоторые замечания

  1. Первая проверка: a) sum(f) равно 1, если Nbins настроено с помощью гистограммы () 's Нормализация как вероятность, b) sum(f)/N равно 1, если Nbins установлено вручную без нормализации.
  2. pdf требует ширины ячейки (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

1 голос
/ 13 июля 2013

Существует прекрасное руководство из трех частей для Настройки гистограммы в MATLAB ( неработающая исходная ссылка , archive.org ссылка ), первая часть на растяжке гистограммы.

1 голос
/ 16 марта 2012

Для некоторых дистрибутивов, Коши, я думаю, я обнаружил, что 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')
...