Myślę, że to pomoże. Szukałem tego samego problemu przez długi czas iw końcu znalazłem rozwiązanie dla mojego problemu. W moim przypadku, Próbowałem dopasować niektóre dane do dystrybucji lognormalnej przy użyciu modułu scipy.stats.lognorm
. Jednakże, gdy w końcu dostałem parametry modelu, nie mogłem znaleźć sposobu na powtórzenie wyników przy użyciu wartości średniej i std z y.
W poniższym kodzie wyjaśniam na podstawie parametrów średnich i standardowych, jak utworzyć próbkę danych o rozkładzie normalnym za pomocą modułu scipy.stats.norm. Korzystając z tych danych, dopasowuję normalny model (norm_dist_fitted
), a także tworzę normalny model, używając wyodrębnionego z danych średniej i standardowego odchylenia (mu, sigma
).
Oryginalny model produkujący dane, dopasowany i wyprodukowany po (mu-sigma) -parę jest porównywany na wykresie.
Fig1
W następnej części kodu używać normalnych danych w celu wytworzenia próbki logarytmiczno-normalny rozdzielone. Aby to zrobić, należy zauważyć, że próbki logormalne będą wykładnicze dla oryginalnej próbki. Zatem średnie i standardowe odchylenie próbki wykładniczej będzie wynosić (exp(mu)
i exp(sigma)
).
I wyposażone wytworzonych danych do lognormal
(od dziennik mojego próbki (exp (x)) jest normalnie rozprowadzane i wykonaj lognormal założeń modelowych.
celu wytworzenia logarytmiczno-normalny model z średniej i odchylenia standardowego z oryginalnych danych (x) kod będzie:
lognorm_dist = scipy.stats.lognorm(s=sigma, loc=0, scale=np.exp(mu))
Jednakże, jeśli dane są już w wykładniczej przestrzeni (exp (x)), następnie trzeba użyć:
muX = np.mean(np.log(x))
sigmaX = np.std(np.log(x))
scipy.stats.lognorm(s=sigmaX, loc=0, scale=muX)
Fig2
import scipy
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
mu = 10 # Mean of sample !!! Make sure your data is positive for the lognormal example
sigma = 1.5 # Standard deviation of sample
N = 2000 # Number of samples
norm_dist = scipy.stats.norm(loc=mu, scale=sigma) # Create Random Process
x = norm_dist.rvs(size=N) # Generate samples
# Fit normal
fitting_params = scipy.stats.norm.fit(x)
norm_dist_fitted = scipy.stats.norm(*fitting_params)
t = np.linspace(np.min(x), np.max(x), 100)
# Plot normals
f, ax = plt.subplots(1, sharex='col', figsize=(10, 5))
sns.distplot(x, ax=ax, norm_hist=True, kde=False, label='Data X~N(mu={0:.1f}, sigma={1:.1f})'.format(mu, sigma))
ax.plot(t, norm_dist_fitted.pdf(t), lw=2, color='r',
label='Fitted Model X~N(mu={0:.1f}, sigma={1:.1f})'.format(norm_dist_fitted.mean(), norm_dist_fitted.std()))
ax.plot(t, norm_dist.pdf(t), lw=2, color='g', ls=':',
label='Original Model X~N(mu={0:.1f}, sigma={1:.1f})'.format(norm_dist.mean(), norm_dist.std()))
ax.legend(loc='lower right')
plt.show()
# The lognormal model fits to a variable whose log is normal
# We create our variable whose log is normal 'exponenciating' the previous variable
x_exp = np.exp(x)
mu_exp = np.exp(mu)
sigma_exp = np.exp(sigma)
fitting_params_lognormal = scipy.stats.lognorm.fit(x_exp, floc=0, scale=mu_exp)
lognorm_dist_fitted = scipy.stats.lognorm(*fitting_params_lognormal)
t = np.linspace(np.min(x_exp), np.max(x_exp), 100)
# Here is the magic I was looking for a long long time
lognorm_dist = scipy.stats.lognorm(s=sigma, loc=0, scale=np.exp(mu))
# The trick is to understand these two things:
# 1. If the EXP of a variable is NORMAL with MU and STD -> EXP(X) ~ scipy.stats.lognorm(s=sigma, loc=0, scale=np.exp(mu))
# 2. If your variable (x) HAS THE FORM of a LOGNORMAL, the model will be scipy.stats.lognorm(s=sigmaX, loc=0, scale=muX)
# with:
# - muX = np.mean(np.log(x))
# - sigmaX = np.std(np.log(x))
# Plot lognormals
f, ax = plt.subplots(1, sharex='col', figsize=(10, 5))
sns.distplot(x_exp, ax=ax, norm_hist=True, kde=False,
label='Data exp(X)~N(mu={0:.1f}, sigma={1:.1f})\n X~LogNorm(mu={0:.1f}, sigma={1:.1f})'.format(mu, sigma))
ax.plot(t, lognorm_dist_fitted.pdf(t), lw=2, color='r',
label='Fitted Model X~LogNorm(mu={0:.1f}, sigma={1:.1f})'.format(lognorm_dist_fitted.mean(), lognorm_dist_fitted.std()))
ax.plot(t, lognorm_dist.pdf(t), lw=2, color='g', ls=':',
label='Original Model X~LogNorm(mu={0:.1f}, sigma={1:.1f})'.format(lognorm_dist.mean(), lognorm_dist.std()))
ax.legend(loc='lower right')
plt.show()
dwa komentarze: nastąpił błąd w scipy 0,9 z kłaczków, która została ustalona w scipy 0,10 http://projects.scipy.org/scipy/ticket/1536 a po drugie dlatego, generycznego parametryzacji dystrybucja lognormalna nie ma zwykłej parametryzacji, na przykład http://projects.scipy.org/scipy/ticket/1502. – user333700
dzięki za poprawki. Nie dostałem drugiego - z komentarzy w linku wydaje się, że nie ma tam żadnego błędu ...? –
@JakubM. Tak, jeśli używasz najnowszego scipy (0.10), powyższa odpowiedź/przykład nie jest sprzeczna z żadnym z biletów wymienionych w komentarzu użytkownika user33700. – ars