Raccordo distribuzione log-normale in R vs. SciPy


10

Ho montato un modello lognormale usando R con un set di dati. I parametri risultanti erano:

meanlog = 4.2991610 
sdlog = 0.5511349

Vorrei trasferire questo modello su Scipy, che non avevo mai usato prima. Usando Scipy, sono stato in grado di ottenere una forma e una scala di 1 e 3,1626716539637488e + 90 - numeri molto diversi. Ho anche provato a usare exp di meanlog e sdlog ma continuo a ottenere un grafico bizzarro.

Ho letto tutti i documenti che posso su Scipy e sono ancora confuso su cosa significano i parametri di forma e scala in questo caso. Avrebbe senso codificare la funzione da solo? Questo sembra soggetto a errori, dato che sono nuovo di Scipy.

SCIPY Lognormal (BLU) vs. R Lognormal (ROSSO): Scipy Lognormal (BLU) vs. R Lognormal (ROSSO)

Qualche idea su quale direzione prendere? I dati si adattano molto bene al modello R, a proposito, quindi se sembra qualcosa d'altro in Python, sentiti libero di condividere.

Grazie!

Aggiornare:

Sto eseguendo Scipy 0.11

Ecco un sottoinsieme dei dati. Il campione effettivo è 38k +, con una media di 81.53627:

sottoinsieme:

x
[60, 170, 137, 138, 81, 140, 78, 46, 1, 168, 138, 148, 145, 35, 82, 126, 66, 147, 88, 106, 80, 54, 83, 13, 102, 54, 134, 34]
numpy.mean (x)
99.071428571428569

In alternativa:

Sto lavorando a una funzione per acquisire il pdf:

def lognoral(x, mu, sigma):
    a = 1 / (x * sigma * numpy.sqrt(2 * numpy.pi) )
    b = - (numpy.log(x) - mu) ^ 2 / (2 * sigma ^ 2)
    p = a * numpy.exp(b)
    return p

Tuttavia, questo mi dà i seguenti numeri (ne ho provati diversi nel caso avessi confuso il significato di sdlog e meanlog):

>>> lognormal(54,4.2991610, 0.5511349)
0.6994656085799437
 >>> lognormal(54,numpy.exp(4.2991610), 0.5511349)
0.9846125119455129
>>> lognormal(54,numpy.exp(4.2991610), numpy.exp(0.5511349))
0.9302407837304372

qualche idea?

Aggiornare:

rileggere con il suggerimento "UPQuark":

forma, loc, scala (1.0, 50.03445923295007, 19.074457156766517)

La forma del grafico è molto simile, tuttavia, con il picco che si verifica intorno al 21.


Questa domanda e risposta possono aiutare: stackoverflow.com/questions/8747761/...
jbowman

Grazie, l'ho scoperto e ho imparato il "adattamento" al lognormale. Tuttavia, le mie domande sono: perché dovrei ottenere distribuzioni così diverse?
Lillian Milagros Carrasquillo,

Stai usando SciPy 0.9? Inoltre, potresti pubblicare i tuoi dati o un loro sottoinsieme?
jbowman,

Aggiornato! A proposito, è Scipy 0.11. Quindi i bug di cui ho letto non dovrebbero essere rilevanti;)
Lillian Milagros Carrasquillo

Risposte:


11

Mi sono fatto strada attraverso il codice sorgente, per arrivare alla seguente interpretazione della routine lognormale di Scipy.

xlocscaleLognormal(σ)

dove è il parametro "forma". σ

L'equivalenza tra i parametri scipy e il parametro R è la seguente:

loc - Nessun equivalente, questo viene sottratto dai tuoi dati in modo che 0 diventi l'infimo dell'intervallo di dati.

scala - , dove è la media del registro della variabile. (Quando si adatta, in genere si utilizza la media di esempio del registro dei dati.) μexpμμ

forma - la deviazione standard del registro della variabile.

Ho chiamato lognorm.pdf(x, 0.55, 0, numpy.exp(4.29))dove sono gli argomenti (x, forma, loc, scala) rispettivamente e ho generato i seguenti valori:

x pdf

10 0.000106

20 0.002275

30 0.006552

40 0.009979

50 0.114557

60 0.113479

70 0.103327

80 0.008941

90 0,007494

100 0,006155

che sembrano corrispondere abbastanza bene alla tua curva a R.


Grazie, @JBowman, questa è esattamente la spiegazione di cui avevo bisogno e l'output è precisamente la mia distribuzione.
Lillian Milagros Carrasquillo,

8

