Scipy SLSQP约束优化并不总是有效

时间:2018-06-11 16:53:09

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

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

刚刚发生的例子:我让它在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

1 个答案:

答案 0 :(得分:1)

我建议修改'单位'在你的模型中的美元。例如,而不是'美元'切换到数千美元'在代表预算时。为此,请使用' 500'而不是' 500,000',并相应地解释结果。例如,如果分配了' 3.5'单位是从可用预算中获得的资产,这相当于3,500美元等等......

作为一般模型原理,如果数字的数值范围很大,则模型的缩放比例很小,这是对数值问题的邀请。大多数商业优化器都会发出警告,警告您采取措施来改善扩展。如果模型是线性的(有或没有整数变量),优化器通常会尝试改进自身的缩放。例如,

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

对于黑盒型非线性模型,可能无法使用此类功能。