【问题标题】:scipy.optimize.minimize with general array indexingscipy.optimize.minimize 与通用数组索引
【发布时间】:2016-01-31 23:41:24
【问题描述】:

我想用 scipy.optimize.minimize 中的“COBYLA”方法解决一个优化问题,如下所示:

test = spopt.minimize(testobj, x_init, method='COBYLA', constraints=cons1)
y = test.x
print 'solution x =', y

但是,由于程序非常大,编写目标函数(和约束)的可扩展方式是使用参数的通用索引。例如,如果我可以使用x['parameter1']x.param1 而不是x[0],那么程序将更易于阅读和调试。我尝试将x 写为对象或使用x['parameter1'] 之类的通用索引编写pandas Series,如下所示:

def testobj(x):
    return x['a']**2 + x['b'] + 1

def testcon1(x):
    return x['a']

def testcon2(x):
    return x['b']

def testcon3(x):
    return 1 - x['a'] - x['b']


x_init = pd.Series([0.1, 0.1])
x_init.index = ['a','b']

cons1 = ({'type': 'ineq', 'fun': testcon1}, \
    {'type': 'ineq', 'fun': testcon2}, \
    {'type': 'ineq', 'fun': testcon3})

但每当我将它传递给minimize 例程时,它都会引发错误:

return x['a']**2 + x['b'] + 1
ValueError: field named a not found

如果我使用普通的 numpy 数组,它会完美运行。也许我做得不对,但这是我必须使用 numpy 数组而不是任何其他数据结构的最小化函数的限制吗? this topic 上的 scipy 文档提到初始猜测必须是 ndarray,但我很好奇例程如何调用参数,因为对于 pandas Series,使用 x[0]x['a'] 调用变量是等效的。

【问题讨论】:

  • 您可以为您的参数向量编写一个对象包装器并在您的计算中使用它。
  • 当我在谷歌上搜索对象包装器时,有没有可以借鉴的小例子?

标签: optimization pandas indexing scipy minimize


【解决方案1】:

如您所述,scipy optimize 使用 numpy 数组作为输入,而不是 pandas 系列。当您使用 pandas 系列进行初始化时,它会有效地将其转换为数组,因此您无法再按名称访问字段。

可能最简单的方法是创建一个函数,每次调用参数时重新包装参数;例如:

def make_series(params):
    return pd.Series(params, index=['a', 'b'])

def testobj(x):
    x = make_series(x)
    return x['a']**2 + x['b'] + 1

def testcon1(x):
    x = make_series(x)
    return x['a']

def testcon2(x):
    x = make_series(x)
    return x['b']

def testcon3(x):
    x = make_series(x)
    return 1 - x['a'] - x['b']

x_init = make_series([1, 1])
test = spopt.minimize(testobj, x_init, method='COBYLA', constraints=cons1)
print('solution x =', test.x)
# solution x = [  1.38777878e-17   0.00000000e+00]

【讨论】:

  • 但方式略有不同。我将'a''b'01 的映射存储在一个名为x_ind(比如说)的熊猫系列中,并用x[x_ind['a']] 调用向量x
猜你喜欢
  • 2012-11-21
  • 2010-10-28
  • 2019-03-22
  • 2019-03-31
  • 2016-06-02
  • 1970-01-01
  • 2018-05-02
  • 1970-01-01
  • 2011-05-23
相关资源
最近更新 更多