2012-01-15 8 views
16

Próbuję uzyskać wynik dystrybucji lognormal przy użyciu Scipy. Mam już Mu i Sigmę, więc nie muszę wykonywać żadnych innych prac przygotowawczych. Jeśli potrzebuję być bardziej konkretny (i staram się być z moją ograniczoną wiedzą o statystykach), powiedziałbym, że szukam funkcji skumulowanej (cdf pod Scipy). Problem polega na tym, że nie mogę wymyślić, jak to zrobić, stosując tylko średnią i odchylenie standardowe w skali 0-1 (tzn. Zwrócona odpowiedź powinna wynosić od 0-1). Nie jestem również pewien, która metoda z dist, powinienem używać, aby uzyskać odpowiedź. Próbowałem czytać dokumentację i przeglądać SO, ale odpowiednie pytania (takie jak this i this) nie zawierały odpowiedzi, których szukałem.Jak uzyskać dystrybucję logarytmiczną w Pythonie za pomocą Mu i Sigmy?

Oto przykład kodu, z którym pracuję. Dzięki.

from scipy.stats import lognorm 
stddev = 0.859455801705594 
mean = 0.418749176686875 
total = 37 
dist = lognorm.cdf(total,mean,stddev) 

UPDATE:

Więc po trochę pracy i trochę badań, mam trochę dalej. Ale wciąż dostaję złą odpowiedź. Nowy kod znajduje się poniżej. Według R i Excela wynik powinien wynosić .7434, ale to wyraźnie nie dzieje się. Czy brakuje mi luki logicznej?

dist = lognorm([1.744],loc=2.0785) 
dist.cdf(25) # yields=0.96374596, expected=0.7434 

UPDATE 2: Praca realizacja lognorm który daje poprawny 0,7434 wynik.

def lognorm(self,x,mu=0,sigma=1): 
    a = (math.log(x) - mu)/math.sqrt(2*sigma**2) 
    p = 0.5 + 0.5*math.erf(a) 
    return p 
lognorm(25,1.744,2.0785) 
> 0.7434 
+1

mógłby pan wyjaśnić, co rozumiesz przez „w wyniku dystrybucji”? – joaquin

+0

@joaquin Dodałem próbkę kodu, która pokazuje, co mam i czego oczekuję. –

+0

@EricLubow: Myślę, że możesz być nieporozumieniem, co oznacza średnia i stddev w tym przypadku.Dla rozkładu lognormalnego są to średnie i stddev * logarytmu zmiennej *. Jeśli zmienna jest rozkładana lognormalnie, oznacza to, że logarytm zmiennej jest normalnie dystrybuowany. – talonmies

Odpowiedz

12

Wygląda na to, że chcesz utworzyć "zamrożoną" dystrybucję ze znanych parametrów. W przykładzie, można zrobić coś takiego:

from scipy.stats import lognorm 
stddev = 0.859455801705594 
mean = 0.418749176686875 
dist=lognorm([stddev],loc=mean) 

które dadzą Ci obiekt dystrybucyjny lognorm ze średniej i odchylenia standardowego można określić. Następnie można uzyskać PDF lub CDF takiego:

import numpy as np 
import pylab as pl 
x=np.linspace(0,6,200) 
pl.plot(x,dist.pdf(x)) 
pl.plot(x,dist.cdf(x)) 

lognorm cdf and pdf

Czy to, co miał na myśli?

+1

literówka: zamiast "np.inspace" musi być "np.linspace" –

+0

dzięki, naprawione. literówka po wycięciu i wklejeniu ... – talonmies

+0

czy nie powinno to być "dist = lognorm ([stddev ** 2], loc = mean)", tj. wariancja, a nie odchylenie standardowe jako parametr? Nie znalazłem specyfikacji parametrów w dokumentach scipy, czy wiesz o tym? –

21

Wiem, że jest nieco późno (prawie rok!), Ale robię pewne badania na temat funkcji lognorm w scipy.stats. Wielu ludzi wydaje się nie rozumieć parametrów wejściowych, więc mam nadzieję pomóc tym osobom. Powyższy przykład jest prawie poprawny, ale stwierdziłem, że ustawienie parametru średniego na lokalizację ("loc") jest dziwne - sygnalizuje to, że plik cdf lub pdf nie "startuje", dopóki wartość nie przekroczy wartości średniej. Również średnie i standardowe argumenty odchylenia powinny mieć formę odpowiednio exp (Ln (średnia)) i Ln (StdDev).

Mówiąc najprościej, argumenty są (x, kształt, loc, skala), z definicji parametrów poniżej:

loc - Nie równoważne, to zostaje odjęta od danych tak, 0 staje się infimum zakresu danych.

skala - exp μ, gdzie μ jest średnią logu zmiennej. (Podczas dopasowywania zazwyczaj użyjesz średniej próbki dziennika danych.)

kształt - standardowe odchylenie dziennika odmiany.

Przeżyłam tę samą frustrację, co większość osób z tą funkcją, więc udostępniam swoje rozwiązanie. Tylko uważaj, ponieważ wyjaśnienia nie są bardzo jasne bez kompendium zasobów.

Aby uzyskać więcej informacji, znalazłem te źródła pomocne:

I tutaj jest przykładem, zaczerpnięte z @ odpowiedź Serv-inc „s, napisanych na ten temat strona here:

import math 
from scipy import stats 

# standard deviation of normal distribution 
sigma = 0.859455801705594 
# mean of normal distribution 
mu = 0.418749176686875 
# hopefully, total is the value where you need the cdf 
total = 37 

frozen_lognorm = stats.lognorm(s=sigma, scale=math.exp(mu)) 
frozen_lognorm.cdf(total) # use whatever function and value you need here 
+1

