Python 程序错误和有关最大对数可能性的问题

Python 程序错误和有关最大对数可能性的问题,python,statistics,Python,Statistics,我试图计算以下概率密度函数(PDF)的最大对数似然(MLE): 我通过最小化目标函数(负对数似然)来计算它,而不依赖任何预定义的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))

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

我通过最小化目标函数(负对数似然)来计算它,而不依赖任何预定义的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…)

第一个问题:由于我对最大似然估计的主题相当陌生,我的数据向量的形式正确吗?我不完全确定我使用的是包含每个观测直径的数据向量(如上图所示),还是只包含“可能”直径的数据向量(即:0.19、0.2、0.21、0.22、0.25、0.27…),或者只是观察直径的频率(即:3、1、2、3、1、1…)。我认为第一个选择是正确的,但我只是想完全确定

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

然而,为了在python中实现最小化(如果我理解正确的话),我不得不重新考虑变量的定义。这意味着,通常我会假设PDF的参数(这里是“a”和“scale”)是应该在“optimize.minimize”中传递给“args”的变量。然而,在文档中指出,args应该包含“常量”参数,因此我将数据向量用作最小化的常量“参数向量”

第三个问题:这是一个推理错误吗?

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

最后,程序返回一个错误“TypeError:bad Operator type for One Ary-:‘tuple’”,我不知道如何处理它,因为我没有将任何元组传递给最小化函数

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

如果您能给我任何帮助,我将不胜感激

致以最良好的祝愿


PS:由于这篇文章是一般数学和编程的混合体,我不完全确定这是否是提出问题的正确地方。对不起,如果我弄错了

首先,除了第一部分(在乘法运算符之前),我们正在讨论通常称为最大似然估计(MLE)的算法。它刚刚被重新参数化为一种叫做a的东西

我们希望根据直径样本估计该单个参数;没有比例参数。在最大似然估计下,我们假设样本是固定的,并将参数视为可以变化的。我们通过取密度函数(而不是CDF)的乘积来形成样本的可能性,其中每个密度函数将针对样本的一个元素进行计算

(从概念上讲,可能性就像掷骰子两次。用非常难看的术语来说,我们可以说连续两次掷骰子的可能性可能是(1/6)(1/6)。)

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

如果你想避开几乎所有的代数,那么你应该:

  • 编写一个函数来计算给定直径和参数值的密度函数
  • 编写另一个函数,该函数将接受密度函数参数值作为其Python参数,并将示例作为其第二个参数。让它为每个样本值调用第一个函数一次,获取每个样本值的日志并返回它们的总和
  • 调用
    minimize
    ,将第二个函数作为其第一个参数,对密度函数参数进行合理猜测,在列表中,将
    args
    的示例作为第二个参数。内尔德·米德可能没问题
编辑:简而言之:

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格式

常数“lambda”可以被视为一个值,该值将表达式剩余部分的积分从零缩放到无穷大,再缩放到一。我们可以忽略它,将pdf的指数(不含比例因子)与指数相等。我们必须记住,
d
扮演
x
的角色

求解“lambda”


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

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

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

我画了一个大小为100的样本,其中
p
任意设置为0.4。我做了一些实验,试图找到一个值,这个值可以给我一个样本,它的最低11个值与你的样本中的值相近

scipy rv_连续对象有一种称为“拟合”的方法,该方法将尝试计算位置、比例和“形状”的最大似然估计。在这个
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))
      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)