【问题标题】:scipy.optimize.shgo ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()scipy.optimize.shgo ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all()
【发布时间】:2019-07-30 16:06:38
【问题描述】:

我正在尝试拟合函数 y(x,T,p) 以获取系数 a,b,c,d,e,fy,x,T,p 的数据是已知的。使用全局优化器,我想找到一个好的起点。 shgo 似乎是唯一接受constraints 的人。

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import shgo

# test data
x = np.array([0.1,0.2,0.3,1])
T = np.array([300,300,300,300])
p = np.array([67.2,67.2,67.2,67.2])
y = np.array([30,50,55,67.2])

# function
def func(pars,x,T,p):
    a,b,c,d,e,f = pars
    return x*p+x*(1-x)*(a+b*T+c*T**2+d*x+e*x*T+f*x*T**2)*p

# residual
def resid(pars):
    return ((func(pars,x,T,p) - y) ** 2).sum()

# constraint: derivation is positive in every data point
def der(pars):
    a,b,c,d,e,f = pars
    return -p*((3*f*T**2+3*e*T+3*d)*x**2+((2*c-2*f)*T**2+(2*b-2*e)*T-2*d+2*a)*x-c*T**2-b*T-a-1)

con1 = ({'type':'ineq', 'fun':der})

# minimizer shgo
bounds = [(-1,1),(-1,1),(-1,1),(-1,1),(-1,1),(-1,1)]
res = shgo(resid, bounds, constraints=con1)
print("a = %f , b = %f, c = %f, d = %f, e = %f, f = %f" % (res[0], res[1], res[2], res[3], res[4], res[5]))

# plotting
x0 = np.linspace(0, 1, 100)
fig, ax = plt.subplots()
fig.dpi = 80
ax.plot(x,y,'ro',label='data')
for i,txt in enumerate(T):
    ax.annotate(txt,(x[i],y[i]))
ax.plot(x0, func(res.x, x0, 300,67.2), '-', label='fit1')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()

有了这个我得到ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() 我不知道那个错误是什么意思,其他具有相同错误的线程并不能真正帮助我理解。当我使用本地最小化器(scipy.optimize.minimize 和方法cobyla)时,不会出现错误。

有人可以帮助我了解我的问题,甚至帮助解决它吗? 谢谢

编辑:

Traceback (most recent call last):
  File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 759, in __getitem__
    return self.cache[x]
KeyError: (0, 0, 0, 0, 0, 0)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:/Users/.../test.py", line 70, in <module>
    res = shgo(resid, bounds, constraints=con1)
  File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo.py", line 423, in shgo
    shc.construct_complex()
  File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo.py", line 726, in construct_complex
    self.iterate()
  File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo.py", line 869, in iterate
    self.iterate_complex()
  File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo.py", line 890, in iterate_hypercube
    self.g_args)
  File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 121, in __init__
    self.n_cube(dim, symmetry=symmetry)
  File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 172, in n_cube
    self.C0.add_vertex(self.V[origintuple])
  File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 767, in __getitem__
    index=self.index)
  File "C:\Users\...\Python\Python36\site-packages\scipy\optimize\_shgo_lib\triangulation.py", line 681, in __init__
    if g(self.x_a, *args) < 0.0:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

【问题讨论】:

  • 如果您想测试除 shgo 之外的其他优化器,您可以尝试在函数中实现“砖墙”以返回一个大错误 - 例如 1.0E10 - 如果违反了任何给定的约束.虽然初始参数估计必须在允许优化器开始的约束范围内,但这种简单的技术有时在实践中非常有用。
  • 如果您显示错误回溯会有所帮助,因此我们可以(和您)看到错误发生的位置。在简单的真/假测试中使用数组时会发生这样的错误。我怀疑这与con1 约束有关,例如def 返回一个数组而不是单个值。但我们确实需要回溯。
  • 我已经编辑了我的帖子。

标签: python scipy curve-fitting


【解决方案1】:

问题是,der 返回一个数组而不是一个标量值。改变

con1 = ({'type':'ineq', 'fun':der})

con_list = [{'type':'ineq', 'fun': lambda x: der(x)[i_out]} for i_out in range(T.shape[0])]

删除错误。这会将der 的每个输出转换为它自己的不等式约束。

【讨论】:

    猜你喜欢
    • 2020-05-12
    • 2016-01-26
    • 2014-04-06
    • 2020-01-28
    相关资源
    最近更新 更多