Используйте распределенное логарифмическое распределение для подгонки данных с небольшими значениями, а затем отобразите в matplotlib - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть набор данных, который содержит значения от 0 до 1e-5.Я предполагаю, что данные могут быть описаны логнормальным распределением.Поэтому я использую scipy.stats.lognorm для подгонки своих данных и хочу нанести данные о происхождении и распределении на одну и ту же фигуру с помощью matplotlib.

Во-первых, я строю график по гистограмме:
enter image description here

Затем я добавляю распределение фитингов по линейному графику.Однако это изменит ось Y на очень большое число:
enter image description here

Таким образом, исходные данные (образец) не видны на рисунке!

Я проверил все переменные и обнаружил, что переменная pdf_fitted настолько велика (> 1e7).Я действительно не понимаю, почему простая подгонка scistats.lognorm.fit к образцу, который был сгенерирован тем же дистрибутивом scistats.lognorm.pdf, не работает.Вот коды для демонстрации моей проблемы:

from matplotlib import pyplot as plt
from scipy import stats as scistats
import numpy as np

# generate a sample for x between 0 and 1e-5
x = np.linspace(0, 1e-5, num=1000)
y = scistats.lognorm.pdf(x, 3, loc=0, scale=np.exp(10))
h = plt.hist(y, bins=40) # plot the sample by histogram
# plt.show()

# fit the sample by using Log Normal distribution
param = scistats.lognorm.fit(y)
print("Log-normal distribution parameters : ", param)
pdf_fitted = scistats.lognorm.pdf(
    x, *param[:-2], loc=param[-2], scale=param[-1])
plt.plot(x, pdf_fitted, label="Fitted Lognormal distribution")
plt.ticklabel_format(style='sci', scilimits=(-3, 4), axis='x')
plt.legend()
plt.show()

1 Ответ

0 голосов
/ 19 декабря 2018

Проблема

Непосредственная проблема, с которой вы столкнулись, заключается в том, что ваше состояние действительно очень плохое.Вы можете увидеть это, если вы установите шкалу x и y на графике для регистрации, как с plt.xscale('log') и plt.yscale('log').Это позволяет вам видеть как гистограмму, так и ваши данные на одном графике:

enter image description here

, поэтому она отклоняется на много порядков в обоих направлениях.

Исправление

Весь ваш подход к генерации выборки из распределения вероятности, представленной stats.lognorm, и ее подгонке был неверным.Вот правильный способ сделать это, используя те же параметры для распределения lognorm, которые вы указали в своем вопросе:

from matplotlib import pyplot as plt
from scipy import stats as scistats
import numpy as np

plt.figure(figsize=(12,7))
realparam = [.1, 0, np.exp(10)]

# generate pdf data around the mean value
m = realparam[2]
x = np.linspace(m*.6, m*1.4, num=10000)
y = scistats.lognorm.pdf(x, *realparam)

# generate a matching random sample
sample = scistats.lognorm.rvs(*realparam, size=100000)
# plot the sample by histogram
h = plt.hist(sample, bins=100, density=True)

# fit the sample by using Log Normal distribution
param = scistats.lognorm.fit(sample)
print("Log-normal distribution parameters : ", param)
pdf_fitted = scistats.lognorm.pdf(x, *param)
plt.plot(x, pdf_fitted, lw=5, label="Fitted Lognormal distribution")
plt.legend()
plt.show()

Вывод:

Log-normal distribution parameters :  (0.09916091013245995, -215.9562383088556, 22245.970148671593)

enter image description here

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