使用scipy.optimize.leastsq报错:输入向量长度超过输出长度
scipy.optimize.leastsq 报错 TypeError 的原因及解决方法
问题代码
def solido_3parameters(time, strain0, eta1, time0, stiffness2, eta): return strain0 + (sigma0 / eta1) * (time-time0) + sigma0 / stiffness2 * (1 - np.exp(-(time time0) * stiffness2/eta)) def residual(parameters): strain0 = parameters[0] eta1 = parameters[1] time0 = parameters[2] stiffness2 = parameters[3] eta = parameters[4] strain_fitted = solido_3parameters(time, strain0, eta1, time0, stiffness2, eta) RSS = np.sum(np.square(strain - strain_fitted)) return RSS initial_params = [1.0, 2, 1.5, 1.0, 1.0] leastsq(residual, x0=initial_params)
错误信息
TypeError: Improper input: func input vector length N=5 must not exceed func output vector length M=1.
问题原因
scipy.optimize.leastsq 要求残差函数返回每个数据点的残差组成的向量(观测值 - 拟合值),而非残差平方和(RSS,单个标量值)。当前代码中residual函数返回的是求和后的RSS(长度为1的标量),但待优化的参数有5个(N=5),此时输出向量长度M=1小于N,触发了该类型错误。
另外,solido_3parameters函数中存在语法错误:(time time0) 缺少减号,应为 (time - time0)。
修正代码
import numpy as np from scipy.optimize import leastsq # 请根据实际情况替换为你的真实数据 sigma0 = 1.0 time = np.linspace(0, 10, 100) strain = np.random.rand(100) def solido_3parameters(time, strain0, eta1, time0, stiffness2, eta): # 修正语法错误:补充减号 return strain0 + (sigma0 / eta1) * (time - time0) + sigma0 / stiffness2 * (1 - np.exp(-(time - time0) * stiffness2/eta)) def residual(parameters): strain0 = parameters[0] eta1 = parameters[1] time0 = parameters[2] stiffness2 = parameters[3] eta = parameters[4] strain_fitted = solido_3parameters(time, strain0, eta1, time0, stiffness2, eta) # 返回残差向量,而非平方和 return strain - strain_fitted initial_params = [1.0, 2, 1.5, 1.0, 1.0] # 执行优化 optimized_params, _ = leastsq(residual, x0=initial_params) print("优化完成,参数为:", optimized_params)
说明
leastsq 内部会自动计算残差的平方和并执行最小化逻辑,无需手动提前求和。只要残差向量的长度(即数据点数量)大于等于待优化参数的数量,就能满足函数的输入要求,避免该错误。
内容的提问来源于stack exchange,提问作者Manu_sab
相关产品推荐
相关产品推荐

