import numpy as np
from scipy.stats import lognorm
from scipy.stats import norm
import ipywidgets as widgets
import matplotlib.pyplot as plt
import math
import warnings; warnings.filterwarnings(action='once')
Можно ли на глаз отличить плотность нормального распределения от плотности логнормального зависит, в первую очередь, от коэффициентов асимметрии и эксцесса логнормального распределения. Чем ближе они к нулю, тем более похожи плотности (при одинаковых мат.ож. и дисперсии). Посмотрев на формулы для логнормального распределения, можно увидеть, что асимметрия и эксцесс равны нулю, только если параметр $\sigma^2$ близок к нулю. На этом и основаны след. примеры.
Одинаковые математические ожидания, одинаковые малые дисперсии, похожие плотности.
mean = 1
sigma = 0.1
mean_log = math.exp(mean+(sigma**2)/2)
sigma_log = np.sqrt((math.exp(sigma**2)-1)*math.exp(2*mean+(sigma**2)))
grid = np.linspace(-1, 6, 1000) # сетка для построения графика
plt.figure(figsize=(12, 6))
plt.plot(grid, norm(mean_log, sigma_log).pdf(grid), lw=5,
label='${N}' + '({}, {})$'.format(2.73, 0.27))
plt.plot(grid, lognorm(s=sigma, loc=0, scale=np.exp(mean)).pdf(grid), lw=5,
label='${LogN}' + '({}, {})$'.format(1, 0.1))
plt.xlim(1, 4)
plt.legend(fontsize=16)
plt.title('Плотность нормального и логнормального распределения', fontsize=20)
plt.xlabel('Значение', fontsize=18)
plt.ylabel('Плотность', fontsize=18)
plt.grid(ls=':')
plt.show()
При увеличении дисперсии различие плотностей становится гораздо заметнее.
mean = 1
sigma = 0.4
mean_log = math.exp(mean+(sigma**2)/2)
sigma_log = np.sqrt((math.exp(sigma**2)-1)*math.exp(2*mean+(sigma**2)))
grid = np.linspace(-2, 7, 1000) # сетка для построения графика
plt.figure(figsize=(12, 6))
plt.plot(grid, norm(mean_log, sigma_log).pdf(grid), lw=5,
label='${N}' + '({}, {})$'.format(2.944, 1.226))
plt.plot(grid, lognorm(s=sigma, loc=0, scale=np.exp(mean)).pdf(grid), lw=5,
label='${LogN}' + '({}, {})$'.format(1, 0.4))
plt.xlim(-2, 7)
plt.legend(fontsize=16)
plt.title('Плотность нормального и логнормального распределения', fontsize=20)
plt.xlabel('Значение', fontsize=18)
plt.ylabel('Плотность', fontsize=18)
plt.grid(ls=':')
plt.show()
Промоделируем выборку объемом 1000 из нормального распределения $\mathcal{N}(a,\sigma^2)$ c $a=0$, $\sigma=1$
mean = 0
sigma = 1
sample = np.random.normal(mean, sigma, 1000)
Найдём выборочное среднее, медиану и дисперсию и сравним их с генеральными характеристиками, которые должны быть равны 0,0 и 1 соответственно.
params = [np.mean(sample),np.median(sample), np.sqrt(np.var(sample))]
params
[0.014214970842872748, -0.04546632429359594, 1.0156016415468325]
plt.figure(figsize=(9,9), dpi= 80)
plt.hist(sample, density=True, bins=20,label='hist of Log(LogN)')
k=4
x = np.linspace(-k*sigma, k*sigma, 100)
plt.plot(x, norm.pdf(x), 'r-', lw=3, label='N(0,1) density')
plt.xlim(-k*sigma, k*sigma)
plt.title('Гистограмма выборки из N(0,1), плотность N(0, 1)', fontsize=22)
plt.xlabel('Значение', fontsize=18)
plt.ylabel('Плотность', fontsize=18)
plt.grid(ls=':')
plt.legend()
plt.show()
Промоделируем выборку объёмом $n = 10000$ из логнормального распределения $\mathcal{LogN}(a,\sigma^2)$ с параметрами $a=0$, $\sigma=0.2$
mean = 0
sigma = 0.2
sample = np.random.lognormal(mean, sigma, 10000)
real_params = [np.exp(mean+sigma**2/2),np.exp(mean),(np.exp(sigma**2)-1)*np.exp(2*mean+sigma**2)]
Ожидаемые параметры (теоретические):
real_params
[1.0202013400267558, 1.0, 0.04247629348257031]
Оценки параметров по выборке
params = [np.mean(sample),np.median(sample), np.var(sample)]
params
[1.0195543273582472, 0.9995968836595583, 0.041927894904046165]
В целом правдоподобно выглядит. Построим гистограмму:
plt.figure(figsize=(9,9), dpi= 80)
plt.hist(sample, density=True, bins=20, label='hist of sample from ${LogN}' + '({}, {})$'.format(0, 0.2))
x = np.linspace(-1/2, 9, 100)
plt.xlim(-1/2, 2.5)
plt.plot(grid, lognorm(s=sigma, loc=0, scale=np.exp(mean)).pdf(grid), lw=5, label='Density ${LogN}' + '({}, {})$'.format(0, 0.2))
plt.title('Гистограмма выборки и плотность LogN(0, 0.2)', fontsize=22)
plt.xlabel('Значение', fontsize=18)
plt.ylabel('Плотность', fontsize=18)
plt.grid(ls=':')
plt.legend()
plt.show()
Проверим свойство, что логарифм логнормально распределенной случайной величины имеет нормальное распределение. Прологарифмируем выборку, стандартизуем ее и сравним с $N(0,1)$
sample_log=np.log(sample)
sample_scaled = (sample_log-np.mean(sample_log))/math.sqrt(np.var(sample_log))
plt.figure(figsize=(9,9), dpi= 70)
x = np.linspace(-4, 4, 100)
plt.hist(sample_scaled, density=True, bins=20,label='hist of ln$(LogN)$')
plt.plot(x, norm.pdf(x), 'r-', lw=3, label='$N(0,1)$ density')
plt.xlabel('Значение', fontsize=18)
plt.ylabel('Плотность', fontsize=18)
plt.title('Гистограмма стандартизированной прологарифмированной выборки из $Log(0,0.2)$ и плотность $N(0, 1)$', fontsize=22)
plt.legend()
plt.show()
Как видим, получившаяся гистограмма выборки после логарифмирования действительно не отличима от гистрограммы выборки из нормального распределения.