scypy, rozkład lognormalny-parametry
Chcę dopasować dystrybucję lognormal do moich danych, używając Pythona scipy.stats.lognormal.fit
. Zgodnie z instrukcją , fit
zwraca shape, Loc, scale parametry. Jednak rozkład lognormalny zwykle wymaga tylko dwóch parametrów : średniej i odchylenia standardowego.
Jak interpretować wyniki z funkcji scipy fit
? Jak uzyskać średnią i choroby weneryczne.dev.?
3 answers
Dystrybucje w scipy są kodowane w sposób ogólny wrt dwa parametr lokalizacja i skala tak, że lokalizacja jest parametrem (loc
), który przesuwa dystrybucję w lewo lub w prawo, podczas gdy {[2] } jest parametrem, który kompresuje lub rozciąga dystrybucję.
Dla dwóch parametrów rozkładu lognormalnego, "mean " I" std dev " odpowiadają logom (scale
) i shape
(można pozwolić loc=0
).
Poniżej przedstawiono jak dopasować rozkład lognormalny, aby znaleźć dwa parametry zainteresowania:
In [56]: import numpy as np
In [57]: from scipy import stats
In [58]: logsample = stats.norm.rvs(loc=10, scale=3, size=1000) # logsample ~ N(mu=10, sigma=3)
In [59]: sample = np.exp(logsample) # sample ~ lognormal(10, 3)
In [60]: shape, loc, scale = stats.lognorm.fit(sample, floc=0) # hold location to 0 while fitting
In [61]: shape, loc, scale
Out[61]: (2.9212650122639419, 0, 21318.029350592606)
In [62]: np.log(scale), shape # mu, sigma
Out[62]: (9.9673084420467362, 2.9212650122639419)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-05 19:45:09
Po prostu spędziłem trochę czasu na rozpracowywaniu tego i chciałem to udokumentować tutaj: jeśli chcesz uzyskać gęstość prawdopodobieństwa (w punkcie x
) z trzech wartości zwrotnych lognorm.fit
(nazwijmy je (shape, loc, scale)
), musisz użyć tego wzoru:
x = 1 / (shape*((x-loc)/scale)*sqrt(2*pi)) * exp(-1/2*(log((x-loc)/scale)/shape)**2) / scale
Więc jako równanie, które jest (loc
jest µ
, shape
jest σ
i scale
jest α
):
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-09 20:14:53
Myślę, że to pomoże. długo szukałem tego samego problemu i w końcu znalazłem rozwiązanie mojego problemu. W moim przypadku starałem się dopasować niektóre dane do rozkładu lognormalnego za pomocą modułu scipy.stats.lognorm
. jednak, kiedy w końcu dostałem parametry modelu, nie mogłem znaleźć sposobu, aby odtworzyć moje wyniki za pomocą średniej i choroby weneryczne z danych y.
W poniższym kodzie wyjaśniam na podstawie parametrów mean I std, w jaki sposób stworzyć normalnie rozłożoną próbkę danych używam scipy.statystyki.moduł norm. Korzystając z tych danych, dopasowuję model normalny (norm_dist_fitted
), a także tworzę model normalny za pomocą średniej i odchylenia standardowego (mu, sigma
) wydobytych z danych.
Oryginalny model wytwarzający dane, dopasowany i wyprodukowany-przez-(mu-sigma)-jest porównywany na wykresie.
W następnej sekcji kodu, używam normalnych danych do wytworzenia próbki o rozproszeniu lognormalnym. Aby to zrobić należy zauważyć, że próbki lognormalne będą wykładnicza oryginalnej próbki. Stąd średnie i odchylenie standardowe próbki wykładniczej będzie (exp(mu)
i exp(sigma)
).
Dopasowałem wytworzone dane do lognormal
(ponieważ dziennik mojej próbki (exp (x)) jest normalnie rozłożony i postępuj zgodnie z założeniami modelu lognormalnego.
Aby stworzyć model lognormalny ze średniej i odchylenia standardowego oryginalnych danych (x), kod będzie wynosił:
lognorm_dist = scipy.stats.lognorm(s=sigma, loc=0, scale=np.exp(mu))
Jeśli jednak Twoje dane znajdują się już w przestrzeni wykładniczej (exp (x)), to musisz użyć:
muX = np.mean(np.log(x))
sigmaX = np.std(np.log(x))
scipy.stats.lognorm(s=sigmaX, loc=0, scale=muX)
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()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-10 12:53:38