numpy 正态分布的对数似然

txu3uszq  于 2023-03-30  发布在  其他
关注(0)|答案(3)|浏览(179)

我试图找到最大似然估计的mu和sigma从正态分布使用最小化函数形式scipy。然而,最小化返回的期望值的平均值,但估计的sigma是远离真实的的sigma。
我定义函数llnorm,返回正态分布的负对数似然,然后从正态分布中创建随机样本,平均值为150,标准差为10,然后使用优化我试图找到MLE。

import numpy as np
import math
import scipy.optimize as optimize

def llnorm(par, data):
    n = len(data)
    mu, sigma = par
    ll = -np.sum(-n/2 * math.log(2*math.pi*(sigma**2)) - ((data-mu)**2)/(2 * (sigma**2)))
    return ll

data = 10 * np.random.randn(100) + 150

result = optimize.minimize(llnorm, [150,10], args = (data))

即使数据的平均值接近150并且std接近10,优化也会返回小得多的估计sigma值(接近0)。

ecr0jaav

ecr0jaav1#

你的数学有点问题:

ll = n*math.log(2*math.pi*(sigma**2))/2 + np.sum(((data-mu)**2)/(2 * (sigma**2)))

ll = np.sum(math.log(2*math.pi*(sigma**2))/2 + ((data-mu)**2)/(2 * (sigma**2)))

首先,我取消-的(这不是问题),但最重要的是,要么你保持常数项的总和,不乘以n,或者你把它拿出来,乘以n,......但不能同时两者。

xdnvmnnf

xdnvmnnf2#

你也可以使用scipy logpdf:

from scipy.stats import norm
norm(mu, sigma).logpdf(samples).sum()
jqjz2hbq

jqjz2hbq3#

np.random.randn创建具有方差1(docs here)的随机高斯分布。由于您的目标是具有标准差为10的分布,因此需要与10 * 10相乘

import numpy as np
import math
import scipy.optimize as optimize

def llnorm(par, data):
    n = len(data)
    mu, sigma = par
    ll = -np.sum(-n/2 * math.log(2*math.pi*(sigma**2)) - ((data-mu)**2)/(2 * (sigma**2)))
    return ll

data = 10 * 10 * np.random.randn(100) + 150 

result = optimize.minimize(llnorm, [150,10], args = (data))
print(result)

这给我:

fun: 36328.17002555693
 hess_inv: array([[ 0.96235834, -0.32116447],
       [-0.32116447,  0.10879383]])
      jac: array([0., 0.])
  message: 'Optimization terminated successfully.'
     nfev: 44
      nit: 8
     njev: 11
   status: 0
  success: True
        x: array([166.27014352,   9.15113937])

编辑:看起来~9的输出纯属巧合。还有其他的东西需要调查

相关问题