J'ai adapté un modèle lognormal utilisant R avec un ensemble de données. Les paramètres résultants étaient:
meanlog = 4.2991610
sdlog = 0.5511349
J'aimerais transférer ce modèle sur Scipy, que je n'ai jamais utilisé auparavant. En utilisant Scipy, j'ai pu obtenir une forme et une échelle de 1 et 3,1626716539637488e + 90 - des nombres très différents. J'ai également essayé d'utiliser l'exp du meanlog et du sdlog mais continue à obtenir un graphique bizarre.
J'ai lu tous les documents que je peux sur scipy et je suis toujours confus quant à la signification des paramètres de forme et d'échelle dans ce cas. Serait-il juste logique de coder la fonction moi-même? Cela semble cependant sujet à des erreurs, car je suis nouveau sur scipy.
SCIPY Lognormal (BLUE) contre R Lognormal (RED):
Avez-vous des idées sur la direction à prendre? Les données sont très bien adaptées au modèle R, d'ailleurs, si elles ressemblent à quelque chose d'autre en Python, n'hésitez pas à les partager.
Je vous remercie!
Mettre à jour:
Je lance Scipy 0.11
Voici un sous-ensemble des données. L'échantillon réel est de 38k +, avec une moyenne de 81,53627:
Sous-ensemble:
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
Alternativement:
Je travaille sur une fonction pour capturer le 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
Cependant, cela me donne les chiffres suivants (j'en ai essayé plusieurs au cas où j'aurais mélangé le sens de sdlog et 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
Des pensées?
Mettre à jour:
relance avec la suggestion "UPQuark":
forme, loc, échelle (1.0, 50.03445923295007, 19.074457156766517)
La forme du graphique est cependant très similaire, le pic se situant autour de 21.
Réponses:
Je me suis frayé un chemin à travers le code source, pour arriver à l'interprétation suivante de la routine lognormale scipy.
où est le paramètre "forme".σ
L'équivalence entre les paramètres scipy et le paramètre R est la suivante:
loc - Aucun équivalent, cela est soustrait de vos données afin que 0 devienne l'infimum de la plage des données.
échelle - , où est la moyenne du log de la variable. (Lors de l'ajustement, vous utilisez généralement la moyenne de l'échantillon du journal des données.) μexpμ μ
forme - l'écart type du logarithme de la variable.
J'ai appelé
lognorm.pdf(x, 0.55, 0, numpy.exp(4.29))
où les arguments sont (x, forme, loc, échelle) respectivement, et généré les valeurs suivantes: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
qui semblent correspondre assez bien à votre courbe R.
la source
La distribution lognormale dans SciPy s'inscrit dans le cadre général de toutes les distributions dans SciPy. Ils ont tous un mot-clé d'échelle et d'emplacement (par défaut 0 et 1 s'ils ne sont pas explicitement fournis). Cela permet à toutes les distributions d'être déplacées et mises à l'échelle de leur spécification normalisée avec des implications claires pour les statistiques de la distribution. Les distributions ont généralement aussi un ou plusieurs paramètres de "forme" (bien que certains, comme la distribution normale, n'aient pas besoin de paramètres supplémentaires).
Bien que cette approche générale unifie bien toutes les distributions, pour lognormal, elle peut créer une certaine confusion en raison de la façon dont d'autres packages définissent les paramètres. Pourtant, il est très simple de faire correspondre n'importe quelle distribution lognormale si vous voulez direlog (la moyenne de la distribution sous-jacente) et sdlog (l'écart-type de la distribution sous-jacente).
Tout d'abord, assurez-vous de définir le paramètre d'emplacement sur 0. Ensuite, définissez le paramètre de forme sur la valeur de sdlog. Enfin, définissez le paramètre d'échelle sur math.exp (meanlog). Ainsi, rv = scipy.stats.lognorm (0.5511349, scale = math.exp (4.2991610)) créera un objet de distribution dont le pdf correspond exactement à votre courbe générée par R. Comme x = numpy.linspace (0,180,1000); plot (x, rv.pdf (x)) vérifiera.
Fondamentalement, la distribution lognormale de SciPy est une généralisation de la distribution lognormale standard qui correspond exactement à la norme lors de la définition du paramètre d'emplacement sur 0.
Lorsque vous ajustez des données avec la méthode .fit, vous pouvez également utiliser des mots clés, f0..fn, floc et fshape pour maintenir fixe l'un des paramètres de forme, d'emplacement et / ou d'échelle et ne tenir que sur les autres variables. Pour la distribution lognormale, cela est très utile car généralement vous savez que le paramètre d'emplacement doit être fixé à 0. Ainsi, scipy.stats.lognorm.fit (jeu de données, floc = 0) renverra toujours le paramètre d'emplacement à 0 et ne fera varier que l'autre paramètres de forme et d'échelle.
la source
L'ajustement log-normal Scipy renvoie la forme, l'emplacement et l'échelle. Je viens d'exécuter ce qui suit sur un tableau d'exemples de données de prix:
Cela me donne des estimations raisonnables de 1,0, 0,09, 0,86, et lorsque vous le tracez, vous devez prendre en compte les trois paramètres.
Le paramètre de forme est l'écart-type de la distribution normale sous-jacente, et l'échelle est l'exponentielle de la moyenne de la normale.
J'espère que cela t'aides.
la source
On dirait que la distribution dans Scipy pour le lognormal n'est pas la même que dans R, ou généralement, pas la même que la distribution que je connais. John D Cook a abordé ce sujet: http://www.johndcook.com/blog/2010/02/03/statistical-distributions-in-scipy/ http://www.johndcook.com/distributions_scipy.html
Cependant, je n'ai rien trouvé de concluant sur la façon d'utiliser une fonction de densité lognormale en Python. Si quelqu'un souhaite ajouter quelque chose, n'hésitez pas.
Ma solution jusqu'à présent est d'utiliser le pdf lognormal évalué entre 0 et 180 (exclusif), et utilisé comme dictionnaire dans le script python.
la source