Jeśli otrzymam to poprawnie: w zapisie matematycznym, jeśli X to N (mu, sigma), to Y = exp (X) to LogN (mu, sigma). Aby uzyskać X w scipy, użyłbym norm (mu, sigma), ale żeby uzyskać Y, użyłbym lognorm (sigma, 0, exp (mu)). To jest niezręczne ... –

+1

BTW: Znalazłem twój post pomocny, ale nie pomoc scipy. Dla każdej dystrybucji naprawdę musisz wypróbować, jakie znaczenie mogą mieć parametry (np. Dla rozkładu jednorodnego U (a, b), gdzie [a, b] jest przedziałem, którego potrzebujesz jednolity (loc = a, skala = ba), tutaj loc nie jest średnią, ani skalą stddev ...) –

+2

@ElmarZander: możesz użyć 'lognorm (s = sigma, scale = math.exp (mu)'. Patrz http: // stackoverflow. com/a/36714419/1587329 –

3

Jeszcze późno, ale w przypadku jest to pomocne dla nikogo innego: okazało się, że Excel

LOGNORM.DIST(x,Ln(mean),standard_dev,TRUE) 

daje takie same wyniki jak Pythona

from scipy.stats import lognorm 
lognorm.cdf(x,sigma,0,mean) 

Podobnie Excel

LOGNORM.DIST(x,Ln(mean),standard_dev,FALSE) 

wydaje równoważny do Pythona:

from scipy.stats import lognorm 
lognorm.pdf(x,sigma,0,mean). 
+0

W pierwszym przypadku nie zwracano dla mnie tego samego wyniku, gdzie x = 2039.9337873, średnia = 7.6901, std_dev = 0.6772 –

+0

Ah, zapomniałem dodać Ln (średnia) w mojej formule excel. Poprawione w odpowiedzi. – Docuemada

2

@lucas' answer ma zużycie dół pat. Jako przykład kodu, można użyć

import math 
from scipy import stats 

# standard deviation of normal distribution 
sigma = 0.859455801705594 
# mean of normal distribution 
mu = 0.418749176686875 
# hopefully, total is the value where you need the cdf 
total = 37 

frozen_lognorm = stats.lognorm(s=sigma, scale=math.exp(mu)) 
frozen_lognorm.cdf(total) # use whatever function and value you need here 
0

Jeśli czytasz to i po prostu chcą funkcji z zachowaniem podobnym do lnorm w R. dobrze, to zwalnia się od gwałtownego gniewu i używać numpy na numpy.random.lognormal.

4
from math import exp 
from scipy import stats 

def lognorm_cdf(x, mu, sigma): 
    shape = sigma 
    loc = 0 
    scale = exp(mu) 
    return stats.lognorm.cdf(x, shape, loc, scale) 

x  = 25 
mu  = 2.0785 
sigma = 1.744 
p  = lognorm_cdf(x, mu, sigma) #yields the expected 0.74341 

podobne do Excela i R, powyżej funkcja lognorm_cdf parametryzuje CDF na rozkład logarytmiczno-normalny stosując MU i sigma.

Chociaż scipy wykorzystuje kształt, loc i skala parametry scharakteryzować jego rozkład prawdopodobieństwa dla rozkładu logarytmiczno-normalny uważam, że nieco łatwiej myśleć o tych parametrów na poziomie zmiennej zamiast w dystrybucji poziom. Oto co mam na myśli ...

Log normalnego zmienna X odnosi się do normalnej zmiennej Z następująco:

X = exp(mu + sigma * Z)    #Equation 1 

który jest taki sam jak:

X = exp(mu) * exp(Z)**sigma   #Equation 2 

Można podstępnie ponownie jest napisane w następujący sposób:

X = exp(mu) * exp(Z-Z0)**sigma  #Equation 3 

gdzie Z0 = 0. To równanie ma postać:

f(x) = a * ((x-x0) ** b)   #Equation 4 

Jeśli można wizualizować równań w głowie powinno być jasne, że skala, parametry kształt i położenie w równaniu 4 są: , b i x0, odpowiednio. Oznacza to, że w równaniu 3 skala, kształt i parametry lokalizacji są następujące: exp (mu), sigma i zero, z szacunkiem.

Jeśli nie można wyobrazić, że bardzo wyraźnie, niech przepisać równanie 2 jako funkcję:

f(Z) = exp(mu) * exp(Z)**sigma  #(same as Equation 2) 

a następnie spojrzeć na skutki MU i sigma na F (z) . Poniższy rysunek ma stałą wartość i różni się mu. Powinieneś zobaczyć, że mu pionowo skali f (Z). Czyni to jednak w sposób nieliniowy; efekt zamiany mu od 0 do 1 jest mniejszy niż efekt zmiany mu z 1 na 2. Z Równania 2 widzimy, że exp (mu) jest w rzeczywistości liniowym współczynnikiem skalowania. Stąd "skala" SciPy to exp (mu).

effects_of_mu

Kolejna postać posiada MU stałe i zmienia sigma. Powinieneś zobaczyć, że zmienia się kształt f (Z). Oznacza to, że f (Z) ma stałą wartość, gdy Z = 0 Sigma wpływa na to jak szybko f (Z) zakrzywiona w stosunku do osi poziomej. Stąd "kształt" SciPy to sigma.

effects_of_sigma

+0

Troszczyć się o wyjaśnienie, dlaczego jest to odpowiedź na pytanie? – MeanGreen

+0

Zauważyłem, że to mapuje 1: 1 z funkcją Excel LOGNORM.DIST (x, Mu, Sigma, TRUE) – asdag8

Powiązane problemy