Wie berechnen Sie die Wahrscheinlichkeit eines Wertes, der eine Liste von Samples aus einer Verteilung in Python gegeben wird?

Nicht sicher, ob dies in der Statistik gehört, aber ich versuche, Python zu verwenden, um dies zu erreichen. Ich habe im Grunde nur eine Liste von ganzen Zahlen:

data = [300,244,543,1011,300,125,300 ... ] 

Und ich möchte die Wahrscheinlichkeit eines Wertes kennen, der bei diesen Daten auftritt. Ich zeigte Histogramme der Daten mit matplotlib und erhielt diese:

Bildbeschreibung hier eingeben

Bildbeschreibung hier eingeben

Im ersten Graphen repräsentieren die Zahlen die Zeichenanzahl in einer Sequenz. In der zweiten Grafik ist es eine gemessene Zeit in Millisekunden. Das Minimum ist größer als Null, aber es ist nicht unbedingt ein Maximum. Die Graphen wurden mit Millionen von Beispielen erstellt, aber ich bin mir nicht sicher, ob ich andere Annahmen über die Verteilung machen kann. Ich möchte die Wahrscheinlichkeit eines neuen Wertes kennen, da ich ein paar Millionen Beispiele für Werte habe. In der ersten Grafik habe ich ein paar Millionen Sequenzen von verschiedenen Längen. Würde gerne eine Wahrscheinlichkeit von 200 Längen kennen, zum Beispiel.

