Подключить эмпирическое распределение к теоретическим с помощью Scipy (Python)?

ВВЕДЕНИЕ: У меня есть список из более чем 30 000 значений от 0 до 47, например [0,0,0,0, .., 1,1,1,1, …, 2,2,2,2, …, 47 и т. Д.], Что является непрерывным распределением.

ПРОБЛЕМА: исходя из моего распределения, я хотел бы рассчитать p-значение (вероятность увидеть большие значения) для любого заданного значения. Например, поскольку вы можете видеть, что значение p для 0 будет приближаться к 1, а значение p для более высоких чисел будет стремиться к 0.

Я не знаю, прав ли я, но для определения вероятностей, я думаю, мне нужно подогнать мои данные к теоретическому распределению, которое наиболее подходит для описания моих данных. Я предполагаю, что для определения лучшей модели требуется какая-то проверка пригодности.

Есть ли способ реализовать такой анализ в Python (Scipy или Numpy)? Не могли бы вы представить какие-либо примеры?

Спасибо!

6 Solutions collect form web for “Подключить эмпирическое распределение к теоретическим с помощью Scipy (Python)?”

В SciPy 0.12.0 реализовано 82 реализованных функций распределения . Вы можете проверить, как некоторые из них соответствуют вашим данным, используя метод fit() . Проверьте приведенный ниже код:

введите описание изображения здесь

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

Рекомендации:

– Установочные распределения, добротность посадки, p-значение. Можно ли это сделать с помощью Scipy (Python)?

– Распределительная арматура с Scipy

И здесь список с именами всех функций распределения, доступных в 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'] 

Распределительная установка с суммой квадратной ошибки (SSE)

Это обновление и модификация ответа Saullo , который использует полный список текущих дистрибутивов scipy.stats и возвращает распределение с наименьшим SSE между гистограммой дистрибутива и гистограммой данных.

Пример установки

Используя набор данных El Niño из statsmodels , распределения подходят, и определяется ошибка. Возвращается распределение с наименьшей ошибкой.

Все дистрибутивы

Все установленные распределения

Лучшее соответствие

Лучшее соответствие

Пример кода

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

fit() упомянутый @Saullo Castro, дает оценки максимального правдоподобия (MLE). Лучшим распределением для ваших данных является тот, который дает вам наивысший уровень, который может быть определен несколькими различными способами: например,

1, тот, который дает вам наивысшую вероятность регистрации.

2, тот, который дает вам наименьшие значения AIC, BIC или BICc (см. Wiki: http://en.wikipedia.org/wiki/Akaike_information_criterion , в основном можно рассматривать как логарифмическое правдоподобие, скорректированное на количество параметров, так как распределение с большим количеством параметры, как ожидается, будут лучше соответствовать)

3, тот, который максимизирует байесовскую заднюю вероятность. (см. wiki: http://en.wikipedia.org/wiki/Posterior_probability )

Конечно, если у вас уже есть дистрибутив, который должен описывать ваши данные (на основе теорий в вашем конкретном поле) и вы хотите придерживаться этого, вы пропустите шаг определения наилучшего соответствия.

scipy не имеет функции для вычисления вероятности регистрации (хотя метод MLE предоставляется), но жесткий код один из них прост: см. Функции встроенной функции плотности вероятности `scipy.stat.distributions` медленнее, чем предоставленный пользователем?

AFAICU, ваше распределение дискретно (и ничего, кроме дискретного). Поэтому просто подсчитывать частоты разных значений и нормализовать их должно быть достаточно для ваших целей. Итак, пример, чтобы продемонстрировать это:

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

Таким образом, вероятность видеть значения выше 1 просто (в соответствии с дополнительной кумулятивной функцией распределения (ccdf) :

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

Обратите внимание: ccdf тесно связан с функцией выживания (sf) , но он также определяется с дискретными распределениями, тогда как sf определяется только для смежных распределений.

Это звучит как проблема оценки плотности вероятности для меня.

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

Также см. http://jpktd.blogspot.com/2009/03/using-gaussian-kernel-density.html .

Простите меня, если я не понимаю вашу потребность, но как насчет хранения ваших данных в словаре, где ключи будут числами от 0 до 47, и значения количества вхождений их связанных ключей в вашем исходном списке?
Таким образом, ваша вероятность p (x) будет представлять собой сумму всех значений для ключей, больших, чем x, деленная на 30000.

  • Эффективное заполнение разреженной матрицы SciPy из подмножества словаря
  • Получение значений, используемых в boxplot, с использованием python и matplotlib
  • Python: изменение тональности аудиофайла
  • Как уменьшить размер изображения при обработке изображений (scipy / numpy / python)
  • Написание wav-файла в Python с помощью wavfile.write от SciPy
  • Возможно ли воспроизвести randn () MATLAB с NumPy?
  • Python - быстрый способ суммирования внешних продуктов?
  • Как быстро выполнить установку наименьших квадратов по множеству наборов данных?
  •  
    Interesting Posts for Van-Lav

    SSL / концептуальные аспекты совместного использования объекта через pythons Объект DataProcess удаленно

    Почему django ORM намного медленнее, чем raw SQL

    Чтение и печать файлов Python с исключениями и окончаниями

    Как сделать эту рекурсивную функцию итеративной в python?

    Как выполнить запрос HTTP DELETE с помощью библиотеки запросов

    Python: удаление элемента в sys.path отменяется каждый раз, когда я перезапускаю интерпретатор

    Сравните результат с hexdigest () с строкой

    Записать словарь python в столбцы CSV: ключи к первому столбцу, значения для второго

    KenKen puzzle addends: REDUX A (исправленный) нерекурсивный алгоритм

    Как классифицировать новые предложения с неизвестными атрибутами?

    Django: статические файлы в шаблоне 404

    Как использовать python-openbabel в Travis CI?

    Странное поведение Pywin32 при использовании слова

    Использовать Python для написания скрипта VBA?

    Реализация Итеративной Ближайшей Точки (ICP) на python

    Python - лучший язык программирования в мире.