INTRODUCCIÓN : Tengo una lista de más de 30,000 valores enteros que van de 0 a 47, inclusive, por ejemplo, [0,0,0,0,..,1,1,1,1,...,2,2,2,2,...,47,47,47,...]
muestreados de alguna distribución continua. Los valores en la lista no están necesariamente en orden, pero el orden no importa para este problema.
PROBLEMA : Según mi distribución, me gustaría calcular el valor p (la probabilidad de ver valores mayores) para cualquier valor dado. Por ejemplo, como puede ver, el valor p para 0 se acercará a 1 y el valor p para números más altos tenderá a 0.
No sé si tengo razón, pero para determinar las probabilidades creo que necesito ajustar mis datos a una distribución teórica que sea la más adecuada para describir mis datos. Supongo que se necesita algún tipo de prueba de bondad de ajuste para determinar el mejor modelo.
¿Hay alguna manera de implementar dicho análisis en Python ( Scipy
o Numpy
)? ¿Podría presentar algún ejemplo?
¡Gracias!
fuente
Respuestas:
Ajuste de distribución con suma de error cuadrado (SSE)
Esta es una actualización y modificación de la respuesta de Saullo , que utiliza la lista completa de las
scipy.stats
distribuciones actuales y devuelve la distribución con la menor SSE entre el histograma de la distribución y el histograma de los datos.Ejemplo de montaje
Usando el conjunto de datos de El Niño de
statsmodels
, las distribuciones se ajustan y se determina el error. Se devuelve la distribución con el menor error.Todas las distribuciones
Distribución de mejor ajuste
Código de ejemplo
fuente
density=True
lugar denormed=True
ennp.histogram()
. ^^.plot()
métodos para evitar futuras confusiones. ^^from scipy.stats._continuous_distns import _distn_names
. Luego puede usar algo comogetattr(scipy.stats, distname)
para cada unodistname
en _distn_names`. Útil porque las distribuciones se actualizan con diferentes versiones de SciPy.ax = data.plot(kind='hist', bins=50, normed=True, alpha=0.5, color=list(matplotlib.rcParams['axes.prop_cycle'])[1]['color'])
Hay 82 funciones de distribución implementadas en SciPy 0.12.0 . Puede probar cómo algunos de ellos se ajustan a sus datos utilizando su
fit()
método . Consulte el código a continuación para obtener más detalles:Referencias
- Distribuciones de ajuste, bondad de ajuste, valor p. ¿Es posible hacer esto con Scipy (Python)?
- Ajuste de distribución con Scipy
Y aquí una lista con los nombres de todas las funciones de distribución disponibles en Scipy 0.12.0 (VI):
fuente
normed = True
al trazar el histograma? No te multiplicaríaspdf_fitted
por elsize
, ¿verdad?from scipy.stats._continuous_distns import _distn_names
. Luego puede usar algo comogetattr(scipy.stats, distname)
para cada unodistname
en _distn_names`. Útil porque las distribuciones se actualizan con diferentes versiones de SciPy.fit()
El método mencionado por @Saullo Castro proporciona estimaciones de máxima verosimilitud (MLE). La mejor distribución para sus datos es la que le brinda la más alta puede determinarse de varias maneras diferentes: como1, el que le brinda la mayor probabilidad de registro.
2, el que le proporciona los valores más pequeños de AIC, BIC o BICc (consulte wiki: http://en.wikipedia.org/wiki/Akaike_information_criterion , básicamente se puede ver como la probabilidad de registro ajustada por el número de parámetros, como distribución con más se espera que los parámetros se ajusten mejor)
3, el que maximiza la probabilidad posterior bayesiana. (ver wiki: http://en.wikipedia.org/wiki/Posterior_probability )
Por supuesto, si ya tiene una distribución que debería describir sus datos (en base a las teorías en su campo particular) y desea apegarse a eso, omitirá el paso de identificar la distribución de mejor ajuste.
scipy
no viene con una función para calcular la probabilidad de registro (aunque se proporciona el método MLE), pero el código uno es fácil: consulte ¿Las funciones de densidad de probabilidad incorporadas de `scipy.stat.distributions` son más lentas que las proporcionadas por el usuario?fuente
scipy
AFAICU, su distribución es discreta (y nada más que discreta). Por lo tanto, solo contar las frecuencias de diferentes valores y normalizarlos debería ser suficiente para sus propósitos. Entonces, un ejemplo para demostrar esto:
Por lo tanto, la probabilidad de ver valores más altos que
1
simplemente (de acuerdo con la función de distribución acumulativa complementaria (ccdf) :Tenga en cuenta que ccdf está estrechamente relacionado con la función de supervivencia (sf) , pero también se define con distribuciones discretas, mientras que sf se define solo para distribuciones contiguas.
fuente
A mí me parece un problema de estimación de densidad de probabilidad.
Consulte también http://jpktd.blogspot.com/2009/03/using-gaussian-kernel-density.html .
fuente
Prueba la
distfit
biblioteca.pip install distfit
Tenga en cuenta que en este caso, todos los puntos serán significativos debido a la distribución uniforme. Puede filtrar con dist.y_pred si es necesario.
fuente
Con OpenTURNS , usaría los criterios BIC para seleccionar la mejor distribución que se ajuste a dichos datos. Esto se debe a que este criterio no da demasiada ventaja a las distribuciones que tienen más parámetros. De hecho, si una distribución tiene más parámetros, es más fácil para la distribución ajustada estar más cerca de los datos. Además, el Kolmogorov-Smirnov puede no tener sentido en este caso, porque un pequeño error en los valores medidos tendrá un gran impacto en el valor p.
Para ilustrar el proceso, cargo los datos de El-Nino, que contienen 732 mediciones de temperatura mensuales desde 1950 hasta 2010:
Es fácil obtener las 30 fábricas de distribuciones univariadas incorporadas con el
GetContinuousUniVariateFactories
método estático. Una vez hecho, elBestModelBIC
método estático devuelve el mejor modelo y la puntuación BIC correspondiente.que imprime:
Para comparar gráficamente el ajuste al histograma, utilizo los
drawPDF
métodos de la mejor distribución.Esto produce:
Más detalles sobre este tema se presentan en el documento BestModelBIC . Sería posible incluir la distribución Scipy en SciPyDistribution o incluso con distribuciones ChaosPy con ChaosPyDistribution , pero supongo que el script actual cumple con la mayoría de los propósitos prácticos.
fuente
Perdóneme si no entiendo su necesidad, pero ¿qué pasa con el almacenamiento de sus datos en un diccionario donde las claves serían los números entre 0 y 47 y valora el número de apariciones de sus claves relacionadas en su lista original?
Por lo tanto, su probabilidad p (x) será la suma de todos los valores para claves mayores que x dividido por 30000.
fuente