#python #python-3.x #scipy #scipy-optimize-minimize
Вопрос:
Код:
def minimize_vol_ver2(rets, d, **kwargs):
n = rets.cov().shape[0]
init_guess = np.repeat(1/n, n)
# construct the constraints
def cons1(weights):
return 15.0 - np.sum(weights>0)
def cons2(weights):
return np.sum(weights) - 1.0
def cons3(weights):
return 1.0 - np.sum(weights)
def cons4(weights):
return weights
cons = ([
{'type': 'ineq', 'fun': cons1},
{'type': 'ineq', 'fun': cons2},
{'type': 'ineq', 'fun': cons3},
{'type': 'ineq', 'fun': cons4}
])
weights = minimize(portfolio_vol, init_guess,
args=(rets, d), method='SLSQP',
options={'disp': False},
constraints=cons)
weights = pd.Series(weights.x, index=rets.columns)
return weights.round(2)
Проблема: Оптимизатор не удовлетворяет 1-му ограничению, т. е. минусам1, в основном у меня есть список доходностей для 50 акций, и я использую scipy.optimize.minimize для минимизации волатильности портфеля со следующими ограничениями:
- количество весов, превышающих 0, должно быть меньше или равно 15
- Сумма весов должна быть равна 1
- Неотрицательные веса
Основываясь на приведенном выше коде, оптимизатор удовлетворяет ограничениям 2 и 3, но терпит неудачу в течение 1
Пожалуйста, помогите!!
Комментарии:
1. Это не сработает. Это ограничение (дважды) не дифференцируемо и делает недействительным то, о чем просит scipy.minimize. Подобные ограничения (почти) всегда подразумевают необходимость в методах дискретной оптимизации (где scipy сильно отсутствует). Я думаю, что этот частный случай иногда называют оптимизацией с ограничением мощности, и должна быть доступна некоторая литература (показывающая, что большинство этих проблем становятся NP-трудными). Часто люди просто используют некоторые прокси-потери, которые могут работать на практике (для борьбы с NP-жесткостью): например, l1-норма (которая также не дифференцируема, но с этим можно справиться с помощью трюков с переформулировкой)