normalized - ¿Cómo normalizar un histograma en MATLAB?
histograma normalizado matlab (7)
Desde 2014b, Matlab tiene estas rutinas de normalización incorporadas de forma nativa en la función de histogram
(consulte el archivo de ayuda para las 6 rutinas que ofrece esta función). Aquí hay un ejemplo usando la normalización de PDF (la suma de todos los contenedores es 1).
data = 2*randn(5000,1) + 5; % generate normal random (m=5, std=2)
h = histogram(data,''Normalization'',''pdf'') % PDF normalization
El PDF correspondiente es
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));
Los dos juntos dan
hold on;
plot(x,f,''LineWidth'',1.5)
¡Una mejora que bien podría deberse al éxito de la pregunta real y la respuesta aceptada!
EDITAR - El uso de hist
e histc
no se recomienda ahora, y el histogram
debería usarse en su lugar. Tenga en cuenta que ninguna de las 6 formas de crear contenedores con esta nueva función producirá los contenedores hist
e histc
. Hay una secuencia de comandos de Matlab para actualizar el código anterior para que se ajuste a la forma en que se llama el histogram
(bordes del contenedor en lugar de centros del contenedor - link ). Al hacerlo, se pueden comparar los métodos de normalización de pdf
de @abcd ( trapz
y sum
) y Matlab ( pdf
).
El método de normalización de 3 pdf
da resultados casi idénticos (dentro del rango de eps
) .
PRUEBA:
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 diferencia máxima entre la nueva normalización de PDF y la anterior es 5.5511e-17.
¿Cómo normalizar un histograma de modo que el área bajo la función de densidad de probabilidad sea igual a 1?
El área de PDF de abcd no es una, lo que es imposible como se señala en muchos comentarios. Suposiciones hechas en muchas respuestas aquí
- Suponga una distancia constante entre los bordes consecutivos.
- La probabilidad bajo
pdf
debe ser 1. La normalización debe hacerse comoNormalization
conprobability
, no comoNormalization
conpdf
, en histograma () e hist ().
Fig. 1 Salida del enfoque hist (), Fig. 2 Salida del enfoque del histograma ()
La amplitud máxima difiere entre dos enfoques que propone que hay algún error en el enfoque de hist () porque el enfoque de histograma () usa la normalización estándar. Supongo que el error con el enfoque hist () aquí es acerca de la normalización como parcialmente pdf
, no completamente como probability
.
Código con hist () [obsoleta]
Algunas observaciones
- Primera comprobación:
sum(f)/N
da1
siNbins
establece manualmente. - pdf requiere el ancho del contenedor (
dx
) en el gráficog
Código
%http://.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 salida está en la Fig. 1.
Código con histograma ()
Algunas observaciones
- Primera comprobación: a)
sum(f)
es1
siNbins
ajustado con histogram () ''s Normalization como probabilidad, b)sum(f)/N
es 1 siNbins
se establece manualmente sin normalización. - pdf requiere el ancho del contenedor (
dx
) en el gráficog
Código
%%METHOD 5: with histogram()
% http://.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 salida en la Fig. 2 y la salida esperada se cumplen: área 1.0000.
Matlab: 2016a
Sistema: Linux Ubuntu 16.04 64 bit
Kernel de Linux 4.6
Hay una excelente guía de tres partes para los Ajustes de Histograma en MATLAB ( enlace original roto , enlace archive.org ), la primera parte es sobre Estiramiento de Histograma.
Mi respuesta a esto es la misma que en una respuesta a su pregunta anterior . Para una función de densidad de probabilidad, la integral en todo el espacio es 1 . Dividir por la suma no le dará la densidad correcta. Para obtener la densidad correcta, debes dividir por el área. Para ilustrar mi punto, pruebe el siguiente ejemplo.
[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
Puedes ver por ti mismo qué método está de acuerdo con la respuesta correcta (curva roja).
Otro método (más directo que el método 2) para normalizar el histograma es dividir por sum(f * dx)
que expresa la integral de la función de densidad de probabilidad, es decir,
% 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
Para algunas distribuciones, creo que Cauchy, he descubierto que trapz sobreestimará el área, por lo que el pdf cambiará dependiendo de la cantidad de contenedores que seleccione. En cuyo caso lo hago
[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'')
hist
no solo puede trazar un histograma sino también devolverle el recuento de elementos en cada contenedor, de modo que puede obtener ese conteo, normalizarlo dividiendo cada contenedor por el total y trazando el resultado usando la bar
. Ejemplo:
Y = rand(10,1);
C = hist(Y);
C = C ./ sum(C);
bar(C)
o si quieres un trazador de líneas:
bar(hist(Y) ./ sum(hist(Y)))
Documentación:
Editar: esta solución responde a la pregunta Cómo hacer que la suma de todos los intervalos sea igual a 1 . Esta aproximación es válida solo si el tamaño de su contenedor es pequeño en relación con la varianza de sus datos. La suma utilizada aquí corresponde a una fórmula de cuadratura simple, se pueden usar más complejas como trapz
como lo propuso RM
[f,x]=hist(data)
El área para cada barra individual es alto * ancho. Como MATLAB elegirá puntos equidistantes para las barras, el ancho será:
delta_x = x(2) - x(1)
Ahora, si sumamos todas las barras individuales, el área total saldrá como
A=sum(f)*delta_x
Entonces, el diagrama correctamente escalado se obtiene
bar(x, f/sum(f)/(x(2)-x(1)))