Я пытаюсь свернуть функцию с помощью scipy.optimize.minimize с помощью метода SLSQP.Но иногда происходит сбой с сообщением об ошибке «Превышен лимит итераций» или «Положительная производная по направлению для linesearch», для того же самого ввода.
Пример, который только что произошел: у меня это работает на сервере Flask, поэтому яинициализировал его и отправил запрос, не удалось (предел итерации).Я отправил много одного и того же запроса, не выключая флягу, он не удался с каждым из них.Затем я перезапустил колбу.Внезапно ВСЕ запросы были успешно оптимизированы, я продолжал отправлять их, и они никогда не подводили.Но если я перезапущу колбу снова, она может перестать работать, или нет, она кажется случайной, но если она работала один раз, она будет работать вечно, пока сервер не будет перезапущен.
Но даже когда он один изэкземпляр сервера, на котором работает оптимизатор, все еще работает для менее сложных входных данных.
Контекст проблемы: я пытаюсь оптимизировать портфель фондового рынка с учетом таких ограничений, как волатильность.Обычно он терпит неудачу, когда он превышает 500 000 долларов США.
con = {"type": "eq", "fun": self.sum}
con2 = {"type": "ineq", "fun": self.volatility_ceiling}
con3 = {"type": "ineq", "fun": self.volatility_floor}
cons = (con, con2, con3)
#allocation_list is a list of percentages for each stock in the portfolio
optimized_result = minimize(self.gain, allocation_list, constraints=cons, bounds=self.bounds, method="SLSQP", options={"maxiter": 400})
def gain(self, allocation_list):
gain_list = [get_gain(id) for id in self.id_list]
gain_avg = np.average(gain_list, weights=allocation_list)
return (gain_avg) * (-1)
def sum(self, allocation_list):
return np.sum(allocation_list) - 1
def volatility_ceiling(self, allocation_list):
standard_dev = self.vol_portfolio(lista_aloc)
if self.current_risk_profile == "PROFILE_1":
return (standard_dev * (-1)) + 0.009
elif self.current_risk_profile == "PROFILE_2":
return (standard_dev * (-1)) + 0.011
elif self.current_risk_profile == "PROFILE_3":
return (standard_dev * (-1)) + 0.015
elif self.current_risk_profile == "PROFILE_4":
return (standard_dev * (-1)) + 0.024
#The function continues until PROFILE_10
def volatility_ceiling(self, allocation_list):
standard_dev = self.vol_portfolio(allocation_list)
if self.current_risk_profile == "PROFILE_1":
return standard_dev - 0.0
elif self.current_risk_profile == "PROFILE_2":
return standard_dev - 0.009
elif self.current_risk_profile == "PROFILE_3":
return standard_dev - 0.011
elif self.current_risk_profile == "PROFILE_4":
return standard_dev - 0.015
#The function continues until PROFILE_10