Comment normaliser un histogramme dans MATLAB?

Comment normaliser un histogramme tels que l'aire sous la fonction de densité de probabilité est égale à 1?

40
demandé sur Léo Léopold Hertz 준영 2011-03-16 06:19:48

7 réponses

ma réponse à cela 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 l'espace entier est 1 . En divisant par la somme et non , on obtient la densité correcte. Pour obtenir la bonne densité, vous devez diviser par la surface. Pour illustrer mon point de vue, 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 est d'accord avec la bonne réponse (courbe rouge).

enter image description here

une autre méthode (plus simple que la méthode 2) pour normaliser l'histogramme est de diviser par sum(f * dx) qui exprime l'intégrale de la fonction de densité de probabilité, i.e.

% 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
115
répondu abcd 2018-03-04 19:32:28

depuis 2014b, Matlab dispose de ces routines de normalisation intégrées nativement dans la fonction histogram (voir le fichier d'aide pour les 6 routines offertes par cette fonction). Voici un exemple utilisant le PDF normalisation (la somme de tous les bacs est 1).

data = 2*randn(5000,1) + 5;             % generate normal random (m=5, std=2)
h = histogram(data,'Normalization','pdf')   % PDF normalization

le PDF correspondant 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)

enter image description here

une amélioration qui pourrait très bien être due au succès de la question actuelle et de la réponse acceptée!


modifier - 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 produira les boîtes hist et histc . Il y a un script Matlab pour mettre à jour l'ancien code pour s'adapter à la façon dont histogram est appelé (bin edges au lieu de bin centers - link ). Ce faisant, on peut comparer les pdf méthodes de normalisation DE @abcd ( trapz et sum ) et Matlab ( pdf ).

3 pdf méthode de normalisation donner des résultats presque identiques (dans la gamme de 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

la différence maximale entre la nouvelle normalisation PDF et la première est de 5.5511 e-17.

20
répondu marsei 2017-06-30 13:53:18

hist peut non seulement tracer un histogramme, mais aussi vous rendre le nombre d'éléments dans chaque bin, de sorte que vous pouvez obtenir ce nombre, le normaliser en divisant chaque bin par le total et de tracer le résultat en utilisant bar . Exemple:

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

ou si vous voulez une doublure:

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

de la Documentation:

Edit: Cette solution répond à la question Comment faire pour avoir la somme de toutes les cellules égal à 1 . Cette approximation n'est valable que si la taille de votre bin est petite par rapport à la variance de vos données. La somme utilisée ici correspond à une simple formule de quadrature, les plus complexes peuvent être utilisés comme trapz comme proposé par R. M.

11
répondu Simon 2011-03-16 18:46:51
[f,x]=hist(data)

la surface de chaque barre est Hauteur*Largeur. Puisque MATLAB choisira des points équidistants pour les barres, la largeur est donc:

delta_x = x(2) - x(1)

maintenant, si nous additionnons toutes les barres individuelles, la superficie totale s'élèvera à

A=sum(f)*delta_x

ainsi le tracé à l'échelle correcte est obtenu par

bar(x, f/sum(f)/(x(2)-x(1)))
5
répondu Moppi 2012-09-22 03:07:01

la zone de PDF d'abcd n'est pas une, ce qui est impossible comme souligné dans de nombreux commentaires. Hypothèses faites dans de nombreuses réponses ici

  1. suppose une distance constante entre les bords consécutifs.
  2. la probabilité sous pdf devrait être 1. La normalisation doit être faite comme Normalization avec probability , et non comme Normalization avec pdf , dans histogram() et hist().

Fig. 1 résultat de l'approche hist (), Fig. 2 Sortie de l'approche histogram () 1519220920"

enter image description here enter image description here

l'amplitude maximale diffère entre deux approches qui proposent qu'il y ait une erreur dans l'approche de hist () parce que l'approche de histogram () utilise la normalisation standard. Je suppose que l'erreur avec l'approche de hist () ici est au sujet de la normalisation comme partiellement pdf , pas complètement comme probability .

Code avec hist() [obsolète]

Quelques remarques

  1. premier contrôle: sum(f)/N donne 1 si Nbins réglé manuellement.
  2. pdf exige la largeur de la cellule ( dx ) dans le graphique 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

sortie est en Figue. 1.

Code avec histogramme ()

Quelques remarques

  1. d'Abord vérifier: a) sum(f) est 1 si Nbins ajusté avec de l'histogramme()'s la Normalisation de la probabilité, b) sum(f)/N est 1 si Nbins est réglé manuellement sans normalisation.
  2. pdf exige la largeur de la cellule ( dx ) dans le graphique 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

sortie Fig. 2 et les résultats escomptés sont atteints: zone 1.0000.

Matlab: 2016a

Système: Linux Ubuntu 16.04 64 bits

Noyau Linux 4.6

3
répondu Léo Léopold Hertz 준영 2017-03-08 11:23:59

pour certaines Distributions, Cauchy je pense, j'ai constaté que trapz surestimera la zone, et donc le pdf changera en fonction du nombre de bacs que vous sélectionnez. Dans ce 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')
1
répondu user1240280 2012-03-16 12:12:53

il y a un excellent guide en trois parties pour ajustements D'histogrammes dans MATLAB ( rupture de lien original , archive.org link ), la première partie est sur l'Étirement d'Histogramme.

1
répondu anna 2016-03-03 20:37:30