【问题标题】:The following code for minimizing a function returns a RuntimeWarning. Why?以下用于最小化函数的代码返回 RuntimeWarning。为什么?
【发布时间】:2021-10-01 12:17:02
【问题描述】:

我这几天一直在学习优化方法。我编写的以下代码返回了RuntimeWarning

import numpy as np
from scipy.optimize import minimize

def func(a, x):
    return 1 + (x - 0.5) * a

def log_like(a, x):
    sum1 = 0 
    for i in range(len(x)):
        sum1 += np.log(func(a, x[i]))
    return sum1
    
def log_like_prime(a, x):
    sum1 = 0
    for i in range(len(x)):
        sum1 += (x[i] - 0.5) / (1 + (x[i] - 0.5) * a)
    return sum1

def log_like_prime2(a, x):
    sum1 = 0
    for i in range(len(x)):
        sum1 += -(x[i] - 0.5) ** 2.0 / (1 + (x[i] - 0.5) * a) ** 2.0
    return sum1

x = [0.89, 0.03, 0.50, 0.36, 0.49]
a = -1
a_opt = minimize(
    log_like, a, args=(x,), method="Newton-CG",
    jac=log_like_prime, hess=log_like_prime2
)
print(a_opt)

返回以下错误:

fun: array([0.03194467])
     jac: array([0.18690836])
 message: 'Warning: Desired error not necessarily achieved due to precision loss.'
    nfev: 21
    nhev: 1
     nit: 0
    njev: 21
  status: 2
 success: False
       x: array([-1.])
py:17: RuntimeWarning: invalid value encountered in log
  sum1 += np.log(func(a, x[i]))
py:17: RuntimeWarning: invalid value encountered in log
  sum1 += np.log(func(a, x[i]))

对于x = [0.89, 0.03, 0.50, 0.36, 0.49]的给定值不应返回无效值,对数部分内的函数不得返回负值。我不明白为什么会出现这样的问题。

【问题讨论】:

  • 您确定要最小化函数而不是最大化它吗? x 的选择没有本地最低要求。

标签: python scipy scipy-optimize-minimize


【解决方案1】:

您对a 的初始猜测为-1,对所有i 给出严格的正值func(a, x[i])

但是 scipy 的最小化算法会改变 a 的值(这就是它找到更好值的方式)。在这里,它趋向于更大的负值,最终导致 func(a, x[i]) 的负值,从而导致日志错误。

调试(我同意scipy在这里不友好)尝试在脚本开头写np.seterr(all='raise'),然后日志中引发的警告将转换为错误,然后输入%debug% in the next ipython cell, you'll be able to check the value of a`:

~/miniconda3/lib/python3.8/site-packages/scipy/optimize/_differentiable_functions.py in fun_wrapped(x)
     68         def fun_wrapped(x):
     69             self.nfev += 1
---> 70             return fun(x, *args)
     71 
     72         def update_fun():

~/tmp.py in log_like(a)
     12     sum1 = 0
     13     for i in range(len(x)):
---> 14         sum1 += np.log(func(a, x[i]))
     15     return sum1
     16 

FloatingPointError: invalid value encountered in log

In [21]: %debug
> /home/mathurin/tmp.py(14)log_like()
     12     sum1 = 0
     13     for i in range(len(x)):
---> 14         sum1 += np.log(func(a, x[i]))
     15     return sum1
     16 

ipdb> a
a = array([-2.7761329])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-11-29
    • 2013-03-30
    • 2020-02-24
    • 2017-05-07
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多