【问题标题】:CVXPY error when trying to solve a convex minimization / binary programming problem尝试解决凸最小化/二进制编程问题时出现 CVXPY 错误
【发布时间】:2021-06-25 19:58:48
【问题描述】:

我正在尝试解决我提交给 QSE https://quant.stackexchange.com/questions/65680/find-k-of-n-assets-that-minimize-the-correlation-matrix/ 的问题,但我在使用 cvxpy 库时遇到了问题。即,我认为是一个凸二进制编程问题,cvxpy 说的是“不遵循 DCP 规则”。

我要解决的问题是:“从给定的 10 种风险资产中,找出相关性最低的 5 种”。我目前解决这个问题的方法是

  1. 获取每项资产的回报
  2. 找到这些回报的相关矩阵C
  3. 将凸优化问题公式化为
    • x 是二元向量
    • x的条目总和为5
    • C' = transpose(C * x) * x 是一个矩阵,其中Cith 行和ith 列在i 的第i 条目为0 时“清零”(而不是清零)否则)。注意:我想知道这是否是我的问题出现的地方。这是我能想到的从相关矩阵 C 中删除与“被拒绝”资产相对应的条目的最佳方法。
    • 最后,我想最小化C' 的平方和。这将为我提供类似 5 个相关性最低的资产的投资组合。

以下是我到目前为止的非工作代码。

import pandas as pd
import pandas_datareader as web
import datetime as dt
import cvxpy as cvx

stocks = ['SHW', 'GOOG', 'AMZN', 'WMT', 'XOM', 'JNJ', 'UPS', 'AMT', 'AAPL', 'NEE']
start = dt.datetime(2015, 1, 1)
end = dt.datetime(2020, 1, 1)
d = web.DataReader(stocks, 'yahoo', start, end)['Adj Close']
corr = d.corr().to_numpy()

x = cvx.Variable(len(stocks), boolean=True)
cost = cvx.sum_squares((corr @ x).T @ x)
prob = cvx.Problem(cvx.Minimize(cost), [cvx.sum(x) == 5])
prob.solve(solver='ECOS_BB')

以及它产生的错误

DCPError: Problem does not follow DCP rules. Specifically:
The objective is not DCP. Its following subexpressions are not:

# The corr array

我还尝试以多种无效的方式重新表述这一点,包括

  • 使用 cvxp 变量矩阵X,它具有 cvxpy 属性布尔和对称。如果它是对称的并且每行总和为 5,那么我有一个矩阵,我可以对其进行逐元素乘法以找到 C'。这不起作用,因为一个变量只允许一个属性(奇怪的 cvxpy 限制)。
  • 使用 cvxp 变量二进制矩阵 X 和 cvxp 变量对称矩阵 Y 并包括约束 X == Y(以绕过 2 属性限制)。我不记得为什么这不起作用。
  • 使用 cvxp 变量二进制矩阵 X 并约束每 ith 行的总和为 5,并且 ith 行等于 jth 列。我遇到了麻烦,因为测试 X[i] == X[:i] 会产生一个布尔数组,我不知道如何使用 cvxpy 来减少它。
  • 我还尝试使用 -二进制 cvxpy 变量向量 x 并尝试将 xith 值约束为 0 或 1,但约束 @987654348 @ 无效,因为 ||--我也找不到 cvxpy 逻辑或条件。

因此,我尝试以几种不同的方式重新表述这一点,但我总是遇到每种策略的问题。我想知道是否有人可以帮助我

  1. 确定这是否真的是 cvxpy 可以解决的问题。如果不是,我该如何更改它以从根本上解决我想要的问题?如果是cvxpy能解决的问题
  2. 我可以用我当前的代码做什么来纠正它的问题?

感谢您的宝贵时间。

【问题讨论】:

    标签: python logic cvxpy integer-programming convex-optimization


    【解决方案1】:

    我认为 C' 不是矩阵而是标量:

    transpose(C * x) * x = (Cx)'x=x'C'x=x'Cx
    

    (我在这里使用'转置)所以这个平方和没有多大意义?

    您的问题可能只是基数受限的投资组合问题吗?

    或精简:

      min x'Cx
      sum(x) = k
      x ∈ {0,1}
    

    x中所选资产对应的C行和列就是你要找的子矩阵。

    【讨论】:

    • 您好 Erwin,感谢您的浏览。我不熟悉基数投资组合问题,但我会看看。我的意图是让 C' 不是一个标量,所以如果这是正在生成的,那就是我的错误。我的意图是让候选 C' 基本上成为 C 的简化/稀疏版本,其中与候选 x 中的被拒绝资产相关联的 C 的行和列(由 0 表示)都设置为 0。所以有应该仍然是一个矩阵,但实际上比 C 小得多。
    猜你喜欢
    • 2020-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    相关资源
    最近更新 更多