Definir função de densidade de probabilidade personalizada em Python


20

Existe uma maneira de usar algum pacote Python estabelecido (por exemplo, SciPy) para definir minha própria função de densidade de probabilidade (sem dados anteriores, apenas ), para que eu possa fazer cálculos com ele (como obter a variância da variável aleatória contínua)? É claro que eu poderia, digamos, SymPy ou Sage, criar uma função simbólica e executar as operações, mas estou pensando se, em vez de fazer todo esse trabalho, posso usar um pacote já implementado.f(x)=umax+b


Obrigado por uma maneira fácil! Como você gera um histograma de números aleatórios implementando essa maneira de definir a função de distribuição personalizada?
Ankur Agrawal

Respostas:


23

Você tem que subclasse o rv_continuous classe em scipy.stats

import scipy.stats as st

class my_pdf(st.rv_continuous):
    def _pdf(self,x):
        return 3*x**2  # Normalized over its range, in this case [0,1]

my_cv = my_pdf(a=0, b=1, name='my_pdf')

agora my_cv é uma variável aleatória contínua com o PDF fornecido e o intervalo [0,1]

Note-se que, neste exemplo, my_pdfe my_cvsão nomes arbitrários (que poderia ter sido qualquer coisa), mas _pdfé não arbitrária; e _cdfsão métodos em st.rv_continuousum dos quais deve ser substituído para que a subclasse funcione.


@GertVdE: O que "self" em def _pdf faz?
precisa


Há um problema com a normalização, aqui: você precisa fornecer uma função de distribuição de probabilidade normalizada ( 3*x**2, aqui) ou a variável aleatória resultante produz resultados incorretos (você pode verificar my_cv.median(), por exemplo). Eu consertei o código.
Eric O Lebigot

@EOL Estou achando confuso o uso do termo "normalizado". o que é necessário, acredito, é que a função seja centrada em 0 e redimensionada para 1. mas essa resposta parece implicar que a normalização precisa estar acima do intervalo de x[0, 1]. você pode esclarecer?
dbliss

1
Talvez a maneira padrão seja usar my_cv.rvs()(o que pode levar um sizeargumento, para obter várias amostras de uma só vez). Acho que é isso da documentação ( docs.scipy.org/doc/scipy/reference/generated/… ).
Eric O Lebigot

15

Você deve verificar o sympy.stats. Ele fornece uma interface para lidar com variáveis ​​aleatórias. O exemplo a seguir fornece uma variável aleatória Xdefinida no intervalo da unidade com densidade2x

In [1]: from sympy.stats import *
In [2]: x = Symbol('x')
In [3]: X = ContinuousRV(x, 2*x, Interval(0, 1))

In [4]: P(X>.5) 
Out[4]: 0.750000000000000

In [5]: Var(X) # variance
Out[5]: 1/18

In [6]: E(2*cos(X)+X**2) # complex expressions are ok too
Out[6]: -7/2 + 4cos(1) + 4sin(1)

Se você estiver interessado, essa abstração pode lidar com algumas manipulações bastante complexas.


Uau ... isso é incrível! Muito obrigado por esta contribuição. Eu vou manter um olho sobre este e seu blog
astrojuanlu
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.