使用LinearConstraint调用scipy minimize报错:对象不可迭代
解决
LinearConstraint对象不可迭代/不可下标访问的错误 问题场景
尝试基于相关矩阵,使用LinearConstraint配合minimize执行最小化操作时,出现'LinearConstraint' object is not iterable或'LinearConstraint' object is not subscriptable错误。
所用相关矩阵(DataFrame格式):
col1 col2 col3 1 1.00 0.59 0.68 2 0.59 1.00 0.92 3 0.68 0.92 1.00
执行代码:
from scipy.optimize import minimize, LinearConstraint import numpy as np A0 = [.3,.4,.3] bnds = [(1, 1) for i in range(len(A0))] def test(w): return (w@np.matrix(corr))@w temp=minimize(test,A0,constraints=(LinearConstraint(np.array([1,1,1]),lb=1.0,ub=1.0), ))
运行后报错:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) C:\Program Files\Anaconda3\lib\site-packages\scipy\optimize\slsqp.py in _minimize_slsqp(func, x0, args, jac, bounds, constraints, maxiter, ftol, iprint, disp, eps, callback, **unknown_options) 253 try: --> 254 ctype = con['type'].lower() 255 except KeyError: TypeError: 'LinearConstraint' object is not subscriptable During handling of the above exception, another exception occurred: TypeError Traceback (most recent call last) <ipython-input-331-ce6c477d5282> in <module> 8 return (w@np.matrix(corr))@w 9 ---> 10 temp=minimize(test,A0,constraints=(LinearConstraint(np.array([1,1,1]),lb=1.0,ub=1.0), )) C:\Program Files\Anaconda3\lib\site-packages\scipy\optimize\_minimize.py in minimize(fun, x0, args, method, jac, hess, hessp, bounds, constraints, tol, callback, options) 609 elif meth == 'slsqp': 610 return _minimize_slsqp(fun, x0, args, jac, bounds, --> 611 constraints, callback=callback, **options) 612 elif meth == 'trust-constr': 613 return _minimize_trustregion_constr(fun, x0, args, jac, hess, hessp, C:\Program Files\Anaconda3\lib\site-packages\scipy\optimize\slsqp.py in _minimize_slsqp(func, x0, args, jac, bounds, constraints, maxiter, ftol, iprint, disp, eps, callback, **unknown_options) 256 raise KeyError('Constraint %d has no type defined.' % ic) 257 except TypeError: --> 258 raise TypeError('Constraints must be defined using a ' 259 'dictionary.') 260 except AttributeError: TypeError: Constraints must be defined using a dictionary.
错误原因
scipy.optimize.minimize的默认优化方法是SLSQP,该方法不支持直接传入LinearConstraint对象,要求约束必须以字典形式定义;而LinearConstraint是专为trust-constr优化方法设计的约束类型。
解决方法
方法1:使用trust-constr方法
在minimize调用中指定method='trust-constr'参数,即可直接使用LinearConstraint对象:
from scipy.optimize import minimize, LinearConstraint import numpy as np A0 = [.3,.4,.3] bnds = [(1, 1) for i in range(len(A0))] def test(w): return (w@np.matrix(corr))@w # 指定method为trust-constr temp=minimize(test,A0,constraints=(LinearConstraint(np.array([1,1,1]),lb=1.0,ub=1.0), ), method='trust-constr')
方法2:改用字典形式定义约束(适配默认SLSQP方法)
如果希望继续使用默认的SLSQP优化器,将约束转换为字典格式,指定type、fun等字段:
from scipy.optimize import minimize import numpy as np A0 = [.3,.4,.3] bnds = [(1, 1) for i in range(len(A0))] def test(w): return (w@np.matrix(corr))@w # 用字典定义线性约束:sum(w) = 1 constraint = { 'type': 'eq', 'fun': lambda w: np.sum(w) - 1 } temp=minimize(test,A0,constraints=(constraint, ))
内容的提问来源于stack exchange,提问作者Sanchit Aluna
相关产品推荐
相关产品推荐

