Python多变量曲线拟合报错求助:TypeError及代码优化咨询
多变量曲线拟合问题求助
我用Python做含2个参数的多变量模型曲线拟合一直失败,查的文档大多是单变量拟合,参考帖子试了链接和解包操作后,还是一直报TypeError: can't multiply sequence by non-int of type 'float',错误出在代码最后一行。除了修复这个错误,我的代码还需要改哪些地方才能得到更优解?y是模型输出,我是Python新手,之前试过把输入改成np.array但没用,求帮忙。
我的代码
import pandas as pd import math import numpy as np from scipy.optimize import curve_fit L_data = np.array([0.856, 0.451]) t_data = np.array([0.398, 0.507]) y_data = np.array([0.63, 0.5]) def model(x, c1, c2): x = ([L, t]) return ((480 / c2) * (math.sqrt(((1 + (c1 ** 2)) / 3)) * np.cos((L * math.pi) / 6)) + c1 * (t + (1 / 3) * np.sin((L * math.pi) / 6))) ** (-1 / 0.19741) xd = [L_data, t_data] p0 = 0.003, 231 popt, pcov = curve_fit(model, xd, y_data, p0)
问题修复与优化建议
1. 修复核心错误(TypeError)
- 导入语句错误:
from scipy.optimize缺少连接符,应改为from scipy.optimize import curve_fit - 模型函数输入处理错误:
curve_fit传入多变量时,会把xd以二维数组形式传入model的x参数,你写的x = ([L, t])完全错误,需从x解包出L和t;同时要用numpy函数替代math函数(numpy数组无法直接用math函数运算):def model(x, c1, c2): L, t = x # 从输入数组解包两个变量 term1 = np.sqrt((1 + c1**2)/3) * np.cos((L * np.pi)/6) term2 = t + (1/3)*np.sin((L * np.pi)/6) return ((480 / c2) * term1 + c1 * term2) ** (-1 / 0.19741) - 输入数据格式错误:
xd需调整为(样本数, 特征数)的二维数组,转置后每个样本对应一组[L,t]:xd = np.array([L_data, t_data]).T
2. 其他优化点
- 移除无用导入:代码中未用到
pandas,可删除import pandas as pd减少冗余 - 解决欠定问题:你只有2个样本却要拟合2个参数,属于欠定问题,拟合结果不唯一,建议增加样本数量才能得到可靠参数
- 初始值与边界约束:确保
p0初始值在合理范围,若知道参数的取值区间,可通过curve_fit的bounds参数限制,避免拟合发散,示例:# 假设c1∈[0,1],c2∈[100,500] popt, pcov = curve_fit(model, xd, y_data, p0, bounds=((0, 100), (1, 500))) - 添加拟合验证:拟合完成后计算预测值与真实值的误差,验证效果:
y_pred = model(xd.T, *popt) mse = np.mean((y_pred - y_data)**2) print(f"拟合均方误差: {mse}")
修复后的完整代码
import numpy as np from scipy.optimize import curve_fit # 数据 L_data = np.array([0.856, 0.451]) t_data = np.array([0.398, 0.507]) y_data = np.array([0.63, 0.5]) # 修正后的模型函数 def model(x, c1, c2): L, t = x term1 = np.sqrt((1 + c1**2)/3) * np.cos((L * np.pi)/6) term2 = t + (1/3)*np.sin((L * np.pi)/6) return ((480 / c2) * term1 + c1 * term2) ** (-1 / 0.19741) # 调整输入数据形状:(样本数, 特征数) xd = np.array([L_data, t_data]).T # 初始参数 p0 = [0.003, 231] # 执行拟合 popt, pcov = curve_fit(model, xd, y_data, p0) print(f"拟合得到的参数c1: {popt[0]}, c2: {popt[1]}") # 验证拟合结果 y_pred = model(xd.T, *popt) mse = np.mean((y_pred - y_data)**2) print(f"拟合均方误差: {mse}")
内容的提问来源于stack exchange,提问作者Zack
相关产品推荐
相关产品推荐

