使用scipy curve_fit拟合多数据集并求解公共参数问题
多数据集共享参数拟合问题
我尝试用同一方程拟合多个数据集,求解共享的拟合参数。问题涉及两个自变量,单数据集拟合结果符合预期,但多数据集拟合时出现异常——拟合曲线呈现弓形(直线与曲线末端连接),而非每个数据集对应单独曲线。我知道需要拆分数据,可能通过堆叠数据并使用索引调整函数,但现有示例让我困惑,不知道怎么实现。
相关代码
# 导入库 import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit ## 数据准备 ## # x数据 xfrac = [1., 0.85, 0.725, 0.6, 0.5, 0.4, 0.] x = np.concatenate((xfrac, xfrac)) # 数据集(直接粘贴计算结果) mix_850 = [1.701, 3.642865, 4.6762, 5.0739, 5.5177, 5.9923, 6.9408] mix_1000 = [1.651185, 3.53359, 4.4854, 4.8978, 5.32525, 5.7388, 6.792] dat = np.concatenate((mix_850, mix_1000)) # 温度值 c = np.repeat(850., 7.) d = np.repeat(1000., 7.) Temp = np.concatenate((c, d)) # 定义拟合函数 def f(Z, a1, b1, a2, b2): x1, T = Z x2 = 1. - x1 excess = a1 + b1 + (a2 + b2 * T) * (x1 - (1. - x1) * (x1 * (1. - x1))) ideal = ((x1 * 25.939) + ((1.0 - x1) * 314.02)) / (((x1 * 25.939)/1.701 - 0.3321e-3 * T) + (((1.0 - x1) * 314.02)/7.784 - 0.9920e-3 * T)) mix = excess + ideal return mix # 拟合 popt, _ = curve_fit(f, (x, Temp), dat) fit_a1 = popt[0] fit_b1 = popt[1] fit_a2 = popt[2] fit_b2 = popt[3]
解决方法
1. 修正绘图逻辑(核心问题)
你拟合后的绘图没有拆分数据集,导致堆叠后的所有数据点被连成一条线,出现弓形。需要分别为每个温度组生成拟合曲线:
# 生成各温度组的拟合曲线数据 # 850K组 x_850 = xfrac fit_850 = f((x_850, np.full_like(x_850, 850)), *popt) # 1000K组 x_1000 = xfrac fit_1000 = f((x_1000, np.full_like(x_1000, 1000)), *popt) # 绘图 plt.scatter(x[:7], dat[:7], label='850K 原始数据') plt.plot(x_850, fit_850, label='850K 拟合曲线') plt.scatter(x[7:], dat[7:], label='1000K 原始数据') plt.plot(x_1000, fit_1000, label='1000K 拟合曲线') plt.xlabel('xfrac') plt.ylabel('mix') plt.legend() plt.show()
2. 验证拟合函数公式
检查excess的计算式,原公式可能存在逻辑偏差。如果是常见的超额性质模型,通常形式类似:
# 示例修正(需根据你的理论模型调整) excess = (a1 + b1*T)*x1*x2 + (a2 + b2*T)*x1*x2*(x1 - x2)
公式错误会直接导致拟合结果异常,务必确认理论模型的准确性。
3. 添加拟合初始参数(可选)
若拟合结果不稳定,给curve_fit提供合理的初始参数可提升拟合效果:
# 根据经验设置初始参数 initial_guess = [0, 0, 0, 0] popt, _ = curve_fit(f, (x, Temp), dat, p0=initial_guess)
内容的提问来源于stack exchange,提问作者Triceratops
相关产品推荐
相关产品推荐

