最大似然估计伪代码

28

我需要编写最大似然估计器来估算一些玩具数据的均值和方差。 我有一个向量,其中包含 100 个样本,使用 numpy.random.randn(100) 创建。 数据应该具有零均值和单位方差的高斯分布。

我查了维基百科和一些额外的来源,但由于我没有统计学背景,所以有点困惑。

是否有任何最大似然估计器的伪代码? 我理解MLE的直觉,但我无法弄清楚从哪里开始编码。

维基百科说要取对数似然函数的argmax。 我理解是:我需要使用不同的参数来计算对数似然函数,然后我将选择给出最大概率的参数。 我不明白的是:首先我从哪里找到参数? 如果我随机尝试不同的均值和方差以获得高概率,那么什么时候应该停止尝试?


如果你有“一组数据”,那么平均值是数据本身,方差为0.0。 - John Machin
1
抱歉造成困惑,该数据是一个包含100个样本的向量。 - user103021
4个回答

42

我刚看到这个,我知道这很旧了,但我希望其他人能从中受益。虽然之前的评论已经相当好地描述了什么是 ML 优化,但没有人给出伪代码来实现它。Python 的 Scipy 库中有一个最小化函数可以做到这一点。以下是线性回归的伪代码。

# import the packages
import numpy as np
from scipy.optimize import minimize
import scipy.stats as stats
import time

# Set up your x values
x = np.linspace(0, 100, num=100)

# Set up your observed y values with a known slope (2.4), intercept (5), and sd (4)
yObs = 5 + 2.4*x + np.random.normal(0, 4, 100)

# Define the likelihood function where params is a list of initial parameter estimates
def regressLL(params):
    # Resave the initial parameter guesses
    b0 = params[0]
    b1 = params[1]
    sd = params[2]

    # Calculate the predicted values from the initial parameter guesses
    yPred = b0 + b1*x

    # Calculate the negative log-likelihood as the negative sum of the log of a normal
    # PDF where the observed values are normally distributed around the mean (yPred)
    # with a standard deviation of sd
    logLik = -np.sum( stats.norm.logpdf(yObs, loc=yPred, scale=sd) )

    # Tell the function to return the NLL (this is what will be minimized)
    return(logLik)

# Make a list of initial parameter guesses (b0, b1, sd)    
initParams = [1, 1, 1]

# Run the minimizer
results = minimize(regressLL, initParams, method='nelder-mead')

# Print the results. They should be really close to your actual values
print results.x

对我来说这很棒。当然,这只是基础知识。它不会对参数估计进行剖析或提供置信区间,但它是一个起点。您还可以使用机器学习技术来找到ODE和其他模型的估计值,就像我在这里描述的那样。

我知道这个问题已经过时了,希望你自从那时以来已经解决了它,但希望其他人也能从中受益。


斜率和y截距分别为(1.0101010101010102, 1.0),对吗? - O.rka
您在此处发布的链接已被删除。 - muammar

20
如果你进行最大似然计算,第一步需要做的是:假设一个依赖于某些参数的分布。由于你会生成数据(你甚至知道你的参数),你会"告诉"程序假设高斯分布。但是,你不会告诉程序你的参数(0和1),而是将它们预先保留未知,并在之后计算它们。
现在,你有了样本向量(我们称之为x,其元素为x[0]x[100]),你必须对它进行处理。为此,你需要计算以下内容(f表示高斯分布的概率密度函数):
f(x[0]) * ... * f(x[100])

如您在我给出的链接中所见,f使用两个参数(希腊字母µ和σ)。现在,您需要以某种方式计算µ和σ的值,使得f(x[0]) * ... * f(x[100])取最大可能值。

完成后,µ就是均值的最大似然值,σ是标准差的最大似然值。

请注意,我没有明确告诉您如何计算µ和σ的值,因为这是一个相当数学的过程,我手头没有(而且可能我也不会理解);我只是告诉您获取值的技术,该技术也可以应用于任何其他分布。

由于您想要最大化原始术语,因此您可以“简单地”最大化原始术语的对数-这样可以避免处理所有这些乘积,并将原始术语转换为具有一些求和项的总和。

如果您真的想计算它,可以进行一些简化,从而得到以下术语(希望我没有搞砸任何东西):

enter image description here

现在,你需要找到 µ 和 σ 的值,使得上述函数最大化。这是一个非常不平凡的任务,称为非线性优化。
一种简化的方法是:固定一个参数,尝试计算另一个参数。这样可以避免同时处理两个变量。

谢谢你的回答。我的理解是:如果我固定一个参数并计算另一个参数,反之亦然,那么我实际上就是在进行期望最大化算法,对吗?http://en.wikipedia.org/wiki/Expectation%E2%80%93maximization_algorithm - user103021
我认为这可能是情况(但我对此并不确定)。我想以平均值作为µ(将µ固定到平均值)的起点,然后最大化σ可能是一个不错的开始... - phimuemue
@Kyle:也许这个链接对你有用:http://en.wikipedia.org/wiki/Maximum_likelihood#Continuous_distribution.2C_continuous_parameter_space。 - phimuemue
2
@Kyle FYI,高斯分布的最大似然估计可以通过解析方法得到。它们是样本均值和样本方差,尽管后者对于小样本大小略有偏差,因此通常除以n-1而不是n。更一般地说,您需要学习牛顿法和EM(期望最大化算法)。 - joran
@joran 实际上,对于高斯分布,如果我取样本均值和样本方差,就可以得到数据集的最大似然估计。实际上,我需要对数据集应用有偏和无偏的最大似然估计。那么在这种情况下,你知道只是取样本均值和样本方差是否有效吗? - user103021
使用LaTeX使数学代码更易读。如果有人需要代码或进行更改,请使用以下代码:n\cdot ln(\frac{1}{\sigma\sqrt{2\pi} } ) - 0.5 \sum^{100}_{i=0}{\frac{(x[i]-\mu)^2}{2\sigma}}。使用此链接进行转换:https://codecogs.com/latex/eqneditor.php - ntg

4
你需要一个数值优化程序。不确定Python中是否实现了任何内容,但如果有的话,它将在numpy或scipy和相关库中。寻找像“Nelder-Mead算法”或“BFGS”之类的东西。如果其他方法都失败了,请使用Rpy并调用R函数“optim()”。这些函数通过搜索函数空间并尝试找出最大值来工作。想象一下在雾中寻找山坡顶部的情况。您可能只是试图一直向上走最陡峭的路。或者您可以让一些朋友带着无线电和GPS设备进行一些测量。这两种方法都可能导致您找到错误的山顶,因此您通常需要从不同的起点多次尝试。否则,当有一个庞大的北峰遮盖时,您可能会认为南峰是最高的。

如果概率密度函数有闭式解,则不必使用数值优化。例如,可以通过对mu和sigma求导并将其等于0来评估多元高斯分布的参数。最优参数对应于数据的mu和sigma。 - yasin.yazici

1
正如joran所说,正态分布的最大似然估计可以通过解析方法计算得出。答案是通过对数似然函数对参数的偏导数为零,然后同时解决两个方程来找到的。
在正态分布的情况下,您将针对均值(mu)推导出对数似然函数,然后再针对方差(sigma^2)推导出对数似然函数,以获得两个等于零的方程。在解出mu和sigma^2的方程之后,您将得到样本均值和样本方差作为答案。
有关更多详细信息,请参见wikipedia页面

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接