Как нормализовать гистограмму так, чтобы область под функцией плотности вероятности была равна 1?
Как нормализовать гистограмму в MATLAB?
Ответ 1
Мой ответ на этот вопрос совпадает с ответом на ваш более ранний вопрос. Для функции плотности вероятности интеграл по всему пространству равен 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
Ответ 2
Начиная с 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)
Улучшение, которое вполне может быть связано с успехом фактического вопроса и принятого ответа!
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)
Максимальное различие между новой нормировкой PDF и прежней - 5.5511e-17.
Ответ 3
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.
Ответ 4
[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)))
Ответ 5
Область PDF файла abcd не является одной, что невозможно, как указано во многих комментариях. Предположения, сделанные во многих ответах здесь
- Предположим, что постоянное расстояние между последовательными ребрами.
- Вероятность при
pdf
должна быть 1. Нормализация должна выполняться какNormalization
сprobability
, а не какNormalization
сpdf
, в гистограмме() и hist().
рис. 1 Выход метода hist(), Рисунок 2 Выход метода гистограммы()
Максимальная амплитуда различается между двумя подходами, которые предполагают, что есть некоторая ошибка в методе 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
Ответ 6
Для некоторых Распределений, Коши, я думаю, я обнаружил, что 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')
Ответ 7
Существует отличное руководство для трех частей для Настройки гистограммы в MATLAB (сломанная исходная ссылка, ссылка archive.org), первая часть находится на растяжке гистограммы.