usar probabilidad normal funciones exponencial estadistica distribucion cuadrado con como chi python numpy statistics scipy distribution

probabilidad - Ajustando la distribución empírica a las teóricas con Scipy(Python)?



poisson en python (6)

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 distribuciones scipy.stats 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 ajuste

Utilizando el conjunto de datos de El Niño de los statsmodels de statsmodels , las distribuciones se ajustan y se determina el error. Se devuelve la distribución con el menor error.

Todas las distribuciones

La mejor distribución de ajuste

Código de ejemplo

%matplotlib inline import warnings import numpy as np import pandas as pd import scipy.stats as st import statsmodels as sm import matplotlib import matplotlib.pyplot as plt matplotlib.rcParams[''figure.figsize''] = (16.0, 12.0) matplotlib.style.use(''ggplot'') # Create models from data def best_fit_distribution(data, bins=200, ax=None): """Model data by finding best fit distribution to data""" # Get histogram of original data y, x = np.histogram(data, bins=bins, density=True) x = (x + np.roll(x, -1))[:-1] / 2.0 # Distributions to check DISTRIBUTIONS = [ st.alpha,st.anglit,st.arcsine,st.beta,st.betaprime,st.bradford,st.burr,st.cauchy,st.chi,st.chi2,st.cosine, st.dgamma,st.dweibull,st.erlang,st.expon,st.exponnorm,st.exponweib,st.exponpow,st.f,st.fatiguelife,st.fisk, st.foldcauchy,st.foldnorm,st.frechet_r,st.frechet_l,st.genlogistic,st.genpareto,st.gennorm,st.genexpon, st.genextreme,st.gausshyper,st.gamma,st.gengamma,st.genhalflogistic,st.gilbrat,st.gompertz,st.gumbel_r, st.gumbel_l,st.halfcauchy,st.halflogistic,st.halfnorm,st.halfgennorm,st.hypsecant,st.invgamma,st.invgauss, st.invweibull,st.johnsonsb,st.johnsonsu,st.ksone,st.kstwobign,st.laplace,st.levy,st.levy_l,st.levy_stable, st.logistic,st.loggamma,st.loglaplace,st.lognorm,st.lomax,st.maxwell,st.mielke,st.nakagami,st.ncx2,st.ncf, st.nct,st.norm,st.pareto,st.pearson3,st.powerlaw,st.powerlognorm,st.powernorm,st.rdist,st.reciprocal, st.rayleigh,st.rice,st.recipinvgauss,st.semicircular,st.t,st.triang,st.truncexpon,st.truncnorm,st.tukeylambda, st.uniform,st.vonmises,st.vonmises_line,st.wald,st.weibull_min,st.weibull_max,st.wrapcauchy ] # Best holders best_distribution = st.norm best_params = (0.0, 1.0) best_sse = np.inf # Estimate distribution parameters from data for distribution in DISTRIBUTIONS: # Try to fit the distribution try: # Ignore warnings from data that can''t be fit with warnings.catch_warnings(): warnings.filterwarnings(''ignore'') # fit dist to data params = distribution.fit(data) # Separate parts of parameters arg = params[:-2] loc = params[-2] scale = params[-1] # Calculate fitted PDF and error with fit in distribution pdf = distribution.pdf(x, loc=loc, scale=scale, *arg) sse = np.sum(np.power(y - pdf, 2.0)) # if axis pass in add to plot try: if ax: pd.Series(pdf, x).plot(ax=ax) end except Exception: pass # identify if this distribution is better if best_sse > sse > 0: best_distribution = distribution best_params = params best_sse = sse except Exception: pass return (best_distribution.name, best_params) def make_pdf(dist, params, size=10000): """Generate distributions''s Propbability Distribution Function """ # Separate parts of parameters arg = params[:-2] loc = params[-2] scale = params[-1] # Get sane start and end points of distribution start = dist.ppf(0.01, *arg, loc=loc, scale=scale) if arg else dist.ppf(0.01, loc=loc, scale=scale) end = dist.ppf(0.99, *arg, loc=loc, scale=scale) if arg else dist.ppf(0.99, loc=loc, scale=scale) # Build PDF and turn into pandas Series x = np.linspace(start, end, size) y = dist.pdf(x, loc=loc, scale=scale, *arg) pdf = pd.Series(y, x) return pdf # Load data from statsmodels datasets data = pd.Series(sm.datasets.elnino.load_pandas().data.set_index(''YEAR'').values.ravel()) # Plot for comparison plt.figure(figsize=(12,8)) ax = data.plot(kind=''hist'', bins=50, normed=True, alpha=0.5, color=plt.rcParams[''axes.color_cycle''][1]) # Save plot limits dataYLim = ax.get_ylim() # Find best fit distribution best_fit_name, best_fir_paramms = best_fit_distribution(data, 200, ax) best_dist = getattr(st, best_fit_name) # Update plots ax.set_ylim(dataYLim) ax.set_title(u''El Niño sea temp./n All Fitted Distributions'') ax.set_xlabel(u''Temp (°C)'') ax.set_ylabel(''Frequency'') # Make PDF pdf = make_pdf(best_dist, best_fir_paramms) # Display plt.figure(figsize=(12,8)) ax = pdf.plot(lw=2, label=''PDF'', legend=True) data.plot(kind=''hist'', bins=50, normed=True, alpha=0.5, label=''Data'', legend=True, ax=ax) param_names = (best_dist.shapes + '', loc, scale'').split('', '') if best_dist.shapes else [''loc'', ''scale''] param_str = '', ''.join([''{}={:0.2f}''.format(k,v) for k,v in zip(param_names, best_fir_paramms)]) dist_str = ''{}({})''.format(best_fit_name, param_str) ax.set_title(u''El Niño sea temp. with best fit distribution /n'' + dist_str) ax.set_xlabel(u''Temp. (°C)'') ax.set_ylabel(''Frequency'')

