Zdefiniuj niestandardową funkcję gęstości prawdopodobieństwa w Pythonie

20

Czy jest jakiś sposób, używając jakiegoś ustalonego pakietu Pythona (np. SciPy) do zdefiniowania mojej własnej funkcji gęstości prawdopodobieństwa (bez żadnych wcześniejszych danych, po prostu ), więc mogę następnie wykonać z nim obliczenia (takie jak uzyskanie wariancja ciągłej zmiennej losowej)? Oczywiście mógłbym wziąć, powiedzmy, SymPy lub Sage, stworzyć funkcję symboliczną i wykonać operacje, ale zastanawiam się, czy zamiast wykonywać całą tę pracę sam, mogę skorzystać z już zaimplementowanego pakietu.f(x)=ax+b

astrojuanlu
źródło
Dzięki za łatwy sposób! Jak wygenerować histogram liczb losowych, realizując ten sposób definiowania niestandardowej funkcji dystrybucji?
Ankur Agrawal

Odpowiedzi:

23

Musisz podklasować klasę rv_continuous w 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')

teraz my_cv jest ciągłą zmienną losową o podanym pliku PDF i zakresie [0,1]

Należy zauważyć, że w tym przykładzie my_pdfi my_cvsą dowolnymi nazwami (to mogło być cokolwiek), ale _pdfto nie arbitralne; i _cdfsą to metody, st.rv_continuousz których jedna musi zostać nadpisana, aby podklasa działała.

GertVdE
źródło
@GertVdE: Co robi „self” w def _pdf?
Srivatsan
@Srivatsan: zobacz odpowiedź na temat Przepełnienia stosu
GertVdE
Występuje problem z normalizacją tutaj: musisz podać znormalizowaną funkcję rozkładu prawdopodobieństwa ( 3*x**2tutaj), lub wynikowa zmienna losowa daje nieprawidłowe wyniki (możesz my_cv.median()na przykład sprawdzić ). Naprawiłem kod.
Eric O Lebigot,
@EOL Uważam, że użycie terminu „znormalizowany” jest mylące. wierzę, że potrzebna jest funkcja wyśrodkowana na 0 i skalowana do 1. ale ta odpowiedź wydaje się sugerować, że normalizacja musi być powyżej zakresu x[0, 1]. możesz wyjaśnić?
dbliss
1
Być może standardowym sposobem jest użycie my_cv.rvs()(co może wymagać sizeargumentu, aby uzyskać wiele próbek za jednym razem). Tak sądzę z dokumentacji ( docs.scipy.org/doc/scipy/reference/generated/... ).
Eric O Lebigot
15

Powinieneś sprawdzić sympy.stats. Zapewnia interfejs do obsługi zmiennych losowych. Poniższy przykład przedstawia losową zmienną Xzdefiniowaną w interwale jednostkowym o gęstości2x

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)

Jeśli jesteś zainteresowany, ta abstrakcja poradzi sobie z dość złożonymi manipulacjami.

MRocklin
źródło
Wow ... to jest po prostu niesamowite! Dziękuję bardzo za ten wkład. Będę
pilnował