Как нормализовать гистограмму в MATLAB?

36

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

Теги:
histogram
normalization

7 ответов

117
Лучший ответ

Мой ответ на этот вопрос совпадает с ответом на ваш более ранний вопрос. Для функции плотности вероятности интеграл по всему пространству равен 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

Вы можете сами убедиться, какой метод соответствует правильному ответу (красная кривая).

Изображение 6347

Другой метод (более прямой, чем метод 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
  • 2
    Сумма «Разделить на площадь» не равна 1. Я вижу, по крайней мере, 10 столбчатых точек больше 0,3. 0,3 * 10 = 3,0 Разве не проще было бы разделить f на количество выборок? В этом случае 10000.
  • 9
    @Rich Столбики тоньше 1, поэтому ваш расчет неверен. Рассмотрим треугольник под кривой от (-2,0) до (0, 0,4) до (2, 0), чтобы оценить площадь. Этот треугольник имеет площадь 0,5 * 4 * 0,4 = 0,8 <1,0
Показать ещё 4 комментария
19

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

Изображение 6348

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


EDIT - использование hist и histc теперь не рекомендуется, и вместо этого следует использовать histogram. Остерегайтесь того, что ни один из 6 способов создания бункеров с этой новой функцией не приведет к созданию бункеров hist и histc. Существует Matlab script для обновления прежнего кода, чтобы он соответствовал тому, как вызывается histogram (края бинов вместо центров bin - ссылка). Таким образом, можно сравнить методы нормализации 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)

Изображение 6349

Максимальное различие между новой нормировкой PDF и прежней - 5.5511e-17.

  • 0
    Область под PDF не является одной из ваших гистограмм, что невозможно в теории вероятностей. Смотрите ответ stackoverflow.com/a/38813376/54964, где некоторые исправления. Чтобы соответствовать области под pdf , нормализация должна быть установлена как probability , а не pdf .
9

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

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

или если вы хотите использовать один слой:

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

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

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

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)))
3

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

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

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

Изображение 6350 Изображение 6351

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

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

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

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

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

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

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

  • 0
    Я в замешательстве, почему в документации MATLAB говорится, что нужно использовать pdf вместо probability , что сумма столбцов будет равна единице? Когда вы используете sum(h.values) , вы не sum(h.values) только высоты бина, а не области бина?
  • 0
    У меня был тот же вопрос, что и у ОП, и что меня смутило, так это то, что вы говорите полную противоположность документации MATLAB. Пожалуйста, проверьте mathworks.com/help/matlab/ref/… Там четко сказано использовать pdf чтобы сумма слитков составляла единицу, а не probability . Более того, вы используете sum(f) где f=h.Values показывают, что эта область равна единице. h.Values соответствуют высотам бина, таким образом, согласно определению нормализации probability которая будет суммироваться с h.Values но это не то же самое, что площади баров.
Показать ещё 4 комментария
1

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

1

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню