Generate random numbers from lognormal distribution in python

I need to generate pseudo random numbers from a lognormal distribution in Python. The problem is that I start with the mode and standard deviation of the lognormal distribution. I have no average or median of the lognormal distribution or none of the parameters of the main normal distribution.

numpy.random.lognormalaccepts the mean and standard deviation of the basic normal distribution. I tried to calculate them according to the parameters that I have, but ended up with a quadratic function. This has a solution, but I hope there is an easier way to do this.

scipy.stats.lognormaccepts parameters that I do not understand. I am not a native speaker of English, and the documentation does not make sense.

Can you help me please

+4
source share
2 answers

You have a mode and a standard deviation of the logarithmic distribution. To use the rvs()scipy method lognorm, you need to parameterize the distribution in terms of the shape parameter s, which is the standard deviation of the sigmabasic normal distribution and scalewhich exp(mu), where muis the average of the underlying distribution.

You indicated that for this reparametrization a quartic polynomial solution is required. For this we can use a class numpy.poly1d. Instances of this class have an attribute roots.

, exp(sigma**2) -

x**4 - x**3 - (stddev/mode)**2 = 0

stddev mode - - , scale (.. exp(mu))

scale = mode*x

, :

def lognorm_params(mode, stddev):
    """
    Given the mode and std. dev. of the log-normal distribution, this function
    returns the shape and scale parameters for scipy parameterization of the
    distribution.
    """
    p = np.poly1d([1, -1, 0, 0, -(stddev/mode)**2])
    r = p.roots
    sol = r[(r.imag == 0) & (r.real > 0)].real
    shape = np.sqrt(np.log(sol))
    scale = mode * sol
    return shape, scale

,

In [155]: mode = 123

In [156]: stddev = 99

In [157]: sigma, scale = lognorm_params(mode, stddev)

:

In [158]: from scipy.stats import lognorm

In [159]: sample = lognorm.rvs(sigma, 0, scale, size=1000000)

:

In [160]: np.std(sample)
Out[160]: 99.12048952171304

- matplotlib , , :

In [176]: tmp = plt.hist(sample, normed=True, bins=1000, alpha=0.6, color='c', ec='c')

In [177]: plt.xlim(0, 600)
Out[177]: (0, 600)

In [178]: plt.axvline(mode)
Out[178]: <matplotlib.lines.Line2D at 0x12c5a12e8>

:

histogram


numpy.random.lognormal() scipy.stats.lognorm.rvs(), :

In [200]: sigma, scale = lognorm_params(mode, stddev)

In [201]: mu = np.log(scale)

In [202]: sample = np.random.lognormal(mu, sigma, size=1000000)

In [203]: np.std(sample)
Out[203]: 99.078297384090902

, poly1d roots, . , scipy x. , :

max(sqrt(stddev/mode), 1) <= x <= sqrt(stddev/mode) + 1
+5

log-normal distribution () .

mu = log (m / sqrt (1 + v / m ^ 2)), sigma = sqrt (log (1 + v / m ^ 2))

μ σ - , " ", m v - - .

, , . v . m : , exp (mu + sigma ^ 2/2), exp (mu - sigma ^ 2). ,

log m = log n + 3/2 log (1 + v / m ^ 2)

n - - , v, m - . ,

m ^ 8 = n ^ 2m ^ 6 + 3vn ^ 2m ^ 4 + 3n ^ 2v ^ 2m ^ 2 + n ^ 2v ^ 3

u ^ 4 - n ^ 2u ^ 3 - 3vn ^ 2u ^ 2 - 3n ^ 2v ^ 2u - n ^ 2v ^ 3 = 0

u = m 2. , , . , , , . , n v , ().

, . , ; https://math.stackexchange.com/.

+1

Source: https://habr.com/ru/post/1665737/


All Articles