我在scipy.minimize中使用SLSQP解算器来解决约束优化问题。解算器通常会尝试违反约束的参数值。当违反这些约束时,目标函数返回nan
。这似乎会带来问题,因为我的近似雅可比人几乎每次重新计算时都会充满nan
。通常情况下,优化会在exit mode 8: Positive directional derivative for linesearch
中终止。我怀疑近似雅可比行列式中的nan
是这个的源头。我的问题是scipy.minimize如何处理nan
?它们是良性的,还是应该转换为大的(甚至是无限的)数字?据我所知,Scipy文档中的任何地方都没有涉及此信息。
答案 0 :(得分:0)
有一个非常先进的最小化例程Minuit,该例程在粒子物理学界使用,与您提到的例程相似。他们都使用准牛顿法来估计二阶导数,以便尝试在最少的迭代次数中“跳”到最小。
这些方法通常不处理边值问题,并且存在一类完全不同的算法,用于最小化带约束的函数。
话虽如此,在Minuit中可以设置参数边界。在Minuit中实现此目标的方法非常聪明。本质上,每个参数都“内部”映射到:
p_int = arcsin(2*(p_ext-a)/(b-a)-1)
和
p_ext = a + ((b-a)/2)*(sin(p_int)+1)
其中a
和b
分别是上限和下限。有关更多详细信息,请参见Minuit手册Python docs。
我怀疑您可以在假设每个参数都具有线性范围的情况下执行类似的操作。
答案 1 :(得分:0)
scipy
中有nans
中有检查项,具体取决于您使用的搜索算法。您必须检查每种搜索算法的来源。它通常不会影响最小化(除非您使用非歧视性方法),但实际上会搞砸最大化。通常,scipy
使用numpy
数组启动。理解发生了什么的最好方法是使用以下简单示例:
>>> x = [-np.nan, np.nan, 1, 2, 3, np.nan] # some random sequence of numbers and nans
>>> np.sort(x)
array([ 1., 2., 3., nan, nan, nan])
np.nan
总是被视为最大的数字,因此,您必须在搜索算法中明确考虑到这一点,以便将来的迭代中不考虑这些解决方案。关于解释+/- nans
,请参见this,如果后端实现是在fortran中实现的-有时就是这种情况。