我使用scipy.opimize.minimize为数据集的负对数似然(具有给定的pdf)找到最佳拟合参数。计算pdf和负对数似然的函数如下:
def density(time, x, y, z):
w = (z/x)*mt.exp(-time/x) + ((1-z)/y)*mt.exp(-time/y)
return w
def NLL2(params):
sig = 0
a, b, c = params[0], params[1], params[2]
for i in range(0, 100):
sig = sig - mt.log(density(xval[i], a, b, c))
return sig
其中xval是数据集(0-10之间的100时间值列表)。对于它的价值,pdf是双重衰变过程。
我已经获得了x,y和z的起始值(存储在名为&#34的列表中; initial_guesses"它被赋予NLL2函数作为" param"参数),以及我必须找到x,y和z的最佳拟合值(即给定数据集xval最小化NLL2的那些值)。
我尝试使用以下代码行执行此操作:
initial_guesses = [1.30719636, 0.19783642, 0.25150731]
best_fit = sci.optimize.minimize(NLL2, initial_guesses, bounds = [(0.1, 20), (0.1, 20), (0.1, 1)], method = 'L-BFGS-B').x
已经选择了界限,因为我认为"想出来的是[1.3,0.2,0.25],即接近初始值。但是,当我这样做时,我经常会收到此错误消息:
文件" newcode2.py",第125行,在NLL2中 sig = sig - mt.log(密度(xval [i],x,y,z)) ValueError:数学域错误
我知道这种情况正在发生,因为对数被认为是负值,但是我给予最小化器的界限应该可以防止这种情况发生。
为了进一步调查,我将NLL2功能更改为以下内容:
def NLL2(params):
sig = 0
a, b, c = params[0], params[1], params[2]
for i in range(0, 100):
if density(xval[i], a, b, c) > 0:
sig = sig - mt.log(density(xval[i], a, b, c))
else:
print density(xval[i], a, b, c), xval[i], params, '\n'
return sig
终端打印出来的示例如下:
-4.25654045048e-10 2.76533572107 [0.1 20. 1.00000001]
所以不知何故,参数会达到我设定的界限,在最后一种情况下实际超过1e-8。这导致密度函数返回一个微小的负数,这导致崩溃。
有谁知道如何阻止最小化器这样做?我也尝试过使用SLSQP方法,但遇到了同样的问题。
如果我提供了太多详细信息,我道歉,但我感到很累,而且我还想提供任何可能有用的信息。
注意我已将数学课导入为mt。