正态分布的对数似然

时间:2019-04-04 06:14:40

标签: python numpy normal-distribution

我正在尝试使用最小函数形式scipy从正态分布中找到mu和sigma的最大似然估计。但是,极小值返回的是均值的期望值,但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)的值。

2 个答案:

答案 0 :(得分:1)

您的数学略有下降:

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,...,但不能同时使用。

答案 1 :(得分:-1)

np.random.randn创建具有方差 1(docs here)的随机高斯分布。由于您的目标是使std为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的输出纯粹是巧合。还有其他事情需要调查