python - Scipy 最小化 - 创建约束以使 20 个中只有 5 个
问题描述
我在周末学习使用 scipy 最小化,并在下面遇到了这段代码。本网站的所有学分http://apmonitor.com/che263/index.php/Main/Python优化
我的问题是......有没有办法设置一个约束,将解决方案限制为在 x0 中只有 2 个非零元素?
在我的问题中,x0 是假设股票组合的权重。这些乘以各自的个股收益。我有 20 只股票可供选择,但我只想在我的最终投资组合中最多有 5 只股票(共 20 只),同时将风险降至最低。
我想要得到的可能看起来像这样:
x0 = [0, 0, 0, 0.2, 0, 0, 0, 0, 0.2, 0.2, 0.2, 0.2, 0, 0, 0, 0, 0, 0, 0, 0]
我的权重数组中只有 5 个非零值。
Ps 如果这是一个简单的问题,我很抱歉,我在空闲时间自学python。
import numpy as np
from scipy.optimize import minimize
def objective(x):
return x[0]*x[3]*(x[0]+x[1]+x[2])+x[2]
def constraint1(x):
return x[0]*x[1]*x[2]*x[3]-25.0
def constraint2(x):
sum_eq = 40.0
for i in range(4):
sum_eq = sum_eq - x[i]**2
return sum_eq
# initial guesses
n = 4
x0 = np.zeros(n)
x0[0] = 1.0
x0[1] = 5.0
x0[2] = 5.0
x0[3] = 1.0
# show initial objective
print('Initial Objective: ' + str(objective(x0)))
# optimize
b = (1.0,5.0)
bnds = (b, b, b, b)
con1 = {'type': 'ineq', 'fun': constraint1}
con2 = {'type': 'eq', 'fun': constraint2}
cons = ([con1,con2])
solution = minimize(objective,x0,method='SLSQP',\
bounds=bnds,constraints=cons)
x = solution.x
# show final objective
print('Final Objective: ' + str(objective(x)))
# print solution
print('Solution')
print('x1 = ' + str(x[0]))
print('x2 = ' + str(x[1]))
print('x3 = ' + str(x[2]))
print('x4 = ' + str(x[3]))
解决方案
这是不可能的。
scipy.minimize 是关于持续优化的,并且有很强的假设,包括约束+目标的两倍可微性。在其核心中,所有这些算法都属于(一般)非线性优化(NLP)领域。
这与您具有分离性质的用例相矛盾。有关比您的问题更简单的问题的含义,请参阅整数编程。
虽然投资组合问题通常是凸二次规划或二阶锥问题(与 NLP 相比这是一个限制),但人们通常使用专门的求解器,与 NLP 求解器(利用额外的假设)相比,它的性能和鲁棒性要高得多。凸性还意味着易处理性(多项式复杂性)。
但是由于析取性质,QP/SOCP 求解器在这里是不够的。你需要去:
- 混合整数 QP / SOCP(如果问题兼容)
- MINLP
求解器。
然后,凸性的易处理性就丢失了(析取的)!
这些求解器在 scipy 中不可用。并且少数可用的非商业求解器并不那么容易设置(尤其是在 Windows 上)。一些候选者:Bonmin(凸 MINLP;非凸情况下的启发式解决方案)或Couenne(非凸 MINLP)。OSQP可以工作,但我持怀疑态度(尤其是关于它的分支定界实现)。osqp 的好处是,安装应该很容易。
您可能会得到一些搜索基数约束优化的想法。示例:斯坦福讲座
一般凸基数问题是 (NP-) 困难的
(该链接还显示了一些现实世界中以任务为中心的启发式方法,以使问题易于处理:L1-norm)
如果您不想探索组合优化的复杂世界并且有一些耐心 + 该示例反映了您的用例,您可以对所有选择组合运行优化(在 [0,0] 中强制变量边界所有未选择的变量)并选择最佳结果。对于您的 <= 20 中的 5,这将导致 ~ 20000 次优化。
推荐阅读
- reactjs - 当匹配 url 嵌套路由器不起作用
- javascript - javascript 从地图中检索值
- amazon-redshift - 如何按顺序运行 sql 语句?
- node.js - Node JS 中的哈希密码用于 MongoDB 中已有的密码
- linux - (Linux) 用另一个文件中的数据递归地覆盖文件夹中的所有文件
- sql - 棘手的 SQL Server 分组
- unix - 用于获取特定列等于给定变量的文件行的 AWK 或 bash 脚本
- python - AttributeError:模块“apache_beam”没有属性“DoFn”
- blazor-webassembly - 在 Blazor Web 程序集组件中嵌入 Github Gists
- java - Jgit 抛出 java.io.IOException:为 /.config/jgit 创建目录失败