Я делаю что-то не так при использовании Scipy.stats при реализации логнормальной функции? - PullRequest
0 голосов
/ 04 июня 2018

Возможно, я просто мертв, но у меня есть код, который определяет логнормальный класс для манипулирования в Python с использованием Scipy.stats.

Мой класс выглядит так:

class LogNorm:

def __init__(self, mean, sd, offset=0) :
# uses 'real' units -i.e., 100000, 15000 for mean and sdn
    self.mean = mean
    self.sd = sd
    self.offset = offset
    self.xvar_mu, self.xvar_sigma = get_base_mu_and_sigma(mean, sd)
    self.mean = np.exp(self.xvar_mu + self.xvar_sigma**2.0/2.0)   # reflect that change in the Y 
    self.sd = ((np.exp(self.xvar_sigma**2.0) - 1.0) *
               (np.exp(2.0 * self.xvar_mu + self.xvar_sigma**2.0))) ** 0.5
    self.RV = lognorm(s = self.xvar_sigma, scale = self.mean, loc = self.offset)  # fozen

Идея в том, что вы передаете среднее значение и sd, как измерено, самого логнормального числа.Я записываю их для потомков (предположим, смещение = 0.0, по умолчанию).Затем у меня есть вспомогательная функция, которая отображает их в мю и сигма нормального распределения, лежащего в основе логнормального.Эта функция выглядит так, если она полезна:

def get_base_mu_and_sigma(mean, sd) :
    mu = math.log(mean**2.0 / (sd**2.0 + mean**2.0)**0.5)
    sigma = (math.log(1.0 + sd**2.0/mean**2.0))**0.5
    return (mu, sigma)

Это прямо из Википедии и кажется правильным (см. Конец раздела «Арифметические моменты»): https://en.wikipedia.org/wiki/Log-normal_distribution

Затем «self.RV» становится «замороженным» RV и имеет набор встроенных / унаследованных функций (mean (), median (), var () и т. Д.), Связанных с логнормальным значением, описанным mu и sigma.

Проблема, с которой я столкнулся, заключается в том, что, когда я создаю такой объект, а затем пытаюсь проверить среднее значение и sd (через квадратный корень из дисперсии), цифры не совпадают.Например, используя среднее значение = 110517.09 и sd = 2210.34 (из моего приложения), когда я затем выполняю следующий код, я получаю противоречивые ответы:

        p = rv1.RV.pdf(x)
        print("rv1.mean, rv1.sd = " + str(rv1.mean) + "  " + str(rv1.sd))
        print("rv1.mean(), rv1.var()**0.5 = " + str(rv1.RV.mean()) + "  " + str(rv1.RV.var()**0.5))

дает:

rv1.mean, rv1.sd = 110517.09180756475  2210.341836151173
rv1.mean(), rv1.var()**0.5 = 110539.19301602637  2210.783860320406

ЛюбойПонять, что я делаю не так?

1 Ответ

0 голосов
/ 05 июня 2018

Вы использовали self.mean в качестве аргумента scale для scipy.stats.lognorm, но это неверно.Цитирование из строки документа для lognorm:

Общая параметризация для логнормальной случайной величины Y выражается в виде среднего значения, mu и стандартного отклонения,sigma уникальной нормально распределенной случайной величины X, такой, что exp (X) = Y. Эта параметризация соответствует настройке s = sigma и scale = exp(mu).

Так, когда вы создаете self.RV, вызывая lognorm, аргумент scale должен быть np.exp(self.xvar_mu).(Предполагается, что offset равно 0.)

Вот упрощенный пример, который использует вашу функцию get_base_mu_and_sigma для преобразования параметров.

Во-первых, вот ваша функция и примеры значений, которыеВы использовали:

In [154]: def get_base_mu_and_sigma(mean, sd) :
     ...:     mu = math.log(mean**2.0 / (sd**2.0 + mean**2.0)**0.5)
     ...:     sigma = (math.log(1.0 + sd**2.0/mean**2.0))**0.5
     ...:     return (mu, sigma)
     ...: 

In [155]: mean = 110517.09180756475

In [156]: sd = 2210.341836151173

Получите параметры основного нормального распределения:

In [157]: mu, sigma = get_base_mu_and_sigma(mean, sd)

Создайте экземпляр распределения lognorm scipy и убедитесь, что среднее и стандартное отклонение этогосоответствие распределения mean и sd:

In [158]: ln = lognorm(s=sigma, loc=0, scale=np.exp(mu))

In [159]: ln.mean()
Out[159]: 110517.09180756476

In [160]: ln.std()
Out[160]: 2210.341836151174
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...