Ich weiß, dass für eine kontinuierliche Verteilung die Wahrscheinlichkeit eines exakten Punktes null sein soll, aber angesichts eines Stroms von neuen Werten muss ich sagen, wie wahrscheinlich jeder Wert ist. Ich habe durch einige der numpy / scipy Wahrscheinlichkeit Dichte Funktionen sah, aber ich bin nicht sicher, welche zu wählen oder wie man nach neuen Werten abfragen, sobald ich etwas wie scipy.stats.norm.pdf (Daten) laufen. Es scheint, dass unterschiedliche Wahrscheinlichkeitsdichtefunktionen den Daten anders entsprechen. Angesichts der Form der Histogramme bin ich nicht sicher, wie zu entscheiden, welche zu verwenden.

    3 Solutions collect form web for “Wie berechnen Sie die Wahrscheinlichkeit eines Wertes, der eine Liste von Samples aus einer Verteilung in Python gegeben wird?”

    Da Sie nicht scheinen, eine spezifische Verteilung im Verstand zu haben, aber Sie konnten viele Datenproben haben, schlage ich vor, eine nichtparametrische Dichteschätzmethode zu verwenden. Einer der Datentypen, die Sie beschreiben (Zeit in ms), ist eindeutig kontinuierlich und eine Methode zur nichtparametrischen Schätzung einer Wahrscheinlichkeitsdichtefunktion (PDF) für kontinuierliche Zufallsvariablen ist das Histogramm, das Sie bereits erwähnt haben. Allerdings, wie Sie unten sehen werden, kann Kernel Density Estimation (KDE) besser sein. Die zweite Art von Daten, die Sie beschreiben (Anzahl der Zeichen in einer Sequenz) ist von der diskreten Art. Hier kann die Kerndichte-Schätzung auch nützlich sein und kann als Glättungstechnik für die Situationen gesehen werden, in denen Sie keine ausreichende Menge an Samples für alle Werte der diskreten Variablen haben.

    Schätzung der Dichte

    Das folgende Beispiel zeigt, wie man zuerst Datenproben aus einer Mischung von 2 Gaußschen Verteilungen erzeugt und dann die Kerndichteabschätzung anwendet, um die Wahrscheinlichkeitsdichtefunktion zu finden:

     import numpy as np import matplotlib.pyplot as plt import matplotlib.mlab as mlab from sklearn.neighbors import KernelDensity # Generate random samples from a mixture of 2 Gaussians # with modes at 5 and 10 data = np.concatenate((5 + np.random.randn(10, 1), 10 + np.random.randn(30, 1))) # Plot the true distribution x = np.linspace(0, 16, 1000)[:, np.newaxis] norm_vals = mlab.normpdf(x, 5, 1) * 0.25 + mlab.normpdf(x, 10, 1) * 0.75 plt.plot(x, norm_vals) # Plot the data using a normalized histogram plt.hist(data, 50, normed=True) # Do kernel density estimation kd = KernelDensity(kernel='gaussian', bandwidth=0.75).fit(data) # Plot the estimated densty kd_vals = np.exp(kd.score_samples(x)) plt.plot(x, kd_vals) # Show the plots plt.show() 

    Dies wird das folgende Diagramm hervorbringen, wo die wahre Verteilung in blau dargestellt ist, das Histogramm grün dargestellt wird und das mit KDE geschätzte PDF in rot dargestellt wird:

    Grundstück

    Wie Sie sehen können, ist in dieser Situation das PDF, das durch das Histogramm angenähert wird, nicht sehr nützlich, während KDE eine viel bessere Schätzung liefert. Jedoch mit einer größeren Anzahl von Datenproben und einer richtigen Wahl der Behältergröße, könnte das Histogramm auch eine gute Schätzung hervorbringen.

    Die Parameter, die du bei KDE einstellen kannst, sind der Kernel und die Bandbreite . Sie können über den Kernel als den Baustein für die geschätzte PDF denken, und mehrere Kernel-Funktionen sind verfügbar in Scikit Learn: Gaussian, tophat, epanechnikov, exponentiell, linear, Cosinus. Durch das Ändern der Bandbreite können Sie den Bias-Varianz-Kompromiss anpassen. Größere Bandbreite führt zu einer erhöhten Bias, was gut ist, wenn man weniger Datenproben hat. Eine kleinere Bandbreite erhöht die Varianz (weniger Samples werden in die Schätzung aufgenommen), wird aber eine bessere Schätzung geben, wenn mehr Proben verfügbar sind.

    Berechnungswahrscheinlichkeit

    Für eine PDF wird die Wahrscheinlichkeit erhalten, indem man das Integral über einen Bereich von Werten berechnet. Wie Sie bemerkt haben, führt das zu der Wahrscheinlichkeit 0 für einen bestimmten Wert.

    Scikit Learn scheint keine eingebaute Funktion für die Berechnung der Wahrscheinlichkeit zu haben. Allerdings ist es einfach, das Integral des PDF über einen Bereich zu schätzen. Wir können es tun, indem wir das PDF mehrmals innerhalb des Bereichs auswerten und die erhaltenen Werte multipliziert mit der Schrittweite zwischen jedem Auswertungspunkt summieren. Im folgenden Beispiel werden N Abtastwerte mit step .

     # Get probability for range of values start = 5 # Start of the range end = 6 # End of the range N = 100 # Number of evaluation points step = (end - start) / (N - 1) # Step size x = np.linspace(start, end, N)[:, np.newaxis] # Generate values in the range kd_vals = np.exp(kd.score_samples(x)) # Get PDF values for each x probability = np.sum(kd_vals * step) # Approximate the integral of the PDF print(probability) 

    Bitte beachten Sie, dass kd.score_samples die Log-Likelihood der kd.score_samples generiert. Daher ist np.exp erforderlich, um die Wahrscheinlichkeit zu erhalten.

    Die gleiche Berechnung kann mit eingebauten SciPy-Integrationsmethoden durchgeführt werden, die ein bisschen genaueres Ergebnis liefern:

     from scipy.integrate import quad probability = quad(lambda x: np.exp(kd.score_samples(x)), start, end)[0] 

    Zum Beispiel, für einen Lauf, die erste Methode berechnet die Wahrscheinlichkeit als 0.0859024655305 , während die zweite Methode produziert 0.0850974209996139 .

    OK Ich biete dies als Ausgangspunkt, aber die Schätzung der Dichten ist ein sehr breites Thema. Für Ihren Fall, der die Menge der Zeichen in einer Sequenz einbezieht, können wir diese aus einer geradlinigen häufigen Perspektive mit empirischer Wahrscheinlichkeit modellieren. Hier ist die Wahrscheinlichkeit im wesentlichen eine Verallgemeinerung des Prozentsatzes. In unserem Modell ist der Probenraum diskret und alle positiven ganzen Zahlen. Nun, dann zählen Sie einfach die Vorkommnisse und teilen sich durch die Gesamtzahl der Ereignisse, um Ihre Schätzung für die Wahrscheinlichkeiten zu erhalten. Überall haben wir null Beobachtungen, unsere Schätzung für die Wahrscheinlichkeit ist Null.

     >>> samples = [1,1,2,3,2,2,7,8,3,4,1,1,2,6,5,4,8,9,4,3] >>> from collections import Counter >>> counts = Counter(samples) >>> counts Counter({1: 4, 2: 4, 3: 3, 4: 3, 8: 2, 5: 1, 6: 1, 7: 1, 9: 1}) >>> total = sum(counts.values()) >>> total 20 >>> probability_mass = {k:v/total for k,v in counts.items()} >>> probability_mass {1: 0.2, 2: 0.2, 3: 0.15, 4: 0.15, 5: 0.05, 6: 0.05, 7: 0.05, 8: 0.1, 9: 0.05} >>> probability_mass.get(2,0) 0.2 >>> probability_mass.get(12,0) 0 

    Nun, für Ihre Timing-Daten, ist es natürlicher, dies als eine kontinuierliche Verteilung zu modellieren. Anstatt einen parametrischen Ansatz zu verwenden, wo Sie davon ausgehen, dass Ihre Daten eine gewisse Verteilung haben und dann diese Verteilung an Ihre Daten anpassen, sollten Sie einen nicht parametrischen Ansatz nehmen. Ein einfacher Weg ist, eine Kerndichte-Schätzung zu verwenden . Sie können einfach daran denken, als eine Möglichkeit, ein Histogramm zu glätten, um Ihnen eine kontinuierliche Wahrscheinlichkeitsdichtefunktion zu geben. Es gibt mehrere Bibliotheken zur Verfügung. Vielleicht ist das einfachste für univariate Daten scipy's:

     >>> import scipy.stats >>> kde = scipy.stats.gaussian_kde(samples) >>> kde.pdf(2) array([ 0.15086911]) 

    Um die Wahrscheinlichkeit einer Beobachtung in einem gewissen Intervall zu erhalten:

     >>> kde.integrate_box_1d(1,2) 0.13855869478828692 

    Hier ist eine mögliche Lösung. Sie zählen die Anzahl der Vorkommen jedes Wertes in der Originalliste. Die zukünftige Wahrscheinlichkeit für einen gegebenen Wert ist seine vergangene Rate des Auftretens, die einfach die Anzahl der Vergangenheit Vorkommen geteilt durch die Länge der ursprünglichen Liste ist. In Python ist es ganz einfach:

    X ist die angegebene Liste der Werte

     from collections import Counter c = Counter(x) def probability(a): # returns the probability of a given number a return float(c[a]) / len(x) 
    Python ist die beste Programmiersprache der Welt.