【问题标题】:Scipy SLSQP constrained optimization doesn't always workScipy SLSQP 约束优化并不总是有效
【发布时间】:2018-11-20 23:51:22
【问题描述】:

我正在尝试使用 SLSQP 方法使用 scipy.optimize.minimize 最小化函数。但有时对于完全相同的输入,它会失败并显示错误消息“超出迭代限制”或“线搜索的正方向导数”。

刚刚发生的示例:我让它在 Flask 服务器上运行,所以我初始化它并发送请求,它失败了(迭代限制)。我在没有关闭 Flask 的情况下发送了很多相同的请求,每一个请求都失败了。然后,我重新启动了 Flask。突然间,所有请求都成功优化了,我不断发送它们,它们从未失败过。但是如果我再次重新启动 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

【问题讨论】:

  • 很确定问题出在其他地方。 SLSQP 应该是确定性的。在代码中寻找不确定的部分。老实说:没有代码的 SO 问题通常不是很好。当然,SLSQP 可能会失败(确定性地),但这是特定于问题/使用的。市场投资组合,嗯,我认为其中许多是人们不会使用 SLSQP 的凸问题。但谁知道你到底在做什么。
  • 谢谢,我已经用代码更新了我的问题。

标签: python python-3.x scipy mathematical-optimization


【解决方案1】:

我建议修改模型中的美元“单位”。例如,在表示预算时,不是“美元”而是“千美元”。为此,请使用“500”而不是“500,000”,并相应地解释结果。例如,如果从可用预算中为一项资产分配了“3.5”个单位,这将对应于 3,500 美元,依此类推……

作为一般模型原则,如果数字的数值范围很广,则模型的缩放比例会很差,并且会引发数值问题。大多数商业优化器都会发出警告,提醒您采取措施改进扩展。如果模型是线性的(有或没有整数变量),优化器通常会尝试改进缩放本身。例如,

https://www.lindo.com/doc/online_help/lingo15_0/205_themodelispoorlyscaled_.htm

对于黑盒类型的非线性模型,这些功能可能不可用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-16
    • 2014-07-13
    • 2019-11-17
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 2019-02-10
    • 1970-01-01
    相关资源
    最近更新 更多