【问题标题】:Using fixed parameters using scipy.optimize.minimize使用 scipy.optimize.minimize 使用固定参数
【发布时间】:2019-01-23 22:50:44
【问题描述】:

我目前正在使用 scipy optimize.minimize 来获取具有 5 个参数的函数的最小值。我希望将其中四个输入作为函数的固定参数放入,并且我希望 optimize.minimize 为我提供第五个输入的值,以便从函数中获得尽可能低的输出。

这是我目前拥有的代码:

from numpy import array
import scipy.optimize as optimize
from scipy.optimize import minimize

def objective(speed, params):
    a,b,c,d=params
    return abs(rg.predict([[speed,params]]))

p0=np.array([[98.3,46.9,119.9,59.1]])

x0=np.array([[4]])
result = optimize.minimize(objective, x0, args=(p0,),method='nelder-mead')
print(result.x)

我正在寻找一种能够在 optimize.minimize 函数中传递固定参数列表或数组的方法。但是上面的代码给了我这个错误:

ValueError: not enough values to unpack (expected 4, got 1)

我似乎可以让它工作的唯一方法是在输入中硬编码,如下所示:

def objective(params):
 a=100
 b=20
 c=119.9
 d=params
 e=59.1
 return abs(rg.predict([[a,b,c,d,e]]))

x0=np.array([[4.5]])
result = optimize.minimize(objective, x0, method='nelder-mead')
print(result.x)

我是否以正确的方式处理这个问题?如何将列表或数组作为固定输入传递?

【问题讨论】:

    标签: python optimization scipy minimize


    【解决方案1】:

    作为args 传递的元组将作为*args 传递给目标函数。如果您按照您的方式定义目标函数,它需要一个输入参数(除了要最小化的speed),因此将单元素元组(p0,) 作为args 关键字传递给minimize 是完美的。您的错误出现在函数调用之后:

    ValueError: not enough values to unpack (expected 4, got 1)
    

    这实际上来自目标函数的第一行:

    a,b,c,d=params # params = np.array([[98.3,46.9,119.9,59.1]])
    

    作为p0 传递的数组有两组方括号,因此它的形状为(1,4)。数组沿着它们的第一个维度解包,因此在解包过程中,它的行为就像一个 1 元组(包含一个 4 元素数组)。这就是为什么您不能将形状 (1,4) 解压缩为四个变量,因此会出现错误。

    这基本上是一个错字(一对方括号太多),不值得完整回答。毕竟我写这篇文章的原因是因为根据您的用例,直接在函数的签名中定义这些参数可能更容易,并在最小化期间​​相应地传递这些参数:

    def objective(speed, a, b, c, d):
        ... # return stuff using a,b,c,d
    
    # define a0, b0, c0, d0 as convenient
    result = optimize.minimize(objective, x0, args=(a0,b0,c0,d0), method='nelder-mead')
    

    这样定义函数是否更优雅取决于如何轻松定义固定参数以及objective 中的这些参数会发生什么。如果您只是要像在 MCVE 中那样传递参数列表,那么首先不需要分离这些变量,但是如果这四个输入在计算中的涉及非常不同,那么处理每个输入可能是有意义的从您的目标函数的定义开始。

    【讨论】:

    • 谢谢!!当我将参数直接放入 args 时,它确实有效。不过,我还有另一个问题。当我确实保持其余代码相同并尝试删除额外的括号时,我收到此错误:ValueError: setting an array element with a sequence.
    • @DanaMcDowelle 您可能必须比这更具体:您要在哪里删除括号?当您尝试将非标量分配给数组元素时,通常会发生该错误,例如arr = np.arange(3); arr[0] = [1,2]。除了我不知道可能是什么的未定义的rg.predict 调用之外,我在您的代码中看不到任何类似的东西:)
    【解决方案2】:

    这些是线性约束,形式为Ax = b。例如, 假设我们要保持前两个变量x0, x1(你的a, b)固定:

    A = [[ 1 0 0 ... ]
         [ 0 1 0 ... ]]
    b = [b0 b1]
    

    有一种通用的方法可以解决线性约束问题Ax = b 对于较少变量的无约束问题,在这个例子中n - 2, 在my gists 下使用SVD.
    minlin.py 是此过程的 numpy SVD 的一页包装。其文档:

    """ Minlin: convert linear-constrained min f(x): Ax = b
    to unconstrained min in fewer variables.
    For example, 10 variables with 4 linear constraints, A 4 x 10,
    -> 6 unconstrained variables:
    
    minlin = Minlin( A, b, bigfunc, verbose=1 )   # bigfunc( 10 vars )
    then
    minimize( minlin.littlefunc, minlin.y0 ... )  # littlefunc( 6 vars )
        with your favorite unconstrained minimizer. For example,
    
    from scipy.optimize import minimize
    res = minimize( minlin.littlefunc, minlin.y0 ... )
    fbest = res.fun
    ybest = res.x  # 6 vars
    xbest = minlin.tobig(ybest)  # 10 vars
        = minlin.x0  + y . nullspace  from svd(A)
        x0 = Ainv b = lstsq( A, b )
    
    Methods: .func(x) .tonullspace(X) .torowspace(X) .tobig(y)
    Attributes: .sing .Vt .Vtop .Vnull .x0
    
    How it works, in a simple case:
    consider holding x0 = b0, x1 = b1 fixed, i.e.
    A = [[ 1 0 0 ... ]
         [ 0 1 0 ... ]]
    We can minimize unconstrained over the n - 2 variables [x2 x3 ...]
    if we could find them / find a basis for them, given just A.
    This is what SVD / Minlin does.
    """
    

    这对您的问题来说可能是多余的。 但是,好问题—— 环顾四周,试图通过 5d 了解粗糙的国家 只改变你理解的几个变量, 是一件好事。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-30
      • 2015-07-20
      • 2019-11-01
      • 2020-12-02
      • 2015-03-18
      • 2019-03-31
      • 1970-01-01
      • 2014-03-03
      相关资源
      最近更新 更多