程序错误和有关最大值的问题对数似然

时间:2017-10-26 11:28:16

标签: python statistics

我试图计算以下概率密度函数(PDF)的最大对数似然(MLE):

pdf

我通过最小化目标函数(负对数似然)来计算它,而不依赖于任何预定义的log-likelihood python内置模块。代码是:

# Alpha Distribution (PDF)
def AD(z, *params): 
    a, scale = z
    diameters = params
    return -np.sum(np.log((((diameters)/(a**2) * np.exp(-diameters/a))) / scale))

# load data
currpath = ('path')
os.chdir(currpath)
diameters = scipy.io.loadmat('data.mat')["m1"]

# minimise
x0 = [1,1] # initial guesses
res = optimize.minimize(AD, x0, args = diameters, method='Nelder-Mead', 
                    tol=1e-6)
print(res.x)

我的数据向量(此处已经排序)包含以下形式的多个直径(0.19,0.19,0.19,0.2,0.21,0.21,0.22,0.22,0.22,0.25,0.27 ......)。

第一个问题:由于我对MLE的主题还不太新,我的数据向量的形式是否正确?我不完全确定我是否使用数据向量包含每个观察到的直径(如上所示),或仅包含"可能"直径(可能是:0.19,0.2,0.21,0.22,0.25,0.27 ......),或者只是观察到的直径的频率(可能是:3,1,2,3,1,1 ......) 。我认为第一个选择是正确的,但我只是想完全确定。

第二个问题:如果我希望使用累积分布函数(CDF)代替PDF来执行我的MLE,我必须将我的PDF功能更改为CDF,对吗? I只是想知道我是否可以以某种方式修改我的数据向量并仍然使用PDF。

但是,对于python中的最小化(如果我理解正确的话),我不得不重新考虑我的变量的定义。这意味着,通常我会假设我的PDF参数(这里" a""比例")是应该传递给" args"的变量。在" optimize.minimize"。但是,在文档中说明,args应该包含"常量"参数,因此我使用我的数据向量作为常量"参数向量"最小化。

第三个问题:这个假设在推理中是错误的吗?

第四个问题:优化方法是" Nelder-Mead"合适吗?我不熟悉优化方法,也不确定我应该使用哪种选项/是最好的。

最后,程序返回错误" TypeError:一元的坏操作数类型 - :' tuple'" ,其中我不知道如何处理它,因为我没有将任何元组传递给最小化函数......

第五个问题:元组来自何处以及如何解决此错误?

我非常感谢你能给我的任何帮助!

祝你好运!

PS:由于这篇文章是一般数学和编程之间的混合,我不能完全确定这是否是提出问题的正确位置。对不起,如果我错了!

2 个答案:

答案 0 :(得分:0)

首先,除了第一部分(乘法运算符之前)之外,我们正在讨论exponential distribution通常所说的最大似然估计(MLE)。它刚刚被称为 a

的东西被重新参数化

我们想根据直径样本估算这个参数;没有比例参数。在MLE下,我们假装样本是固定的,并将参数视为可以变化的东西。我们通过获取密度函数( not cdfs)的乘积来形成样本的似然,其中每个密度函数将被计算用于样本的一个元素。 / p>

(在概念上,似乎就像扔两次骰子一样。在超丑的条件下,我们可以说连续得到两个的可能性可能是(1/6)(1/6)。)

我们希望最大化这种可能性。然而,为了使数学和/或计算上易于处理的优化问题,我们采用函数的对数。由于其所有组成函数都是密度,小于1,因此该函数必须小于零。因此,最大化问题变成了最小化问题。

如果你想避免几乎所有的代数,那么你会:

  • 编写一个函数来计算给定直径和参数值的密度函数。
  • 编写另一个函数,它接受密度函数参数值作为其Python参数,样本作为其第二个参数。让它为每个样本值调用一次函数,记下每个样本的日志并返回这些函数的总和。
  • 使用第二个函数作为第一个参数调用minimize,对列表中的密度函数参数进行一些合理的猜测,作为第二个参数,args的样本。 Nelder-Mead可能还可以。

编辑:简而言之:

diameters =[ 0.19, 0.19, 0.19, 0.2, 0.21, 0.21, 0.22, 0.22, 0.22, 0.25, 0.27]

from scipy.optimize import minimize
from math import exp, log

def pdf(d, a):
    result = d*exp(-d/a)/a**2
    return result

def log_L(a, diameters):
    result = sum(log(pdf(d, a)) for d in diameters)
    return result

res = minimize(log_L, [1], args=diameters)

print (res)

输出:

      fun: -337.80985348524604
 hess_inv: array([[  8.71770021e+10]])
      jac: array([ -7.62939453e-06])
  message: 'Optimization terminated successfully.'
     nfev: 93
      nit: 30
     njev: 31
   status: 0
  success: True
        x: array([ 2157576.39996697])

附录:

维基百科文章为指数的pdf提供了以下表格。

exponential

常量'lambda'可以看作是一个值,它将表达式其余部分的积分从零缩放到无穷大。我们可以忽略它并将你的pdf的指数等同,而不是缩放因子和指数。我们必须记住,d扮演x

的角色

equation

解决'lambda'。

expression for lambda

我们看到这是pdf中的规范化表达式。换句话说,alpha是用不同参数表示的指数。

答案 1 :(得分:0)

这是另一种方法,假设您正在分析数据而不是简单地计算出MLE的细节。

scipy提供了从任意分布生成样本的方法。在这里,我只为你的alpha定义pdf。您的参数a变为p,因为a用作分配支持的下限,我将其定义为零。

我绘制了一个大小为100的样本,其中p有点任意设置为0.4。我做了一些实验,试图找到一个值,它会给我一个样本,其最低的11个值将近似于样本中的值。

scipy rv_continuous对象有一个名为fit的方法,它将尝试计算位置,比例和“形状”的MLE估计值。在这种情况下,形状值约为0.36,与0.4相差不远。

from scipy.stats import rv_continuous
import numpy as np

class Alpha(rv_continuous):
    'alpha distribution'
    def _pdf(self, x, p):
        return x*np.exp(-x/p)/p**2

alpha = Alpha(a=0, shapes='p')
sample = sorted(alpha.rvs(size=100,p=0.4))
for a in sample[:12]:
    print ('{:10.2f}'.format(a))

print (Alpha(a=0, shapes='p').fit(sample))

我不相信你的样本是alpha分布式的。这些价值观似乎过于统一了。与我能产生的相比。但我以前错了。

我建议您绘制示例cdf以查看是否可以识别它是什么。

顺便说一句,当我在另一个答案中更改了对数似然符号时,代码就会嘶哑。我怀疑,这只不合适。

      0.00
      0.03
      0.04
      0.04
      0.08
      0.09
      0.09
      0.11
      0.12
      0.14
      0.19
      0.20
(1.0902616847853124, -0.039102949269294023, 0.35922022997329517)