Ошибка CVXPY при попытке решить задачу выпуклой минимизации / двоичного программирования

Я пытаюсь решить проблему, которую я отправил в QSE, https://quant.stackexchange.com/questions/65680/find-k-of-n-assets-that-minimize-the-correlation-matrix/, но я сталкиваюсь с проблема с использованием cvxpy lib. А именно, то, что я считаю проблемой выпуклого двоичного программирования, как утверждает cvxpy, не соответствует правилам DCP.

Проблема, которую я пытаюсь решить, заключается в следующем: из заданных 10 рискованных активов найти 5 наименее коррелированных. Моя текущая методология решения этой проблемы

  1. Получите доход от каждого актива
  2. Найдите корреляционную матрицу C для этих доходов.
  3. Formulate the convex optimization problem as
    • x is a binary vector
    • сумма записей x равна 5
    • C' = transpose(C * x) * x - это матрица, в которой i-я строка и i-й столбец C обнуляются, когда i-я запись x равна 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 (чтобы обойти ограничение с двумя атрибутами). Я не могу вспомнить, почему это не сработало.
  • Используя двоичную матрицу переменной cvxp X и ограничения, что сумма каждой i -й строки равна 5 и что i-я строка равна j -ому столбцу. У меня были проблемы с этим, потому что тестирование X[i] == X[:i] создает логический массив, который я не знал, как уменьшить с помощью cvxpy.
  • Я также пробовал использовать не -двоичный вектор переменной cvxpy x и пытался ограничить i-е значение x равным 0 или 1, но ограничение x[i] == 0 || x[i] == 1 недействительно из-за _28 _ - Я также не удалось найти условие логического или cvxpy.

Итак, я попытался переформулировать это несколькими разными способами, но постоянно сталкиваюсь с проблемами с каждой стратегией. Мне интересно, может ли кто-нибудь мне помочь

  1. Определите, действительно ли это проблема, которую может решить cvxpy. Если это не так, как я могу изменить его, чтобы решить, по сути, то, что я хочу? Если это что-то, что cvxpy может решить
  2. Что я могу сделать с моим текущим кодом, чтобы исправить его проблемы?

Спасибо за ваше время.


person geofflittle    schedule 25.06.2021    source источник


Ответы (1)


Я думаю, что C 'не матрица, а скаляр:

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

(Я использую 'для транспонирования здесь) Значит, сумма квадратов не имеет особого смысла?

Может ли ваша проблема быть просто проблемой портфеля с ограничением количества элементов?

Или обтекаемый:

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

Строки и столбцы C, соответствующие выбранным активам в x, являются подматрицей, которую вы ищете.

person Erwin Kalvelagen    schedule 26.06.2021
comment
Привет, Эрвин, спасибо, что заглянули. Я не знаком с проблемой портфеля мощности, но я посмотрю. Мое намерение состоит в том, чтобы C 'не был скаляром, поэтому, если это то, что создается, это моя ошибка. Мое намерение состоит в том, чтобы кандидат C 'был в основном сокращенной / разреженной версией C, где строки и столбцы C, которые связаны с отклоненными активами в кандидате x (представленном 0), все установлены в 0. Итак, есть должен по-прежнему быть матрицей, но в действительности намного меньше, чем C. - person geofflittle; 26.06.2021