scipy的可变参数数量用L-BFGS-B算法优化

时间:2013-09-11 15:13:47

标签: python optimization

我正在寻找使用可变数量参数作为scipy中优化器输入的正确方法。

我有一组输入参数p1,...,pn,我用函数func(p1,...,pn)计算质量标准。我想最小化这个值。

输入参数为0或1表示应该使用它们。我不能简单地从参数列表中删除所有未使用的,因为我的质量标准函数要求它们为“0”以从方程中删除未使用的项。

def func(parameters):
    ...calculate one scalar as quality criteria...

solution = optimize.fmin_l_bfgs_b(func,parameters,approx_grad=1,bounds=((0.0, 5.0),...,(0.0,5.0)) # This will vary all parameters

在我的代码中,优化器运行时没有错误,但当然所有给定的参数都会更改以获得最佳解决方案。

有没有办法让... func的10个输入参数,但在优化器中只使用了5个?

到目前为止,我只能想到以一种不需要来自未使用参数的“0”输入的方式更改我的func定义。我会很感激如何避免这种想法。

非常感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

如果我理解正确,那么您要求的是最适合的约束,这样您就可以找到效果最好的[p0,p1,p2...p10],而不是为func()找到最佳[p0, p1, ...p5]。在func()等条件下的函数p6=fixed6, p7=fixed7, p8=fixed8...

如果您在python中使用args=(somthing),则可以将其转换为scipy.optimize.fmin_l_bfgs_b代码。首先,编写一个部分修复的函数func_fixed()

def func_fixed(p_var, p_fixed):
    return func(p_var+p_fixed) 
# this will only work if both of them are lists. If they are numpy arrays, use hstack, append or similar

solution = optimize.fmin_l_bfgs_b(func_fixed,x0=guess_parameters,\
                                  approx_grad=your_grad,\
                                  bounds=your_bounds,\
                                  args=(your_fixed_parameters), \ #this is the deal
                                  other_things)

没有必要func_fixed(),您可以使用lambda。但这种方式读起来要容易得多。

答案 1 :(得分:0)

我最近解决了一个类似的问题,我希望在每次运行时优化不同的参数子集,但需要所有参数来计算目标函数。我在目标函数中添加了两个参数:

  1. 索引数组x_idx,其指示要优化的参数,即0不优化和1优化
  2. 具有所有参数初始值的数组x0
  3. 在目标函数中,我根据索引数组将参数列表设置为要优化的参数或初始值。

    import numpy 
    import scipy.optimize
    
    def objective_function(x_optimised, x_idx, x0):
        x = []
        j = 0
        for i, idx in enumerate(x_idx):
            if idx is 1:
                x.append(x_optimised[j])
                j = j + 1
            else:
                x.append(x0[i])
        x = numpy.array(x)
        return sum(x**2)
    
    if __name__ == '__main__':
        x_idx = [1, 1, 0]
        x0 = [1.1, 1.3, 1.5]
    
        x_initial = [x for i, x in enumerate(x0) if x_idx[i] is 1]
        xopt, fopt, iter, funcalls, warnflag = scipy.optimize.fmin(objective_function, \
                                                       x_initial, args=(x_idx, x0,), \
                                                       maxfun = 200, full_output=True)
        print xopt