Scipy Minimize - 无法最小化目标函数 [英] Scipy Minimize - Unable to minimize objective function

查看:124
本文介绍了Scipy Minimize - 无法最小化目标函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 scipy 最小化优化函数以查找 rev_tot 的最大值.这里obj_data 是一个概率列表,prem 是一个常数,inc 可以取任何实际值.以下是我为目标函数编写的代码:

将 numpy 导入为 np将熊猫导入为 pd进口scipy从 scipy.optimize 导入最小化定义目标(x,* args):prem = args[0]概率 = args[1]公司 = x[0]rev_tot = 0转速 = 0del_p = 0.2*(1-np.exp(-2*(1-np.exp(-inc/400))))对于我在范围内(len(概率)):rev = (prob[i]*(1+del_p)*prem) - increv_tot = rev_tot + rev返回 1/rev_tot预付款 = 3300par = [0.9,0.1,0.5,0.4]x0 = np.array([3]) # 初始猜测解决 = 最小化(目标,x0,args=(prem,par),method='SLSQP')解决.x

我想找到使 1/rev_tot 最小化的 inc 值(从而最大化 rev_tot.当我打电话时:

minimize(objective,x0,args=(prem,par),method='SLSQP')

函数运行,但 solve.x 显示初始值没有变化.我无法弄清楚为什么没有发生最小化.

解决方案

您的问题是由于您的 return 1/rev_tot,求解器必须处理微小的数字.因此,x 轴上的变化不能很好地反映在 y 值的变化中,求解器估计它已经收敛:

将 numpy 导入为 np将熊猫导入为 pd进口scipy从 scipy.optimize 导入最小化定义目标(x,* args):prem = args[0]概率 = args[1]公司 = x[0]rev_tot = 0转速 = 0del_p = 0.2*(1-np.exp(-2*(1-np.exp(-inc/400))))对于我在范围内(len(概率)):rev = (prob[i]*(1+del_p)*prem) - increv_tot = rev_tot + rev返回 1/rev_tot预付款 = 3300par = [0.9,0.1,0.5,0.4]x0 = np.array([2]) # 初始猜测解决 = 最小化(目标,x0,args=(prem,par),method='SLSQP')x_min = solve.x打印(x_min)#绘制您的函数以可视化结果x_func = np.linspace(1, 100, 1000)y_func = []对于 x_func 中的项目:y_func.append((objective(np.asarray([item]), prem, par)))y_min = 目标(np.asarray([x_min]),prem,par)plt.plot(x_func, y_func)plt.plot(x_min, y_min, "ro")plt.show()

输出:

<代码>[2.]

解决方案1)

解决方案2)
使用求解器SLSQP"的 return 1000000/rev_tot 放大您的返回值.输出:

[63.07110511]

I am trying to optimise a function to find max value of rev_tot using scipy minimise. Here obj_data is a list of probabilities, prem is a constant and inc can take any real value. Following is the code I have written for the objective function :

import numpy as np
import pandas as pd
import scipy
from scipy.optimize import minimize

def objective(x,*args):

    prem = args[0]
    prob = args[1]
    inc = x[0]


    rev_tot = 0
    rev = 0
    del_p = 0.2*(1-np.exp(-2*(1-np.exp(-inc/400))))
    for i in range(len(prob)):
        rev = (prob[i]*(1+del_p)*prem) - inc
        rev_tot = rev_tot + rev
    return 1/rev_tot


prem = 3300
par = [0.9,0.1,0.5,0.4]
x0 = np.array([3]) # initial guess
solve = minimize(objective,x0,args=(prem,par),method='SLSQP')
solve.x

I want to find the inc value which will minimize 1/rev_tot(and thus maximising rev_tot. When I call:

minimize(objective,x0,args=(prem,par),method='SLSQP')

the function runs, but solve.x shows no change in initial value. I am unable to figure out why the minimisation is not happening.

解决方案

Your problem is that the solver has to deal with tiny numbers due to your return 1/rev_tot. Hence changes over the x-axis are not well reflected in changes in y-values and the solver estimates that it has already converged:

import numpy as np
import pandas as pd
import scipy
from scipy.optimize import minimize

def objective(x,*args):

    prem = args[0]
    prob = args[1]
    inc = x[0]

    rev_tot = 0
    rev = 0
    del_p = 0.2*(1-np.exp(-2*(1-np.exp(-inc/400))))
    for i in range(len(prob)):
        rev = (prob[i]*(1+del_p)*prem) - inc
        rev_tot = rev_tot + rev
    return 1/rev_tot

prem = 3300
par = [0.9,0.1,0.5,0.4]
x0 = np.array([2]) # initial guess
solve = minimize(objective,x0,args=(prem,par),method='SLSQP')
x_min = solve.x
print(x_min)
#plot your function to visualize the outcome
x_func = np.linspace(1, 100, 1000)
y_func = []
for item in x_func:
    y_func.append((objective(np.asarray([item]), prem, par)))

y_min = objective(np.asarray([x_min]), prem, par)

plt.plot(x_func, y_func)
plt.plot(x_min, y_min, "ro")
plt.show()

Output:

[2.]

Solution 1)
Different solvers manage certain problems better than others. Change your solver to "Nelder-Mead". Output:

[63.07910156]

Solution 2)
Scale up your return value with return 1000000/rev_tot for solver "SLSQP". Output:

[63.07110511]

这篇关于Scipy Minimize - 无法最小化目标函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