繁体   English   中英

使用scipy.optimize.minimize()的Ineq和eq约束

[英]Ineq and eq constraints with scipy.optimize.minimize()

我试图了解scipy.optimize.minimize约束的行为:

首先,我创建了4种资产和100种回报方案。 平均回报资金最好是使D > B > A > C变差

#seed first 
np.random.seed(1)

df_returns = pd.DataFrame(np.random.rand(100,4) - 0.25, columns =list('ABCD'))
df_returns.head()

    A           B           C           D
0   0.167022    0.470324    -0.249886   0.052333
1   -0.103244   -0.157661   -0.063740   0.095561
2   0.146767    0.288817    0.169195    0.435220
3   -0.045548   0.628117    -0.222612   0.420468
4   0.167305    0.308690    -0.109613   -0.051899

和一组权重

weights = pd.Series([0.25, 0.25, 0.25, 0.25], index=list('ABCD'))

    0
A   0.25
B   0.25
C   0.25
D   0.25

我们创建一个目标函数:

def returns_objective_function(weights, df_returns):
    result = -1. * (df_returns * weights).mean().sum()
    return result

和约束与界限

cons = ({'type': 'eq', 'fun': lambda weights: np.sum(weights) -1  })
bnds = ((0.01, .8), (0.01, .8), (0.01, .8), (0.01, .75))

让我们优化

optimize.minimize(returns_objective_function, weights, (df_returns),
                              bounds=bnds, constraints=cons, method= 'SLSQP')

And we get success.
  status: 0
 success: True
    njev: 8
    nfev: 48
     fun: -0.2885398923185326
       x: array([ 0.01,  0.23,  0.01,  0.75])
 message: 'Optimization terminated successfully.'
     jac: array([-0.24384782, -0.2789166 , -0.21977262, -0.29300382,  0.        ])
     nit: 8

现在,我想添加一个从基本不等式开始的约束:

scipy.optimize.minimize文档状态

等式约束表示约束函数结果为零,而不等式表示约束函数结果为非负数。

cons = ( 
        {'type': 'eq', 'fun': lambda weights: np.sum(weights) -1  }
        ,{'type': 'ineq', 'fun': lambda weights: np.sum(weights) + x}
)

根据x,我得到了意外的行为。

x = -100

根据边界,权重最大为3.15,并且当然必须通过第一个等式约束np.sum(weights) - 1 ,但结果np.sum(weights) + x会永远是负面的。 我相信找不到解决方案,但scipy.optimize.minimize成功返回。

使用更简单的模型,我得到相同的行为:

x = [1,2] 
optimize.minimize(
    lambda x: x[0]**2+x[1]**2, 
    x, 
    constraints = (
        {'type':'eq','fun': lambda x: x[0]+x[1]-1},
        {'type':'ineq','fun': lambda x: x[0]-2}
                  ),
    bounds = ((0,None),(0,None)),
    method='SLSQP')

结果:

   nfev: 8
    fun: 2.77777777777712
    nit: 6
    jac: array([  3.33333334e+00,   2.98023224e-08,   0.00000000e+00])
      x: array([  1.66666667e+00,   1.39888101e-14])
success: True
message: 'Optimization terminated successfully.'
 status: 0
   njev: 2

应该有一些标志,表明这是不可行的解决方案。

R也可以提供SLSQP:

> slsqp(c(1,2),
+       function(x) {x[1]^2+x[2]^2},
+       heq=function(x){x[1]+x[2]-1},
+       hin=function(x){x[1]-2},
+       lower=c(0,0))
$par
[1] 1.666667e+00 4.773719e-11

$value
[1] 2.777778

$iter
[1] 105

$convergence
[1] -4

$message
[1] "NLOPT_ROUNDOFF_LIMITED: Roundoff errors led to a breakdown of the optimization algorithm. In this case, the returned minimum may still be useful. (e.g. this error occurs in NEWUOA if one tries to achieve a tolerance too close to machine precision.)"

至少我们在这里看到一些警告信号。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM