scipy.optimize.minimize不断返回数学错误,超出范围

时间:2017-04-07 19:31:59

标签: math optimization random scipy distribution

我使用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。

0 个答案:

没有答案