我正在尝试对向量 [a1,a2,a3] 执行最小二乘优化,具有以下约束,其中k
是一个常数:
-k < a3/a2 < k
我将发布我的代码的简化版本,希望这可以清楚地说明我所追求的。
from scipy import optimize
def loss_function(a_candidate):
return MyObject(a_candidate).mean_square_error()
def feasibility(a_candidate):
# Returns a boolean
k = 1.66711
a2 = a_candidate[1]
a3 = a_candidate[2]
return -k < a3/a2 < k
def feasibility_scipy(a_candidate):
# As I understand it, for SciPy the constraint has to be a number
boolean = feasibility(a_candidate)
if boolean:
return 0
else:
return 1
# Equality constraint forcing feasibility_scipy to be 0.
constraint = optimize.NonlinearConstraint(feasibility_scipy, 0, 0)
optimize_results = optimize.minimize(
loss_function,
a_init, # Initial guess
constraints=constraint)
由于初始猜测的生成方式,它位于是a_init
的区域。(我们首先需要使用数值方法的原因是,早期的封闭式方法返回了一个不可行的解决方案。可以提供一个非常糟糕的可行猜测,例如 (0,0,0),但这会很多远离真正的解决方案)。feasibility
False
由于constraint
' 的梯度几乎在所有地方都为零,因此优化例程无法找到离开这个不可行(不可接受)区域的方法,并且它不会成功终止。它仅在SLSQP
1 次迭代后停止,并带有 message Singular matrix C in LSQ subproblem
。使用trust-constr
求解器,它达到了函数评估的最大次数,并且我相信它没有离开不可行区域,因为constr_violation
是1.0
。
据我了解,在 SciPy 中不可能在 and 上提供“联合绑定”(对发明术语表示歉意)a2
,a3
这意味着我被迫使用这种NonlinearConstraint
方法。
这样做的正确方法是什么?(一些搜索表明我可能想尝试mystic
带有符号约束的包。但在我花时间学习这个新包之前,我想看看 StackOverflow 是否有基于 SciPy 的解决方案。或者如果你知道怎么做这在mystic
一些示例代码中会非常有帮助。)