Сципи.Оптимизировать.Минимизировать, не удовлетворяя одному из ограничений

#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 для минимизации волатильности портфеля со следующими ограничениями:

  1. количество весов, превышающих 0, должно быть меньше или равно 15
  2. Сумма весов должна быть равна 1
  3. Неотрицательные веса

Основываясь на приведенном выше коде, оптимизатор удовлетворяет ограничениям 2 и 3, но терпит неудачу в течение 1

Пожалуйста, помогите!!

Комментарии:

1. Это не сработает. Это ограничение (дважды) не дифференцируемо и делает недействительным то, о чем просит scipy.minimize. Подобные ограничения (почти) всегда подразумевают необходимость в методах дискретной оптимизации (где scipy сильно отсутствует). Я думаю, что этот частный случай иногда называют оптимизацией с ограничением мощности, и должна быть доступна некоторая литература (показывающая, что большинство этих проблем становятся NP-трудными). Часто люди просто используют некоторые прокси-потери, которые могут работать на практике (для борьбы с NP-жесткостью): например, l1-норма (которая также не дифференцируема, но с этим можно справиться с помощью трюков с переформулировкой)