Comment normaliser un histogramme tel que l'aire sous la fonction de densité de probabilité soit égale à 1?
Ma réponse à cette question est la même que dans une réponse à votre question précédente . Pour une fonction de densité de probabilité, l'intégrale sur tout l'espace est 1 . La division par la somme et non vous donnera la densité correcte. Pour obtenir la bonne densité, vous devez diviser par la superficie. Pour illustrer mon propos, essayez l'exemple suivant.
[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
Vous pouvez voir par vous-même quelle méthode convient à la bonne réponse (courbe rouge).
Une autre méthode (plus simple que la méthode 2) pour normaliser l'histogramme consiste à diviser par sum(f * dx)
, qui exprime l'intégrale de la fonction de densité de probabilité, c'est-à-dire.
% 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
Depuis 2014b, Matlab a ces routines de normalisation intégrées de manière native dans la fonction histogram
(voir le fichier aide) les 6 routines offertes par cette fonction). Voici un exemple utilisant la normalisation PDF (la somme de tous les bacs est égale à 1).
data = 2*randn(5000,1) + 5; % generate normal random (m=5, std=2)
h = histogram(data,'Normalization','pdf') % PDF normalization
Le correspondant PDF est
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));
Les deux ensemble donne
hold on;
plot(x,f,'LineWidth',1.5)
Une amélioration qui pourrait très bien être due au succès de la question et de la réponse acceptée !
EDIT - L'utilisation de hist
et histc
est non recommandé maintenant, et histogram
devrait être utilisé à la place. Attention, aucune des 6 façons de créer des bacs avec cette nouvelle fonction ne produira les bacs hist
et histc
. Il existe un script Matlab pour mettre à jour l'ancien code afin qu'il s'adapte à la manière dont histogram
est appelé (bin bords au lieu de bin centres - lien ). Ce faisant, on peut comparer les méthodes de normalisation pdf
de @abcd (trapz
et sum
) et Matlab (pdf
).
La méthode de normalisation 3 pdf
donne des résultats presque identiques (dans la plage de eps
) .
TESTER:
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)
La différence maximale entre la nouvelle normalisation PDF et la précédente est de 5.5511e-17.
hist
peut non seulement tracer un histogramme, mais aussi vous renvoyer le nombre d'éléments contenus dans chaque groupe. Vous pouvez ainsi obtenir ce nombre, le normaliser en divisant chaque groupe par le total et en représentant le résultat à l'aide de bar
. Exemple:
Y = Rand(10,1);
C = hist(Y);
C = C ./ sum(C);
bar(C)
ou si vous voulez un one-liner:
bar(hist(Y) ./ sum(hist(Y)))
Edit: Cette solution répond à la question Comment avoir la somme de tous les bacs égale à 1 . Cette approximation n’est valable que si la taille de votre corbeille est petite par rapport à la variance de vos données. La somme utilisée ici correspond à une formule simple en quadrature, les plus complexes pouvant être utilisées comme trapz
comme proposé par R. M.
[f,x]=hist(data)
La zone pour chaque barre individuelle est hauteur * largeur. Puisque MATLAB choisira des points équidistants pour les barres, la largeur est la suivante:
delta_x = x(2) - x(1)
Maintenant, si nous résumons toutes les barres individuelles, la surface totale apparaîtra comme
A=sum(f)*delta_x
Donc, le tracé correctement mis à l'échelle est obtenu par
bar(x, f/sum(f)/(x(2)-x(1)))
Le domaine abcd`s PDF n’est pas ce qui est impossible, comme le soulignent de nombreux commentaires. Des hypothèses formulées dans de nombreuses réponses ici.
pdf
devrait être 1. La normalisation devrait être effectuée comme Normalization
avec probability
, et non comme Normalization
avec pdf
, dans l'histogramme. () et hist ().Fig. 1 Sortie de l'approche hist (), Fig. 2 Sortie de l'histogramme ()
L'amplitude max diffère entre deux approches, ce qui suggère qu'il y a une erreur dans l'approche de hist () car l'approche de histogram () utilise la normalisation standard. Je suppose que l’erreur avec hist () ici est de normaliser partiellement pdf
, pas complètement comme probability
.
Quelques remarques
sum(f)/N
donne 1
Si Nbins
défini manuellement.dx
) dans le graphe g
Code
%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
La sortie est illustrée à la Fig. 1.
Quelques remarques
sum(f)
est 1
Si Nbins
ajusté avec la normalisation de l'histogramme () sous forme de probabilité, b) sum(f)/N
est égal à 1 si Nbins
est défini manuellement sans normalisation.dx
) dans le graphe g
Code
%%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
La sortie sur la figure 2 et la sortie attendue est atteinte: zone 1.0000.
Matlab: 2016a
Système: Linux Ubuntu 16.04 64 bit
Linux noyau 4.6
Pour certaines distributions, Cauchy, je pense que j’ai trouvé que trapz surestimerait la zone, et donc le pdf changera en fonction du nombre de bacs sélectionnés. Dans quel cas je fais
[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')
Il existe un excellent guide en trois parties pour Ajustements d'histogramme dans MATLAB ( lien original cassé , lien archive.org ), la première partie est sur l'histogramme. Étirage.