La distribuzione lognormale in SciPy si adatta al quadro generale per tutte le distribuzioni in SciPy. Tutti hanno una parola chiave scale e location (che per impostazione predefinita è 0 e 1 se non fornita in modo esplicito). Ciò consente a tutte le distribuzioni di essere spostate e ridimensionate dalle loro specifiche normalizzate con chiare implicazioni per le statistiche della distribuzione. Le distribuzioni in genere hanno anche uno o più parametri di "forma" (sebbene alcuni, come la normale distribuzione, non necessitino di parametri aggiuntivi).

Mentre questo approccio generale unifica bene tutte le distribuzioni, per lognormale può creare confusione a causa del modo in cui altri pacchetti definiscono i parametri. Tuttavia, è molto semplice abbinare qualsiasi distribuzione lognormale se intendi log (la media della distribuzione sottostante) e sdlog (la deviazione standard della distribuzione sottostante).

Innanzitutto, assicurati di impostare il parametro location su 0. Quindi, imposta il parametro shape sul valore di sdlog. Infine, imposta il parametro scale su math.exp (meanlog). Pertanto, rv = scipy.stats.lognorm (0.5511349, scale = math.exp (4.2991610)) creerà un oggetto di distribuzione il cui pdf corrisponde esattamente alla curva generata da R. Come x = numpy.linspace (0,180,1000); trama (x, rv.pdf (x)) verificherà.

Fondamentalmente, la distribuzione lognormale di SciPy è una generalizzazione della distribuzione lognormale standard che corrisponde esattamente allo standard quando si imposta il parametro location su 0.

Quando si adattano i dati con il metodo .fit, è anche possibile utilizzare parole chiave, f0..fn, floc e fshape per mantenere fissi i parametri di forma, posizione e / o scala e adattarsi solo alle altre variabili. Per la distribuzione lognormale questo è molto utile poiché di solito sai che il parametro location dovrebbe essere fissato a 0. Pertanto, scipy.stats.lognorm.fit (dataset, floc = 0) restituirà sempre il parametro location come 0 e varia solo l'altro parametri di forma e scala.


3

La vestibilità lognormale di Scipy restituisce forma, posizione e scala. Ho appena eseguito quanto segue su una serie di dati sui prezzi di esempio:

shape, loc, scale = st.lognorm.fit(d_in["price"])

Questo mi dà stime ragionevoli 1.0, 0.09, 0.86 e quando lo traccia, dovresti prendere in considerazione tutti e tre i parametri.

Il parametro shape è la deviazione standard della distribuzione normale sottostante e la scala è l'esponenziale della media della normale.

Spero che sia di aiuto.


Grazie per avermi risposto! Una volta che ho questi valori (loc, scala, forma), provo a trovare il pdf (x) per ogni x che mi interessa (qui sono valori da 0 a 180, in esclusiva). scipy.stats.lognorm.pdf (i, loc, scale, shape) Tuttavia, tracciando questi, ottengo la trama sopra.
Lillian Milagros Carrasquillo,

OK, ti ho visto menzionare solo forma e scala, ecco perché ho menzionato che ci sono tre parametri restituiti di default da fit (). Hai anche detto che sei confuso su cosa significano i parametri di forma e scala e ho cercato di risolverlo. Non ho mai avuto l'adattamento lognormale restituire valori assurdi come nel tuo caso, qual è il parametro location?
upquark

Ho appena aggiornato la domanda per rispondere. Grazie per aver pensato a questo.
Lillian Milagros Carrasquillo,

Chiama scipy.stats.lognorm.pdf (x, forma, loc, scala) invece di scipy.stats.lognorm.pdf (i, loc, scala, forma).
upquark

Grazie, upquark, l'ho fatto anch'io con risultati simili. L'intera forma del grafico continua ad essere molto diversa dai risultati attesi dando in R. Sembra una distribuzione totalmente diversa da quella in R, in realtà.
Lillian Milagros Carrasquillo,

1

Sembra che la distribuzione in Scipy per il lognormale non sia la stessa di R, o in generale, non sia la distribuzione con cui ho familiarità. John D Cook ha toccato questo: http://www.johndcook.com/blog/2010/02/03/statistical-distributions-in-scipy/ http://www.johndcook.com/distributions_scipy.html

Tuttavia, non ho trovato nulla di conclusivo su come utilizzare una funzione di densità lognormale in Python. Se qualcuno desidera aggiungere a questo, non esitate.

La mia soluzione finora è usare il pdf lognormale valutato da 0 a 180 (esclusivo) e usato come dizionario nello script python.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.