Anpassen der logarithmischen Normalverteilung in R vs. SciPy

10

Ich habe ein logarithmisches Normalmodell mit R mit einem Datensatz versehen. Die resultierenden Parameter waren:

meanlog = 4.2991610 
sdlog = 0.5511349

Ich möchte dieses Modell auf Scipy übertragen, das ich noch nie benutzt habe. Mit Scipy konnte ich eine Form und einen Maßstab von 1 und 3.1626716539637488e + 90 erhalten - sehr unterschiedliche Zahlen. Ich habe auch versucht, die exp von meanlog und sdlog zu verwenden, aber weiterhin bizarre Diagramme zu erhalten.

Ich habe jedes Dokument gelesen, das ich auf scipy lesen kann, und bin immer noch verwirrt darüber, was die Form- und Skalierungsparameter in diesem Fall bedeuten. Wäre es nur sinnvoll, die Funktion selbst zu codieren? Das scheint allerdings fehleranfällig zu sein, da ich neu bei scipy bin.

SCIPY Lognormal (BLAU) vs. R Lognormal (ROT): Scipy Lognormal (BLAU) vs. R Lognormal (ROT)

Irgendwelche Gedanken darüber, in welche Richtung es gehen soll? Die Daten passen übrigens sehr gut zum R-Modell. Wenn es also wie etwas anderes in Python aussieht, können Sie es gerne teilen.

Vielen Dank!

Aktualisieren:

Ich verwende Scipy 0.11

Hier ist eine Teilmenge der Daten. Die tatsächliche Stichprobe beträgt 38.000 + mit einem Mittelwert von 81,53627:

Teilmenge:

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

Alternative:

Ich arbeite an einer Funktion zum Erfassen des 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

Dies gibt mir jedoch die folgenden Zahlen (ich habe mehrere ausprobiert, falls ich die Bedeutung von sdlog und meanlog verwechselt habe):

>>> 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

Irgendwelche Gedanken?

Aktualisieren:

Wiederholung mit "UPQuarks" Vorschlag:

Form, Ort, Maßstab (1,0, 50,03445923295007, 19,074457156766517)

Die Form des Diagramms ist jedoch sehr ähnlich, wobei der Peak um 21 herum auftritt.

Lillian Milagros Carrasquillo
quelle
Diese Frage und Antwort kann helfen: stackoverflow.com/questions/8747761/…
jbowman
Danke, ich habe das gefunden und die "Anpassung" an das Lognormal gelernt. Meine Frage ist jedoch, warum ich so unterschiedliche Distributionen bekommen sollte.
Lillian Milagros Carrasquillo
Verwenden Sie SciPy 0.9? Könnten Sie auch Ihre Daten oder eine Teilmenge davon veröffentlichen?
Jbowman
Aktualisiert! Es ist übrigens Scipy 0.11. Die Fehler, über die ich gelesen habe, sollten also nicht relevant sein;)
Lillian Milagros Carrasquillo

Antworten:

11

Ich kämpfte mich durch den Quellcode, um zu der folgenden Interpretation der scipy lognormalen Routine zu gelangen.

xlocscaleLognormal(σ)

σ

Die Äquivalenz zwischen scipy-Parametern und R-Parametern ist wie folgt:

loc - Kein Äquivalent, dies wird von Ihren Daten subtrahiert, so dass 0 das Infimum des Datenbereichs wird.

expμμ

Form - die Standardabweichung des Protokolls der Variablen.

Ich habe angerufen, lognorm.pdf(x, 0.55, 0, numpy.exp(4.29))wo sich die Argumente befinden (x, Form, Ort, Skalierung), und die folgenden Werte generiert:

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

die scheinen ziemlich gut mit Ihrer R-Kurve zu passen.

jbowman
quelle
Vielen Dank, @JBowman, das ist genau die Erklärung, die ich brauchte, und die Ausgabe ist genau meine Verteilung.
Lillian Milagros Carrasquillo
8

Die logarithmische Normalverteilung in SciPy passt zum allgemeinen Rahmen für alle Verteilungen in SciPy. Sie haben alle ein Schlüsselwort für Skalierung und Standort (standardmäßig 0 und 1, wenn nicht explizit angegeben). Dadurch können alle Verteilungen von ihrer normalisierten Spezifikation verschoben und skaliert werden, was eindeutige Auswirkungen auf die Statistik der Verteilung hat. Die Verteilungen haben normalerweise auch einen oder mehrere "Form" -Parameter (obwohl einige, wie die Normalverteilung, keine zusätzlichen Parameter benötigen).

