我试图计算以下概率密度函数(PDF)的最大对数似然(MLE):
我通过最小化目标函数(负对数似然)来计算它,而不依赖于任何预定义的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:由于这篇文章是一般数学和编程之间的混合,我不能完全确定这是否是提出问题的正确位置。对不起,如果我错了!
答案 0 :(得分:0)
首先,除了第一部分(乘法运算符之前)之外,我们正在讨论exponential distribution通常所说的最大似然估计(MLE)。它刚刚被称为 a 。
的东西被重新参数化我们想根据直径样本估算这个单参数;没有比例参数。在MLE下,我们假装样本是固定的,并将参数视为可以变化的东西。我们通过获取密度函数( not cdfs)的乘积来形成样本的似然,其中每个密度函数将被计算用于样本的一个元素。 / p>
(在概念上,似乎就像扔两次骰子一样。在超丑的条件下,我们可以说连续得到两个的可能性可能是(1/6)(1/6)。)
我们希望最大化这种可能性。然而,为了使数学和/或计算上易于处理的优化问题,我们采用函数的对数。由于其所有组成函数都是密度,小于1,因此该函数必须小于零。因此,最大化问题变成了最小化问题。
如果你想避免几乎所有的代数,那么你会:
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提供了以下表格。
常量'lambda'可以看作是一个值,它将表达式其余部分的积分从零缩放到无穷大。我们可以忽略它并将你的pdf的指数等同,而不是缩放因子和指数。我们必须记住,d
扮演x
。
解决'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)