INTRODUÇÃO : Eu tenho uma lista de mais de 30.000 valores inteiros variando de 0 a 47, inclusive, por exemplo, [0,0,0,0,..,1,1,1,1,...,2,2,2,2,...,47,47,47,...]
amostras de alguma distribuição contínua. Os valores na lista não estão necessariamente em ordem, mas a ordem não importa para esse problema.
PROBLEMA : Com base na minha distribuição, gostaria de calcular o valor-p (a probabilidade de ver valores maiores) para qualquer valor. Por exemplo, como você pode ver, o valor de p para 0 se aproximaria de 1 e o valor de p para números mais altos tenderia a 0.
Não sei se estou certo, mas para determinar as probabilidades, acho que preciso ajustar meus dados a uma distribuição teórica mais adequada para descrever meus dados. Suponho que seja necessário algum tipo de teste de qualidade do ajuste para determinar o melhor modelo.
Existe uma maneira de implementar essa análise em Python ( Scipy
ou Numpy
)? Você poderia apresentar algum exemplo?
Obrigado!
fonte
Respostas:
Ajuste de distribuição com erro de soma do quadrado (SSE)
Esta é uma atualização e modificação da resposta de Saullo , que usa a lista completa das
scipy.stats
distribuições atuais e retorna a distribuição com o menor SSE entre o histograma da distribuição e o histograma dos dados.Exemplo de ajuste
Usando o conjunto de dados El Niño de
statsmodels
, as distribuições são adequadas e o erro é determinado. A distribuição com o menor erro é retornada.Todas as distribuições
Distribuição Best Fit
Código de exemplo
fonte
density=True
vez denormed=True
emnp.histogram()
. ^^.plot()
métodos para evitar futuras confusões. ^^from scipy.stats._continuous_distns import _distn_names
. Você pode usar algo comogetattr(scipy.stats, distname)
para cada umdistname
em _distn_names`. Útil porque as distribuições são atualizadas com diferentes versões do SciPy.ax = data.plot(kind='hist', bins=50, normed=True, alpha=0.5, color=list(matplotlib.rcParams['axes.prop_cycle'])[1]['color'])
Existem 82 funções de distribuição implementadas no SciPy 0.12.0 . Você pode testar como alguns deles se ajustam aos seus dados usando o
fit()
método deles . Verifique o código abaixo para obter mais detalhes:Referências:
- Distribuições apropriadas, qualidade de ajuste, valor de p. É possível fazer isso com o Scipy (Python)?
- Acessório de distribuição com Scipy
E aqui uma lista com os nomes de todas as funções de distribuição disponíveis no Scipy 0.12.0 (VI):
fonte
normed = True
na plotagem do histograma? Você não multiplicariapdf_fitted
pelosize
, certo?from scipy.stats._continuous_distns import _distn_names
. Você pode usar algo comogetattr(scipy.stats, distname)
para cada umdistname
em _distn_names`. Útil porque as distribuições são atualizadas com diferentes versões do SciPy.fit()
O método mencionado por @Saullo Castro fornece estimativas de máxima verossimilhança (MLE). A melhor distribuição para os seus dados é aquela que lhe dá o mais alto, podendo ser determinada de várias maneiras diferentes: como1, o que oferece a maior probabilidade de log.
2, o que fornece os menores valores de AIC, BIC ou BICc (consulte o wiki: http://en.wikipedia.org/wiki/Akaike_information_criterion , basicamente pode ser visto como uma probabilidade de log ajustada para o número de parâmetros, como distribuição com mais espera-se que os parâmetros se ajustem melhor)
3, aquele que maximiza a probabilidade posterior bayesiana. (consulte o wiki: http://en.wikipedia.org/wiki/Posterior_probability )
Obviamente, se você já possui uma distribuição que deve descrever seus dados (com base nas teorias de seu campo específico) e deseja se manter fiel a isso, pulará a etapa de identificação da distribuição de melhor ajuste.
scipy
não vem com uma função para calcular a probabilidade do log (embora o método MLE seja fornecido), mas o código rígido é fácil: consulte As funções de densidade de probabilidade incorporadas do `scipy.stat.distributions` são mais lentas que as fornecidas pelo usuário?fonte
scipy
AFAICU, sua distribuição é discreta (e nada além de discreta). Portanto, apenas contar as frequências de valores diferentes e normalizá-los deve ser suficiente para seus propósitos. Então, um exemplo para demonstrar isso:
Assim, a probabilidade de ver valores maiores do que
1
é simplesmente (de acordo com a função de distribuição cumulativa complementar (ccdf) :Observe que o ccdf está intimamente relacionado à função de sobrevivência (sf) , mas também é definido com distribuições discretas, enquanto o sf é definido apenas para distribuições contíguas.
fonte
Parece-me um problema de estimativa de densidade de probabilidade.
Consulte também http://jpktd.blogspot.com/2009/03/using-gaussian-kernel-density.html .
fonte
Experimente a
distfit
biblioteca.pip install distfit
Observe que, neste caso, todos os pontos serão significativos devido à distribuição uniforme. Você pode filtrar com o dist.y_pred, se necessário.
fonte
Com o OpenTURNS , eu usaria os critérios da BIC para selecionar a melhor distribuição que se encaixa nesses dados. Isso ocorre porque esse critério não oferece muitas vantagens às distribuições que possuem mais parâmetros. De fato, se uma distribuição tiver mais parâmetros, é mais fácil para a distribuição ajustada estar mais próxima dos dados. Além disso, o Kolmogorov-Smirnov pode não fazer sentido neste caso, porque um pequeno erro nos valores medidos terá um enorme impacto no valor-p.
Para ilustrar o processo, carrego os dados do El-Nino, que contêm 732 medições mensais de temperatura de 1950 a 2010:
É fácil obter as 30 fábricas de distribuição univariadas internas com o
GetContinuousUniVariateFactories
método estático. Uma vez feito, oBestModelBIC
método estático retorna o melhor modelo e a pontuação BIC correspondente.que imprime:
Para comparar graficamente o ajuste ao histograma, uso os
drawPDF
métodos da melhor distribuição.Isso produz:
Mais detalhes sobre este tópico são apresentados no documento BestModelBIC . Seria possível incluir a distribuição Scipy na SciPyDistribution ou mesmo com as distribuições ChaosPy com ChaosPyDistribution , mas acho que o script atual cumpre os objetivos mais práticos.
fonte
Perdoe-me se eu não entender sua necessidade, mas e quanto a armazenar seus dados em um dicionário em que as chaves seriam os números entre 0 e 47 e valorizem o número de ocorrências de suas chaves relacionadas na sua lista original?
Assim, sua probabilidade p (x) será a soma de todos os valores para chaves maiores que x divididos por 30000.
fonte