Während dieser allgemeine Ansatz alle Verteilungen gut vereinheitlicht , kann er für lognormal aufgrund der Art und Weise, wie andere Pakete die Parameter definieren, Verwirrung stiften. Es ist jedoch sehr einfach, eine logarithmische Normalverteilung abzugleichen, wenn Sie meanlog (den Mittelwert der zugrunde liegenden Verteilung) und sdlog (die Standardabweichung der zugrunde liegenden Verteilung) verwenden.

Stellen Sie zunächst sicher, dass Sie den Standortparameter auf 0 setzen. Setzen Sie dann den Formparameter auf den Wert von sdlog. Schließlich setzen Sie den Parameter scale auf math.exp (meanlog). Daher erstellt rv = scipy.stats.lognorm (0.5511349, scale = math.exp (4.2991610)) ein Verteilungsobjekt, dessen PDF genau mit Ihrer R-generierten Kurve übereinstimmt. As x = numpy.linspace (0,180,1000); Der Plot (x, rv.pdf (x)) wird überprüft.

Grundsätzlich ist die SciPy-Lognormalverteilung eine Verallgemeinerung der Standard-Lognormalverteilung, die genau mit dem Standard übereinstimmt, wenn der Standortparameter auf 0 gesetzt wird.

Wenn Sie Daten mit der .fit-Methode anpassen, können Sie auch die Schlüsselwörter f0..fn, floc und fshape verwenden, um die Parameter für Form, Position und / oder Skalierung festzuhalten und nur über die anderen Variablen anzupassen. Für die logarithmische Normalverteilung ist dies sehr nützlich, da Sie normalerweise wissen, dass der Standortparameter auf 0 festgelegt werden sollte. Daher gibt scipy.stats.lognorm.fit (Datensatz, floc = 0) den Standortparameter immer als 0 zurück und variiert nur den anderen Form- und Skalenparameter.

Travis Oliphant
quelle
3

Scipy lognormal fit gibt Form, Position und Skalierung zurück. Ich habe gerade Folgendes für eine Reihe von Beispielpreisdaten ausgeführt:

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

Dies gibt mir vernünftige Schätzungen von 1,0, 0,09, 0,86, und wenn Sie es zeichnen, sollten Sie alle drei Parameter berücksichtigen.

Der Formparameter ist die Standardabweichung der zugrunde liegenden Normalverteilung, und die Skala ist das Exponential des Mittelwerts der Normalverteilung.

Hoffe das hilft.

upquark
quelle
Vielen Dank für Ihre Antwort! Sobald ich diese Werte (loc, scale, shape) habe, versuche ich, das PDF (x) für jedes x zu finden, das mir wichtig ist (hier sind es Werte von 0 bis 180, exklusiv). scipy.stats.lognorm.pdf (i, loc, scale, shape) Wenn ich diese jedoch zeichne, erhalte ich die obige Darstellung.
Lillian Milagros Carrasquillo
OK, ich habe gesehen, dass Sie nur Form und Skalierung erwähnt haben. Deshalb habe ich erwähnt, dass standardmäßig drei Parameter von fit () zurückgegeben werden. Sie sagten auch, Sie seien verwirrt darüber, was die Form- und Skalierungsparameter bedeuten, und ich habe versucht, dies zu beheben. Ich hatte noch nie absurde Werte für die logarithmische Anpassung, wie in Ihrem Fall. Was ist der Standortparameter?
Upquark
Ich habe gerade die Frage aktualisiert, um das zu beantworten. Danke, dass Sie darüber nachgedacht haben.
Lillian Milagros Carrasquillo
Rufen Sie scipy.stats.lognorm.pdf (x, Form, Ort, Maßstab) anstelle von scipy.stats.lognorm.pdf (i, Ort, Maßstab, Form) auf.
Upquark
Danke, upquark, das habe ich auch mit ähnlichen Ergebnissen gemacht. Die gesamte Form des Diagramms unterscheidet sich weiterhin stark von den erwarteten Ergebnissen in R. Sieht nach einer völlig anderen Verteilung aus als die in R.
Lillian Milagros Carrasquillo
1

Es scheint, dass die Verteilung in Scipy für das Lognormal nicht dieselbe ist wie in R oder im Allgemeinen nicht dieselbe wie die Verteilung, mit der ich vertraut bin. John D Cook hat dies angesprochen: http://www.johndcook.com/blog/2010/02/03/statistical-distributions-in-scipy/ http://www.johndcook.com/distributions_scipy.html

Ich habe jedoch keine schlüssigen Informationen zur Verwendung einer lognormalen Dichtefunktion in Python gefunden. Wenn jemand etwas hinzufügen möchte, zögern Sie nicht.

Meine bisherige Lösung besteht darin, das lognormale PDF zu verwenden, das mit 0 bis 180 (exklusiv) ausgewertet und als Wörterbuch im Python-Skript verwendet wird.

Lillian Milagros Carrasquillo
quelle