ValueError:对象太深,无法在 optimize.curve_fit 中找到所需数组

Posted

技术标签:

【中文标题】ValueError:对象太深,无法在 optimize.curve_fit 中找到所需数组【英文标题】:ValueError: object too deep for desired array in optimize.curve_fit 【发布时间】:2019-01-02 11:05:33 【问题描述】:

我正在尝试为化学系统中四个变量 A、B、C、D 的人口增长和衰减拟合动力学模型。我正在尝试求解以下以矩阵形式附加的方程组:

Matrix form of equations

其中 t 是时间步长,k1,k2,k3 是指数函数中的常数。考虑到我的 A、B、C、D 人口,我想根据这些方程拟合曲线来求解 k1、k2 和 k3。

为此,我使用了 optimize.curve_fit,t 是 (1000,) 数组中的时间步长,X 是 (4,1000) 矩阵,其中 u 和 w 是两个矩阵:

from scipy import optimize

def func(t,X,k1,k2,k3):

    u = np.array([[1,0,0],
                  [-k1/(k1+k2-k3),k1/(k1+k2-k3),0],
                  [(k1*k3)/((k1+k2-k3)*(k1+k2)),-k1/(k1+k2k3),k1/(k1+k2)],
                  [-k2/(k1+k2),0,k2/(k2+k1)]],dtype=float)

    w = np.array([[np.exp(-t*(k1+k2))],
                 [np.exp(-t*k3)],
                 [1]])

    return X*np.dot(u,w)


X = np.array([A,B,C,D]) # A,B,C,D are (1000,) arrays
# X.shape = (4, 1000)
# t.shape = (1000,)

optimize.curve_fit(func,t,X,method='lm')

当我运行这段代码时,我得到以下输出:

ValueError: 对象对于所需数组来说太深

错误:函数调用的结果不是正确的浮点数组。

我在similar 帖子中看到数组的形状很重要,但据我所知,这些都是正确的。

谁能建议这段代码中的问题可能出在哪里,以及我如何才能最好地使用曲线拟合函数求解 k1、k2、k3?

谢谢

【问题讨论】:

至少有几个问题:func 不需要X 参数,你的t 是x 参数。此外,矩阵w 中的第 3 个元素的长度为 1,它的长度应为 1,000 以匹配上面的其他 2 个元素 啊,是的 - X 在这里是一个变量名;我应该称它为“Y”,因此我的 x 参数是 t ,而我的 y 参数是 Y,其中 Y 是形状矩阵 (4,1000)。对于矩阵w的第三个元素,我只希望它是一个常数,这样当与矩阵u取点积时,u中的第三列作为常数返回。 你的函数签名是func(t,X,k1,k2,k3)curve_fit 将第一个参数之后的 所有 参数视为要拟合的参数。所以它试图适应Xk1k2k3 这能回答你的问题吗? What does "ValueError: object too deep for desired array" mean and how to fix it? 【参考方案1】:

正如我在评论中提到的,您无需将X 传递给func。 @WarrenWeckesser 简要解释了原因。所以func 应该是这样的:

def func(t,k1,k2,k3):

    u = np.array([[1,0,0],
                  [-k1/(k1+k2-k3),k1/(k1+k2-k3),0],
                  [(k1*k3)/((k1+k2-k3)*(k1+k2)),-k1/(k1+k2*k3),k1/(k1+k2)],
                  [-k2/(k1+k2),0,k2/(k2+k1)]],dtype=float)

    w = np.array([np.exp(-t*(k1+k2)),
                 np.exp(-t*k3),
                 np.ones_like(t)]) # must match shapes with above 

    return np.dot(u,w).flatten()

最后的输出是展平的,否则它会给出curve_fit 的错误。现在我们对其进行测试:

from scipy.optimize import curve_fit
t = np.arange(1000)*0.01
data = func(t, *[0.5, 2, 1])
data +=np.random.normal(size=data.shape)*0.01 # add some noise
po, pcov = curve_fit(func,t, data.flatten(), method='lm') #data must also be flattened
print(po)
#[ 0.50036411  2.00393807  0.99694513]
plt.plot(t, data.reshape(4,-1).T, t, func(t, *po).reshape(4,-1).T)

优化后的值与原始值非常接近,而且看起来很合适

【讨论】:

谢谢布伦拉!我想我对曲线拟合函数有点困惑——谢谢你清晰的解释和精彩的代码示例!它完美地适用于我的数据。谢谢

以上是关于ValueError:对象太深,无法在 optimize.curve_fit 中找到所需数组的主要内容,如果未能解决你的问题,请参考以下文章

pytorch对象在保存图像时对于数组来说太深了

使用 scipy.optimize.curve_fit - ValueError 和 minpack.error 拟合 2D 高斯函数

scipy.optimize.curve_fit ValueError:具有多个元素的数组的真值不明确

Tensorflow ValueError: Protocol message RewriterConfig has no "layout_optimizer" field(示例代

Keras:ValueError:无法将 NumPy 数组转换为张量(不支持的对象类型列表)

“ValueError:无法将 NumPy 数组转换为张量(不支持的对象类型 numpy.ndarray)。在 TensorFlow CNN 中进行图像分类