Я пытаюсь использовать функцию подгонки scipy
для подгонки гамма-распределения к наблюдаемым данным.Гистограмма для наблюдаемых данных ниже:
Среднее значение и дисперсия
print("mean",np.mean(observed_data)) # mean 0.427611176580073
print("Var",np.var(observed_data)) # Var 0.6898193689790143
Однако, если я использую scipy.stats.gamma.fit()
, чтобы согласовать эти наблюдаемые данные с гамма-распределением, а затем снова произвести выборку из этого распределения, среднее значение и дисперсия совершенно разные:
Я знаючто scipy
подходит на основе MLE, но я не понимаю интуицию, объясняющую, почему эти ключевые статистические данные настолько отклонены - среднее значение и дисперсия совершенно разные.На самом деле, я могу получить гораздо лучшие результаты, просто запустив это через свой собственный решатель:
from scipy.optimize import fsolve
from typing import List
def fit_gamma_distribution(data: List[float]):
mean = np.mean(data)
variance = np.var(data)
def equations(p):
k, theta = p
return (k * theta - mean, k * theta **2 - variance)
solved_k, solved_theta = fsolve(equations, (1,1))
if np.isclose(np.array([solved_k * solved_theta]), np.array([mean]), rtol=0.01):
return fsolve(equations, (1,1))
k, theta = fit_gamma_distribution(observed_data)
new_dist = np.random.gamma(shape=k, scale=
theta, size=len(observed_data))
plt.hist(new_dist, alpha= 0.5, bins=40)
plt.hist(observed_data, alpha=0.2, bins=40)
plt.xlim(0,5)
plt.title(f"New sampled distribution: μ = {round(np.mean(new_dist),2)} observed μ = {round(np.mean(observed_data), 2)}")
Это гораздо лучше, чем scipy
один на мой взгляд.Почему это так?