INTRODUCCIÓN: Tengo una lista de más de 30 000 valores que van de 0 a 47, por ejemplo [0,0,0,0, .., 1,1,1,1, ..., 2,2,2,2, ..., 47 etc.] que es la distribución continua.

PROBLEMA: De acuerdo con 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 a 1 y el valor p para números más altos tendrían tendencia a 0.

No sé si estoy en lo correcto, 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 forma de implementar dicho análisis en Python (Scipy o Numpy)? ¿Podría presentar algún ejemplo?

¡Gracias!


AFAICU, tu distribución es discreta (y nada discreta). Por lo tanto, basta con contar las frecuencias de diferentes valores y normalizarlos para sus propósitos. Entonces, un ejemplo para demostrar esto:

In []: values= [0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 4] In []: counts= asarray(bincount(values), dtype= float) In []: cdf= counts.cumsum()/ counts.sum()

Por lo tanto, la probabilidad de ver valores superiores a 1 es simplemente (de acuerdo con la función de distribución acumulativa complementaria (ccdf) :

In []: 1- cdf[1] Out[]: 0.40000000000000002

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.


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 el número de ocurrencias 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.


Suena como un problema de estimación de densidad de probabilidad para mí.

from scipy.stats import gaussian_kde occurences = [0,0,0,0,..,1,1,1,1,...,2,2,2,2,...,47] values = range(0,48) kde = gaussian_kde(map(float, occurences)) p = kde(values) p = p/sum(p) print "P(x>=1) = %f" % sum(p[1:])

También vea http://jpktd.blogspot.com/2009/03/using-gaussian-kernel-density.html .


fit() método fit() mencionado por @Saullo Castro proporciona estimaciones de máxima verosimilitud (MLE). La mejor distribución para sus datos es la que le proporciona la más alta que puede determinarse de varias maneras diferentes: como

1, el que te da la mayor probabilidad de registro.

2, el que te da los valores más pequeños de AIC, BIC o BICc (ver wiki: http://en.wikipedia.org/wiki/Akaike_information_criterion , básicamente se puede ver como log likelihood ajustado por el número de parámetros, como la 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 debe describir sus datos (según las teorías en su campo particular) y desea apegarse a eso, omitirá el paso de identificar la mejor distribución de ajuste.

scipy no viene con una función para calcular la verosimilitud de registro (aunque se proporciona el método MLE), pero el código difícil uno es fácil: ver ¿Las funciones de densidad de probabilidad incorporadas de `scipy.stat.distributions` son más lentas que las proporcionadas por el usuario?


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 método fit() . Verifique el código a continuación para obtener más detalles:

import matplotlib.pyplot as plt import scipy import scipy.stats size = 30000 x = scipy.arange(size) y = scipy.int_(scipy.round_(scipy.stats.vonmises.rvs(5,size=size)*47)) h = plt.hist(y, bins=range(48), color=''w'') dist_names = [''gamma'', ''beta'', ''rayleigh'', ''norm'', ''pareto''] for dist_name in dist_names: dist = getattr(scipy.stats, dist_name) param = dist.fit(y) pdf_fitted = dist.pdf(x, *param[:-2], loc=param[-2], scale=param[-1]) * size plt.plot(pdf_fitted, label=dist_name) plt.xlim(0,47) plt.legend(loc=''upper right'') plt.show()

Referencias

- Distribuciones ajustadas, 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):

dist_names = [ ''alpha'', ''anglit'', ''arcsine'', ''beta'', ''betaprime'', ''bradford'', ''burr'', ''cauchy'', ''chi'', ''chi2'', ''cosine'', ''dgamma'', ''dweibull'', ''erlang'', ''expon'', ''exponweib'', ''exponpow'', ''f'', ''fatiguelife'', ''fisk'', ''foldcauchy'', ''foldnorm'', ''frechet_r'', ''frechet_l'', ''genlogistic'', ''genpareto'', ''genexpon'', ''genextreme'', ''gausshyper'', ''gamma'', ''gengamma'', ''genhalflogistic'', ''gilbrat'', ''gompertz'', ''gumbel_r'', ''gumbel_l'', ''halfcauchy'', ''halflogistic'', ''halfnorm'', ''hypsecant'', ''invgamma'', ''invgauss'', ''invweibull'', ''johnsonsb'', ''johnsonsu'', ''ksone'', ''kstwobign'', ''laplace'', ''logistic'', ''loggamma'', ''loglaplace'', ''lognorm'', ''lomax'', ''maxwell'', ''mielke'', ''nakagami'', ''ncx2'', ''ncf'', ''nct'', ''norm'', ''pareto'', ''pearson3'', ''powerlaw'', ''powerlognorm'', ''powernorm'', ''rdist'', ''reciprocal'', ''rayleigh'', ''rice'', ''recipinvgauss'', ''semicircular'', ''t'', ''triang'', ''truncexpon'', ''truncnorm'', ''tukeylambda'', ''uniform'', ''vonmises'', ''wald'', ''weibull_min'', ''weibull_max'', ''wrapcauchy'']