Как получить логнормальное распределение в Python с Mu и Sigma? - PullRequest
20 голосов
/ 15 января 2012

Я пытался получить результат lognormal дистрибутива, используя Scipy .У меня уже есть Му и Сигма, поэтому мне не нужно делать никаких других подготовительных работ.Если мне нужно быть более конкретным (и я пытаюсь использовать свои ограниченные знания статистики), я бы сказал, что я ищу кумулятивную функцию (cdf под Scipy).Проблема в том, что я не могу понять, как это сделать, используя только среднее значение и стандартное отклонение по шкале от 0 до 1 (т. Е. Возвращаемый ответ должен быть от 0 до 1).Я также не уверен, какой метод из dist , я должен использовать, чтобы получить ответ.Я пытался прочитать документацию и просмотреть SO, но соответствующие вопросы (такие как this и this ), по-видимому, не давали ответы, которые я искал.

Вот пример кода того, с чем я работаю.Спасибо.

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

ОБНОВЛЕНИЕ:

Так что после небольшой работы и небольшого исследования я получил немного больше.Но я все еще получаю неправильный ответ.Новый код ниже.Согласно R и Excel, результат должен быть .7434 , но это явно не то, что происходит.Есть ли у меня логический недостаток?

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

ОБНОВЛЕНИЕ 2: Рабочая реализация lognorm, которая дает правильный 0.7434 результат.

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

Ответы [ 6 ]

29 голосов
/ 12 декабря 2012

Я знаю, что это немного поздно (почти на год!), Но я проводил некоторые исследования функции lognorm в scipy.stats.Многие люди смущены входными параметрами, поэтому я надеюсь помочь этим людям.Приведенный выше пример почти верен, но мне показалось странным установить среднее значение для параметра location («loc») - это означает, что cdf или pdf не «взлетают», пока значение не станет больше среднего.Кроме того, аргументы среднего и стандартного отклонения должны быть в форме exp (Ln (среднее)) и Ln (StdDev) соответственно.

Проще говоря, аргументы (x, shape, loc, scale), с определениями параметров ниже:

loc - Нет эквивалента, это вычитается из ваших данных, так что 0 становитсянижний предел диапазона данных.

масштаб - exp μ, где μ - среднее значение логарифма переменной.(При подгонке, как правило, вы использовали бы среднее значение выборки из журнала данных.)

shape - стандартное отклонение журнала изменений.

Я испытал то же разочарованиекак и большинство людей с этой функцией, поэтому я делюсь своим решением.Просто будьте осторожны, потому что объяснения не очень ясны без перечня ресурсов.

Для получения дополнительной информации я нашел следующие источники полезными:

А вот пример, взятый из ответа @ serv-inc, размещенного на этой странице здесь:

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
14 голосов
/ 15 января 2012

Звучит так, будто вы хотите создать «замороженный» дистрибутив из известных параметров.В вашем примере вы можете сделать что-то вроде:

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

, что даст вам объект распределения lognorm с указанным средним и стандартным отклонением.Затем вы можете получить pdf или cdf следующим образом:

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

Это то, что вы имели в виду?

9 голосов
/ 27 февраля 2017
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

Подобно Excel и R, функция lognorm_cdf , приведенная выше, параметризует CDF для нормального логарифмического распределения с использованием mu и sigma .

Хотя SciPy использует параметры shape , loc и scale для характеристики своих вероятностных распределений, для нормального логарифмического распределения мне кажется, что это немного легче представить эти параметры на уровне переменных, а не на уровне распределения. Вот что я имею в виду ...

Логнормальная переменная X связана с нормальной переменной Z следующим образом:

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

что совпадает с:

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

Это может быть украдкой переписано следующим образом:

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

, где Z0 = 0. Это уравнение имеет вид:

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

Если вы можете визуализировать уравнения в своей голове, должно быть ясно, что параметры масштаба, формы и местоположения в уравнении 4: a , b и x0 соответственно. Это означает, что в уравнении 3 параметры масштаба, формы и местоположения: exp (mu) , sigma и ноль, соответственно.

Если вы не можете визуализировать это очень четко, давайте перепишем уравнение 2 как функцию:

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

, а затем посмотрите на эффекты mu и sigma на f (Z) . На рисунке ниже содержится сигма константа и изменяется му . Вы должны увидеть, что mu по вертикали f (Z) . Однако это происходит нелинейно; эффект изменения mu от 0 до 1 меньше, чем эффект изменения mu от 1 до 2. Из уравнения 2 мы видим, что exp (mu) на самом деле линейный коэффициент масштабирования. Следовательно, «масштаб» SciPy составляет exp (mu) .

effects_of_mu

Следующая цифра содержит mu константу и изменяется sigma . Вы должны увидеть, что форма f (Z) меняется. То есть f (Z) имеет постоянное значение, когда Z = 0 и sigma влияет на то, как быстро f (Z) изгибается от горизонтальной оси. Следовательно, «форма» SciPy сигма .

effects_of_sigma

3 голосов
/ 24 марта 2014

Еще более поздно, но на случай, если это пригодится кому-либо еще: я обнаружил, что Excel

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

дает те же результаты, что и Python

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

Аналогично, Excel

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

похоже на Python

from scipy.stats import lognorm
lognorm.pdf(x,sigma,0,mean).
2 голосов
/ 19 апреля 2016

@ lucas 'answer не требует использованияВ качестве примера кода вы можете использовать

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 голосов
/ 29 января 2017

Если вы читаете это и просто хотите функцию с поведением, аналогичным lnorm в R. Ну, тогда избавьте себя от насильственного гнева и используйте numpy's numpy.random.lognormal.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...