wake-up-neo.net

pylab.hist (Daten, normed = 1). Die Normalisierung scheint falsch zu funktionieren

Ich versuche ein Histogramm mit dem Argument normed = 1 zu erstellen

Zum Beispiel:

import pylab

data = ([1,1,2,3,3,3,3,3,4,5.1])    
pylab.hist(data, normed=1)
pylab.show()

Ich hatte erwartet, dass die Summe der Fächer 1 sein würde. Stattdessen ist einer der Fächer größer als 1. Was hat diese Normalisierung bewirkt? Und wie erstellt man ein Histogramm mit einer solchen Normalisierung, dass das Integral des Histogramms gleich 1 wäre?

enter image description here

36
smirnoffs

In meinem anderen Beitrag erfahren Sie, wie Sie die Summe aller Fächer in einem Histogramm auf eins setzen: https://stackoverflow.com/a/16399202/1542814

Kopieren Einfügen:

weights = np.ones_like(myarray)/float(len(myarray))
plt.hist(myarray, weights=weights)

wo Myarray Ihre Daten enthält

43
Carsten König

Gemäß documentationnormed: Bei True ist das Ergebnis der Wert der Wahrscheinlichkeitsdichtefunktion an der Bin, normalisiert, so dass das Integral über den Bereich 1 ist. Beachten Sie, dass die Summe der Histogrammwerte nicht ist gleich 1, es sei denn, Behälter mit Einheitsbreite werden ausgewählt; es ist keine Wahrscheinlichkeitsmassenfunktion. Dies ist von numpy doc, sollte aber für Pylab gleich sein.

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

Die Normalisierung erfolgt also einfach gemäß der Dokumentation wie:

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])
23
eat

Ich denke, Sie verwechseln die Behälterhöhen mit dem Inhalt der Behälter. Sie müssen den Inhalt jeder Ablage hinzufügen, d. H. Höhe * Breite für alle Ablagen. Das sollte = 1 sein.

7
juanchopanza

Ich hatte das gleiche Problem, und bei der Lösung kam ein anderes Problem auf: Wie kann man die normalisierten Bin-Frequenzen als Prozentsätze mit Ticks auf gerundete Werte darstellen. Ich poste es hier, falls es für jedermann nützlich ist. In meinem Beispiel wählte ich 10% (0,1) als Maximalwert für die y-Achse und 10 Schritte (eine von 0% bis 1%, eine von 1% bis 2% usw.). Der Trick besteht darin, die Ticks auf die data count-Werte (die Ausgangsliste n des plt.hist) zu setzen, die als Nächstes mit der FuncFormatter-Klasse in Prozentsätze umgewandelt werden. Folgendes habe ich getan:

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()

Grundstücke

Vor der Normalisierung: Die Y-Achseneinheit ist die Anzahl der Abtastungen innerhalb der Bin-Intervalle in der X-Achse: Before normalisation: the y axis unit is number of samples within the bin intervals in the x axis

Nach der Normierung: Die y-Achseneinheit ist die Häufigkeit der Bin-Werte als Prozentsatz über alle Abtastwerte After normalisation: the y axis unit is frequency of the bin values as a percentage over all the samples

5

Was hat diese Normalisierung getan?

Um eine Sequenz zu normalisieren, müssen Sie die Bin-Größe ..__ berücksichtigen. Entsprechend der -Dokumentation ist die voreingestellte Anzahl von Bin 10. Folglich ist die Bin-Größe (data.max() - data.min() )/10, dh 0.41 . Wenn normed=1, dann ist die Höhe des Balkens so, dass die Summe, multipliziert mit 0,41, 1 ergibt. Dies geschieht, wenn Sie integrieren.

Und wie erstellt man ein Histogramm mit einer solchen Normalisierung, dass das Integral des Histogramms gleich 1 wäre?

Ich denke, Sie möchten, dass die Summe des Histogramms und nicht dessen Integral gleich 1 ist. In diesem Fall scheint der schnellste Weg:

h = plt.hist(data)
norm = sum(data)
h2 = [i/norm for i in h[0]]
plt.bar(h[1],h2)
5
altroware

Es gibt auch ein Analogon in numpy - numpy.historgram: http://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html Einer der Parameter ist "density", If Wenn Sie density=True einstellen, wird die Ausgabe normalisiert.

normed: bool, optional Dieses Schlüsselwort ist in Numpy 1.6 aufgrund von verwirrendem/fehlerhaftem Verhalten veraltet. Es wird in Numpy 2.0 entfernt. Verwenden Sie stattdessen das Schlüsselwort density. Bei False enthält das Ergebnis die Anzahl der Proben in jeder Ablage. Wenn True, ist das Ergebnis der Wert der Wahrscheinlichkeitsdichtefunktion an der Bin, normalisiert, so dass das Integral über den Bereich 1 ist. Beachten Sie, dass dieses letztere Verhalten als fehlerhaft mit ungleichen Bin-Breiten bekannt ist; Verwenden Sie stattdessen die Dichte.

dichte: bool, optional Bei False enthält das Ergebnis die Anzahl der Proben in jeder Ablage. Bei True ist das Ergebnis der Wert der Wahrscheinlichkeitsdichtefunktion an der Bin, der so normalisiert ist, dass das Integral über den Bereich 1 ist. Beachten Sie, dass die Summe der Histogrammwerte nicht gleich 1 ist, es sei denn, Bins mit Einheitsbreite werden ausgewählt. es ist keine Wahrscheinlichkeitsmassenfunktion. Überschreibt das normed-Schlüsselwort, falls angegeben.

2

Deine Erwartungen sind falsch

Die Summe der Behälterhöhe mal ihre Breite entspricht eins. Oder, wie Sie richtig gesagt haben, das Integral muss eins sein, nicht die Funktion , die Sie integrieren.

Es ist wie folgt: Wahrscheinlichkeit (wie in "Die Wahrscheinlichkeit, dass die Person zwischen 20 und 40 Jahre alt ist ...%") ist das Integral ("Von 20 bis 40 Jahre") über der Wahrscheinlichkeit Dichte. Die Behälterhöhe zeigt die Wahrscheinlichkeitsdichte, während die Breite mal Höhe die Wahrscheinlichkeit angibt (Sie nehmen die konstant angenommene Funktion, Höhe des Behälters vom Anfang des Behälters bis zum Ende des Behälters) für einen bestimmten Punkt in diesem Behälter an. Die Höhe selbst ist die Dichte und keine Wahrscheinlichkeit. Es ist eine Wahrscheinlichkeit pro Breite, die natürlich höher sein kann als eine.

Ein einfaches Beispiel: Stellen Sie sich eine Wahrscheinlichkeitsdichtefunktion von 0 bis 1 vor, die den Wert 0 von 0 bis 0,9 hat. Was könnte die Funktion zwischen 0,9 und 1 sein? Wenn Sie es integrieren, probieren Sie es aus. Es wird höher als 1 sein.

Übrigens: aus einer groben Annahme scheint die Summe der Höhe mal der Breite Ihres Geschlechts etwa 1 zu ergeben, oder?

0
Mayou36