Деленное на ноль, встречающееся при выполнении минимизации в python

#python #error-handling #scipy

Вопрос:

У меня есть следующий фрагмент кода (часть большего кода):

 import numpy as np
from scipy.stats import multivariate_normal 
from scipy.optimize import minimize as scipy_min

def f_loglike(x):
    pmean = [1.54379044]
    pCov = [[0.00013136]]
    return -np.log(multivariate_normal(pmean[0],pCov).pdf(x))

scipy_min(f_loglike, 1, method='Nelder-Mead', tol=1e-6)
 

Когда я запускаю его, я получаю 2 предупреждения: RuntimeWarning: divide by zero encountered in log и RuntimeWarning: invalid value encountered in subtract np.max(np.abs(fsim[0] - fsim[1:])) <= fatol):

и вывод функции будет:

 final_simplex: (array([[1.],
   [1.]]), array([inf, inf]))
       fun: inf
   message: 'Maximum number of function evaluations has been exceeded.'
      nfev: 200
       nit: 67
    status: 1
   success: False
         x: array([1.])
 

Я не уверен, что происходит (или как это отладить). Это должно быть просто минимум a — гаусса (или максимум Гаусса), что тривиально (ответ должен быть pmean). Кроме того, в формуле для Гаусса, учитывая, что ковариация (или стандартное отклонение в данном случае) фиксирована, нет места, где я мог бы получить какое-либо деление на ноль, поэтому первое предупреждение для меня не имеет смысла. Может ли кто-нибудь помочь мне понять, что происходит и как это исправить? Спасибо!

Комментарии:

1. В документации для минимизации говорится, что она использует функцию градиента, поэтому я подозреваю, что она предназначена для использования, когда f является «гладкой» функцией. По сути, вы передаете ему список случайных чисел.

2. @FrankYellin что вы подразумеваете под случайными числами? Функция-np.log(многомернонормальная(pmean[0],pCov).pdf(x)) является гладкой (это журнал Гаусса). Если я сделаю x = np.arange(-10,10,0.01) и построю эту функцию по сравнению с x, я получу гладкую функцию

3. Извините. Моя вина. Я пропустил, что вы звонили в pdf(). Не обращай внимания на мой комментарий.

Ответ №1:

Я немного изменил функцию на основе документации SciPy и немного изменил начальное условие. У меня есть что-то, что работает, возможно, потому, что начальное условие начиналось в месте, которое давало нулевое значение в аргументе log() . Вот что у меня есть, но я не знаю, то ли это, что вы искали:

 import numpy as np
from scipy.stats import multivariate_normal 
from scipy.optimize import minimize as scipy_min

def f_loglike(x):
    pmean = [1.54379044]
    pCov = [[0.00013136]]
    return -np.log(multivariate_normal.pdf(x,pmean[0],pCov))

print(scipy_min(f_loglike, 1.5, method='Nelder-Mead', tol=1e-6))
 

Он возвращается:

 final_simplex: (array([[1.54379025],
       [1.54379082]]), array([-3.54984592, -3.54984592]))
           fun: -3.549845922780753
       message: 'Optimization terminated successfully.'
          nfev: 36
           nit: 18
        status: 0
       success: True
             x: array([1.54379025])