Журнал нормального распределения - PullRequest
0 голосов
/ 11 января 2019

У меня вопрос по поводу нормального распределения. Я хочу создать и объединить объекты с «массами» от 10 до 10 ** 5, которые обычно распределяются. Я думал, что это будет логарифмический дистрибутив, и поэтому я начал пытаться сделать это на python так:

mu, sigma = 3., 1. # mean and standard deviation
s = np.random.lognormal(mu, sigma, 1000)
count, bins, ignored = plt.hist(s, 1000, density=True, align='mid')
x = np.linspace(min(bins), max(bins), 1000)
pdf = (np.exp(-(np.log(x) - mu)**2 / (2 * sigma**2)) / (x * sigma * np.sqrt(2 * np.pi)))
plt.plot(x, pdf, linewidth=2, color='r')
plt.xscale('log')
plt.show()

как показано в примере с numpy, но меняя mu и sigma и глядя на графики, я не могу точно сказать, если для m и v (следуя приведенной ниже статье в Википедии) установить значение 10 ** 5 и 1000 let скажи дает мне то, что я хочу

Я посмотрел на https://en.wikipedia.org/wiki/Log-normal_distribution, чтобы понять, как вычислить mu и sigma, но, возможно, я делаю что-то еще неправильно. Это правильный подход к этой проблеме?

Я читал предыдущие вопросы / ответы, касающиеся нормального распределения, но я не думаю, что они задавали одно и то же. Извините заранее, если на этот тип вопроса уже дан ответ.

mu, sigma = 3., 1. Это то, что приведено в примере. Это отлично работает, но когда я изменяю mu и sigma на такие значения, как:

m=10**3.5 #where I want the distribution to be centered
v=10000   #the "spread" that I want 
f=1.+(v/m2)
mu=np.log(m/np.sqrt(f))
sigma=np.sqrt(np.log(f))

Я не получаю то, что ожидал ... это распределение, сосредоточенное вокруг 10 ** 3,5 со стандартным значением 10000.

Попытка того, что было предложено:

mu=np.log(3000)
sigma=np.log(10)
s = np.random.lognormal(mu, sigma, 1000)
count, bins, ignored = plt.hist(s, 500, density=True, align='mid')
x = np.linspace(min(bins), max(bins), 1000)
pdf = (np.exp(-(np.log(x) - mu)**2 / (2 * sigma**2)) / (x * sigma * np.sqrt(2 * np.pi)))
plt.semilogx(x, pdf, linewidth=2, color='r')

Похоже, это тоже не сработает, если только я неправильно истолковываю гистограмму. Гистограмма

Ответы [ 2 ]

0 голосов
/ 12 января 2019

Если вы знаете, что вам нужно 1000 значений, которые распределены по лог-нормальному распределению (т. Е. Log (x) дает вам нормальное распределение), и вы хотите, чтобы ваши данные находились в диапазоне от 10 до 10 ^ 5, то вам нужно сделать некоторые расчеты, чтобы получить му и сигма. Но значения, которые вы должны включить в np.random.lognormal, представляют собой среднее и стандартное отклонение базового, связанного нормального распределения, не логарифмически нормального распределения. Вы можете получить их из формул среднего и дисперсии, приведенных на странице Википедии, которую вы видели.

# Parameters
xmax = 10**5
xmin = 10
n = 1000

# Get original mean and variance
# mu: We want normal distribution, so just take the average of the extremes.
# sigma: use the z = (x - mu)/sigma formula and approximation that 
#        the extremes are a deviation of z=3 away.
mu = (xmax + xmin)/2.0
sigma = (xmax - mu)/3.0
m = mu
v = sigma**2

# Get the mean and standard deviation of the underlying normal distribution
norm_mu = np.log(m**2 / np.sqrt(v + m**2))
norm_sigma = np.sqrt((v / m**2)+1)

# Generate random data and an overlying smooth curve
# (This is the same as your code, except I replaced the parameters
# in the 'pdf =' formula.)
s = np.random.lognormal(norm_mu, norm_sigma, n)
count, bins, ignored = plt.hist(s, n, density=True, align='mid')
x = np.linspace(min(bins), max(bins), n)
pdf = (np.exp(-(np.log(x) - norm_mu)**2 / (2 * norm_sigma**2)) / (x * norm_sigma * np.sqrt(2 * np.pi)))
plt.plot(x, pdf, linewidth=2, color='r')
plt.xscale('log')
plt.show()

Вот что я получаю. Обратите внимание, что масштабирование по оси X возрастает экспоненциально, а не линейно. Это то, что вы ищете?

enter image description here

0 голосов
/ 12 января 2019

Я думаю, что вам трудно интерпретировать параметры дистрибутива.

Документация для np.random.lognormal находится здесь: https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.random.lognormal.html

В частности, среднее значение составляет не mu или 10**mu, а exp(mu), поэтому в вашем распределении имеется среднее значение e**3 ≈ 20.

Кажется, вы хотите, чтобы среднее значение было около 1000, поэтому установите mu и sigma на

mu, sigma  = np.log(1000), np.log(10)`

сгенерирует ожидаемый дистрибутив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...