python - histograma - pandas histogram
pylab.hist(data, normed=1). La normalización parece funcionar incorrectamente (7)
¿Qué hizo esta normalización?
Para normalizar una secuencia, debes tener en cuenta el tamaño del contenedor. Según la documentation , el número predeterminado de bin es 10. En consecuencia, el tamaño del contenedor es (data.max() - data.min() )/10
, es decir, 0.41. Si normed=1
, entonces la altura de la barra es tal que la suma, multiplicada por 0.41, da 1. Esto es lo que sucede cuando se integra.
¿Y cómo crear un histograma con tal normalización que la integral del histograma sería igual a 1?
Creo que quieres que la suma del histograma, no su integral, sea igual a 1. En este caso, la forma más rápida parece ser:
h = plt.hist(data)
norm = sum(data)
h2 = [i/norm for i in h[0]]
plt.bar(h[1],h2)
Estoy tratando de crear un histograma con argumento normed = 1
Por ejemplo:
import pylab
data = ([1,1,2,3,3,3,3,3,4,5.1])
pylab.hist(data, normed=1)
pylab.show()
Esperaba que la suma de los contenedores fuera 1. Pero, en cambio, uno de los contenedores es más grande que 1. ¿Qué hizo esta normalización? ¿Y cómo crear un histograma con tal normalización que la integral del histograma sería igual a 1?
Creo que estás confundiendo las alturas de los contenedores con los contenidos del contenedor. Debe agregar el contenido de cada contenedor, es decir, el ancho * de altura para todos los contenedores. Eso debería = 1.
De acuerdo con la documentation normada: si es verdadero, el resultado es el valor de la función de densidad de probabilidad en el contenedor, normalizado de manera que la integral sobre el rango sea 1. Tenga en cuenta que la suma de los valores del histograma no será igual a 1 a menos que los contenedores el ancho de la unidad se eligen; no es una función de masa de probabilidad. Esto es de numpy doc, pero debería ser el mismo para pylab.
In []: data= array([1,1,2,3,3,3,3,3,4,5.1])
In []: counts, bins= histogram(data, normed= True)
In []: counts
Out[]: array([ 0.488, 0., 0.244, 0., 1.22, 0., 0., 0.244, 0., 0.244])
In []: sum(counts* diff(bins))
Out[]: 0.99999999999999989
Entonces la normalización se hace de acuerdo con la documentación como:
In []: counts, bins= histogram(data, normed= False)
In []: counts
Out[]: array([2, 0, 1, 0, 5, 0, 0, 1, 0, 1])
In []: counts_n= counts/ sum(counts* diff(bins))
In []: counts_n
Out[]: array([ 0.488, 0., 0.244, 0., 1.22 , 0., 0., 0.244, 0., 0.244])
También hay un análogo en numpy - numpy.historgram
: http://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html Uno de los parámetros es "densidad", si establece density=True
, la salida se normalizará.
normed: bool, opcional Esta palabra clave está en desuso en Numpy 1.6 debido a un comportamiento confuso / con errores. Se eliminará en Numpy 2.0. Use la palabra clave de densidad en su lugar. Si es False, el resultado contendrá la cantidad de muestras en cada contenedor. Si es Verdadero, el resultado es el valor de la función de densidad de probabilidad en el contenedor, normalizado de modo que la integral sobre el rango sea 1. Tenga en cuenta que se sabe que este último comportamiento tiene errores con anchos de contenedor desiguales; use densidad en su lugar.
densidad: bool, opcional Si es falso, el resultado contendrá la cantidad de muestras en cada contenedor. Si es verdadero, el resultado es el valor de la función de densidad de probabilidad en el contenedor, normalizado de modo que la integral sobre el rango sea 1. Obsérvese que la suma de los valores del histograma no será igual a 1 a menos que se elijan contenedores de ancho unitario; no es una función de masa de probabilidad. Reemplaza la palabra clave normada si se da.
Tuve el mismo problema, y al resolverlo surgió otro problema: cómo trazar las frecuencias de los contenedores normalizados como porcentajes con tics en los valores redondeados . Lo estoy publicando aquí en caso de que sea útil para cualquier persona. En mi ejemplo, elegí 10% (0.1) como el valor máximo para el eje y, y 10 pasos (uno de 0% a 1%, uno de 1% a 2%, y así sucesivamente). El truco consiste en establecer los ticks en los recuentos de datos (que son la lista de salida n
del plt.hist
) que luego se transformarán en porcentajes utilizando la clase FuncFormatter
. Esto es lo que hice:
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
fig, ax = plt.subplots()
# The required parameters
num_steps = 10
max_percentage = 0.1
num_bins = 40
# Calculating the maximum value on the y axis and the yticks
max_val = max_percentage * len(data)
step_size = max_val / num_steps
yticks = [ x * step_size for x in range(0, num_steps+1) ]
ax.set_yticks( yticks )
plt.ylim(0, max_val)
# Running the histogram method
n, bins, patches = plt.hist(data, num_bins)
# To plot correct percentages in the y axis
to_percentage = lambda y, pos: str(round( ( y / float(len(data)) ) * 100.0, 2)) + ''%''
plt.gca().yaxis.set_major_formatter(FuncFormatter(to_percentage))
plt.show()
Parcelas
Antes de la normalización: la unidad del eje y es el número de muestras dentro de los intervalos del contenedor en el eje x:
Después de la normalización: la unidad del eje y es la frecuencia de los valores del contenedor como un porcentaje sobre todas las muestras
Vea mi otra publicación para saber cómo hacer que la suma de todos los contenedores en un histograma sea igual a uno: https://.com/a/16399202/1542814
Copiar pegar:
weights = np.ones_like(myarray)/float(len(myarray))
plt.hist(myarray, weights=weights)
donde myarray contiene tus datos
Tus expectativas son incorrectas
La suma de la altura de los contenedores por su ancho es igual a uno. O, como dijiste correctamente, la integral tiene que ser una, no la función sobre la que estás integrando.
Es así: la probabilidad (como en "la probabilidad de que la persona tenga entre 20 y 40 años es ...%") es la integral ("de 20 a 40 años") sobre la densidad de probabilidad . La altura de los contenedores muestra la densidad de probabilidad, mientras que el ancho por alto muestra la probabilidad (usted integra la función constante asumida, altura del contenedor, desde el principio del contenedor hasta el final del contenedor) para que un determinado punto esté en este contenedor. La altura en sí es la densidad y no una probabilidad . Es una probabilidad por ancho que puede ser más alta que una por supuesto.
Ejemplo simple: imagina una función de densidad de probabilidad de 0 a 1 que tiene un valor 0 de 0 a 0.9. ¿Cuál podría ser la función entre 0.9 y 1? Si te integras, pruébalo. Será más alto que 1.
Por cierto: a partir de una suposición aproximada, la suma de la altura por el ancho de su hist parece producir aproximadamente 1, ¿no?