Как получить логнормальное распределение в Python с помощью Mu и Sigma? - программирование
Подтвердить что ты не робот

Как получить логнормальное распределение в Python с помощью Mu и Sigma?

Я пытаюсь получить результат 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)

UPDATE:

Итак, после небольшой работы и небольшого исследования, я получил немного дальше. Но я все еще получаю неправильный ответ. Новый код приведен ниже. Согласно R и Excel, результат должен быть 0,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
4b9b3361

Ответ 1

Похоже, вы хотите создать "замороженное" распределение по известным параметрам. В вашем примере вы можете сделать что-то вроде:

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

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

Ответ 2

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

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

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

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

Ответ 3

Еще более поздно, но в случае, если это поможет кому-то еще: я обнаружил, что 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).

Ответ 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

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

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

Лог-нормальная переменная 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), сигма и нуль, с уважением.

Если вы не можете четко это ясно представить, пусть переписать уравнение 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 "scale" - exp (mu).

effects_of_mu

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

effects_of_sigma

Ответ 5

ответ @lucas имеет использование погладить. В качестве примера кода вы можете использовать

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

Ответ 6

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