Calcular la función de distribución acumulativa (CDF) en Python

¿Cómo puedo calcular en Python la función de distribución acumulativa (CDF) ?

Quiero calcularlo a partir de una serie de puntos que tengo (distribución discreta), no con las distribuciones continuas que, por ejemplo, tiene scipy.

(Es posible que mi interpretación de la pregunta sea incorrecta. Si la pregunta es cómo pasar de un PDF discreto a un CDF discreto, entonces np.cumsum dividido por una constante adecuada funcionará si las muestras están equidistadas. Si la matriz es no equitativa, entonces np.cumsum de la matriz multiplicado por las distancias entre los puntos servirá.)

Si tiene una matriz discreta de muestras, y le gustaría conocer el CDF de la muestra, puede ordenar la matriz. Si observa el resultado ordenado, se dará cuenta de que el valor más pequeño representa el 0%, y el valor más grande representa el 100%. Si desea conocer el valor al 50% de la distribución, simplemente observe el elemento de la matriz que se encuentra en el centro de la matriz ordenada.

Veamos esto más de cerca con un ejemplo simple:

 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$') 

Esto proporciona la siguiente gráfica donde la gráfica del lado derecho es la función de distribución acumulativa tradicional. Debe reflejar el CDF del proceso detrás de los puntos, pero, naturalmente, no es así mientras el número de puntos sea finito.

función de distribución acumulativa

Esta función es fácil de invertir, y depende de su aplicación que forma usted necesita.

Suponiendo que sepa cómo se distribuyen sus datos (es decir, conoce el pdf de sus datos), entonces Scipy admite datos discretos al calcular los cdf’s

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

introduzca la descripción de la imagen aquí

Incluso podemos imprimir los primeros valores de la cdf para mostrar que son discretos

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

El mismo método para calcular el cdf también funciona para múltiples dimensiones: usamos datos 2d a continuación para ilustrar

 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) 

En los ejemplos anteriores, tenía conocimiento previo de que mis datos se distribuían normalmente, por lo que usé scipy.stats.norm() : hay múltiples distribuciones compatibles con scipy. Pero, una vez más, debe saber cómo se distribuyen sus datos de antemano para usar dichas funciones. Si no sabe cómo se distribuyen sus datos y simplemente utiliza cualquier distribución para calcular el cdf, lo más probable es que obtenga resultados incorrectos.