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

Math scipy.optimize.minimize不断返回数学错误,超出范围,math,optimization,random,scipy,distribution,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

我使用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的起始值(存储在一个名为“初始猜测”的列表中,该列表作为“param”参数提供给NLL2函数),我必须找到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
终端现在打印的内容示例如下:

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.120.1.00000001]

所以,不知怎的,参数会达到我设定的界限的极限,在最后一个例子中,实际上会超过1e-8。这会导致密度函数返回一个微小的负数,从而导致崩溃

有人知道我怎样才能阻止极小化者这么做吗?我也尝试过使用SLSQP方法,但遇到了同样的问题

我很抱歉,如果我提供了太多的细节,但我很累,我也想提供任何可能有用的信息


注意:我已将数学类导入为mt.

而没有进一步分析您的问题:如果您确定密度输出应为正值,则始终可以剪裁密度输出。例如,
np.clip(x,0+eps,np.inf)
。当然,这可能会有一些副作用。@11天哪,你可以尝试直接优化可能性(而不是它的日志版本)。不幸的是,我的作业要求我最小化可能性的对数。不需要进一步分析你的问题:如果你确定密度输出应该是正的,你可以随时剪裁密度输出。例如,
np.clip(x,0+eps,np.inf)
。当然,这可能会有一些副作用。@11天哪,你可以尝试直接优化可能性(而不是它的日志版本)。不幸的是,我的作业要求我最小化可能性的对数。