Muestra de una función de distribución en Python

Sep 11 2020

Tengo una matriz.

array([1,1,1,1,1,
1,1,1,0.96227599,0,
0,1,1,1,1,
0,0,1,0,0,
1,1,1,0,1,
1,1,0,1,0,
0,1,0,0,1,
0,0,1,1,1,
1,1,0,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,0,0,0,
1,0,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
0.94795539,0.85308765,0,0,1,
1,1,0.9113806,1,1,
1,1,1,1,1,
1,0,1,1,0,
1,1,1,1,1,
1,1,0.20363486,0.50635838,0.52025932,
0,0.34747655,0.50147493,0,0.4848249,
0,0.88495575,0,0.27620151,0.3981369,
0,0,0])

Los valores oscilan entre 0 y 1. ¿Cómo puedo graficar una función de distribución de probabilidad? Y luego llene una tabla con 1000 filas basadas en ella, donde cada fila tiene 5 columnas. De hecho, llene la tabla con muestras de 5 valores:

Respuestas

1 scleronomic Sep 11 2020 at 17:44

Para obtener un pdfde sus muestras, puede utilizar un kernel density estimator. Una opción es la gaussian_kdeforma scipy.stats.

Incluye determinación automática de ancho de banda. La estimación funciona mejor para una distribución unimodal; las distribuciones bimodales o multimodales tienden a ser demasiado suavizadas.

Sus muestras tienen un aspecto fuertemente bimodelo con clústeres en 0 y 1, por lo que le recomendamos que utilice sklearns KernelDensity. Aquí tienes más control sobre lo específico algorithm, kernely la bandwidth. Sklearn también tiene una introducción a la estimación de densidad

El flujo de trabajo con ambos métodos es bastante similar:

import numpy as np
from scipy import stats
from sklearn.neighbors import KernelDensity
import matplotlib.pyplot as plt

a = np.array([1,1,1,1,1,1,1,1,0.96227599,0,0,1,1,1,1,0,0,1,0,0,1,1,1,0,1,1,1,0,1,0,0,1,0,0,1,0,0,1,1,1,1,1,0,1,1,1,1,1,
              1,1,1,1,1,1,1,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0.94795539,0.85308765,0,0,1,1,1,0.9113806,1,1,1,1,
              1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,0.20363486,0.50635838,0.52025932,0,0.34747655,0.50147493,0,0.4848249,0,
              0.88495575,0,0.27620151,0.3981369,0,0,0])

kde1 = stats.gaussian_kde(a)
x1 = np.linspace(0, 1, 100)
y1 = kde1.pdf(x1)

kde2 = KernelDensity(bandwidth=0.1).fit(a.reshape(-1, 1))
y2 = kde2.sample(10000)

kde3 = KernelDensity(bandwidth=0.01).fit(a.reshape(-1, 1))
y3 = kde3.sample(10000)

fig, ax = plt.subplots()
ax.plot(x1, y1, c='b')
ax.hist(y2.ravel(), bins=100, density=True, color='r', alpha=0.7)
ax.hist(y3.ravel(), bins=100, density=True, color='m', alpha=0.7)

Tenga en cuenta que este método no limita su PDF en valores entre [0, 1]. Tienes que encargarte de esto tú mismo, es decir, filtrarlos en un segundo paso. Sin embargo, si elige un ancho de banda pequeño, podría acercarse bastante.


No entiendo bien la segunda parte de su pregunta. Si desea extraer nuevas muestras de la distribución estimada, puede hacerlo a través de kde.sample()(sklearn) / kde.resample()(scipy). Y llenar esos valores en una tabla es una pregunta diferente para la que definitivamente encontrará respuestas aquí en StackOverflow.