Как получить логнормальное распределение в 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
Ответы
Ответ 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
.