webentwicklung-frage-antwort-db.com.de

Berechnen Sie die kumulative Verteilungsfunktion (CDF) in Python

Wie kann ich in/Python die kumulative Verteilungsfunktion (CDF) berechnen?

Ich möchte es aus einem Array von Punkten berechnen, die ich habe (diskrete Verteilung), nicht mit den kontinuierlichen Verteilungen, die beispielsweise Scipy hat.

8
wizbcn

(Es ist möglich, dass meine Interpretation der Frage falsch ist. Wenn die Frage ist, wie man von einem diskreten PDF in ein diskretes CDF-Format gelangt, dann wird np.cumsum durch eine geeignete Konstante geteilt, wenn die Abtastwerte in einem gleichen Abstand sind. Wenn das Array nicht gleich ist, ist np.cumsum des Arrays multipliziert mit den Abständen zwischen den Punkten.) 

Wenn Sie über ein diskretes Array von Samples verfügen und die CDF des Samples kennen lernen möchten, können Sie das Array einfach sortieren. Wenn Sie das sortierte Ergebnis betrachten, werden Sie feststellen, dass der kleinste Wert 0% und der größte Wert 100% darstellt. Wenn Sie den Wert bei 50% der Verteilung erfahren möchten, schauen Sie sich das Array-Element an, das sich in der Mitte des sortierten Arrays befindet.

Lassen Sie uns dies mit einem einfachen Beispiel näher betrachten:

import matplotlib.pyplot as plt
import numpy as np

# create some randomly ddistributed data:
data = np.random.randn(10000)

# sort the data:
data_sorted = np.sort(data)

# calculate the proportional values of samples
p = 1. * arange(len(data)) / (len(data) - 1)

# plot the sorted data:
fig = figure()
ax1 = fig.add_subplot(121)
ax1.plot(p, data_sorted)
ax1.set_xlabel('$p$')
ax1.set_ylabel('$x$')

ax2 = fig.add_subplot(122)
ax2.plot(data_sorted, p)
ax2.set_xlabel('$x$')
ax2.set_ylabel('$p$')

Daraus ergibt sich das folgende Diagramm, wobei das Diagramm auf der rechten Seite die traditionelle Funktion der kumulativen Verteilung ist. Es sollte die CDF des Prozesses hinter den Punkten widerspiegeln, aber es ist natürlich nicht so lange, wie die Anzahl der Punkte endlich ist.

cumulative distribution function

Diese Funktion ist einfach zu invertieren und hängt von Ihrer Anwendung ab, welches Formular Sie benötigen.

18
DrV

Vorausgesetzt, Sie wissen, wie Ihre Daten verteilt werden (d. H. Sie kennen das PDF Ihrer Daten), dann unterstützt scipy diskrete Daten bei der Berechnung von CDFs

import numpy as np
import scipy
import matplotlib.pyplot as plt
import seaborn as sns

x = np.random.randn(10000) # generate samples from normal distribution (discrete data)
norm_cdf = scipy.stats.norm.cdf(x) # calculate the cdf - also discrete

# plot the cdf
sns.lineplot(x=x, y=norm_cdf)
plt.show()

 enter image description here

Wir können sogar die ersten Werte des Dokuments drucken, um zu zeigen, dass sie diskret sind

print(norm_cdf[:10])
>>> array([0.39216484, 0.09554546, 0.71268696, 0.5007396 , 0.76484329,
       0.37920836, 0.86010018, 0.9191937 , 0.46374527, 0.4576634 ])

Die gleiche Methode zum Berechnen des Cdf funktioniert auch für mehrere Dimensionen: Zur Veranschaulichung verwenden wir untenstehende 2D-Daten

mu = np.zeros(2) # mean vector
cov = np.array([[1,0.6],[0.6,1]]) # covariance matrix
# generate 2d normally distributed samples using 0 mean and the covariance matrix above
x = np.random.multivariate_normal(mean=mu, cov=cov, size=1000) # 1000 samples
norm_cdf = scipy.stats.norm.cdf(x)
print(norm_cdf.shape)
>>> (1000, 2)

In den obigen Beispielen wusste ich, dass meine Daten normal verteilt waren, weshalb ich scipy.stats.norm() verwendet habe - es gibt mehrere Distributionen, die scipy unterstützt. Sie müssen jedoch vorher wissen, wie Ihre Daten verteilt werden, um solche Funktionen verwenden zu können. Wenn Sie nicht wissen, wie Ihre Daten verteilt werden, und Sie nur eine Verteilung zum Berechnen des cdf verwenden, erhalten Sie höchstwahrscheinlich falsche Ergebnisse.

0
PyRsquared