我在尝试最小化一个很长的函数(它是500000个子函数的总和),以便将一些参数拟合到概率模型中。我使用scipy.optimize.minimize
函数。我尝试了Powell
和Nelder-Mead
算法,Powell在我的设置中看起来确实更快。但尽管如此,我真的不明白如何强迫这个过程在给定的时间后给予我一些结果,即使它们不是“最优的”。
我填写了选项maxiter
,maxfev
,xtol
和ftol
,但我并不真正理解这些选项,因为我试图把一个print
在我的函数,我注意到,算法评估它超过maxfev
次,但当它达到最大点,它发送一个错误“达到最大迭代次数”.
关于我正在使用的两个算法,它们是如何工作的?文档非常不清楚。
我的代码:
def log_likelihood(r, alpha, a, b, customers):
if r <= 0 or alpha <= 0 or a <= 0 or b <= 0:
return -np.inf
c = sum([log_likelihood_individual(r, alpha, a, b, x, tx, t) for x, tx, t in customers])
print -c
return c
negative_ll = lambda params: -log_likelihood(*params,customers=customers)
params0 = (1, 1, 1, 1)
res = minimize(negative_ll, params0, method='Powell', callback=print_callback, options={'disp': True, 'ftol':0.05, 'maxiter':3, 'maxfev":15})
1条答案
按热度按时间iecba09b1#
您可能应该在scipy邮件列表中,甚至在scipy开发人员邮件列表中询问这个问题,但是查看Nelder-Mead算法的源代码时,我注意到对
maxiter
和maxfev
的实际检查是在外部while循环中进行的。因此函数求值的实际次数很容易超过maxfev
. Powell方法的主循环中也发生了类似的情况.对于该方法,看起来在测试求值次数(N
参数的数目)之前函数被求值N
次。我猜这样做是因为否则会有太多的
if
语句在核心循环内检查maxfev
,并且它被认为是更快/更清楚的条件外的内部循环。