You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义函数curve_fit拟合结果异常,寻求技术解决方案

问题排查与解决方法

1. 修正模型公式的核心错误

你当前的模型函数完全写错了电容项的形式:原始公式中电容项是指数衰减,但你误用了幂函数计算,这是拟合失败的首要原因。

  • 正确的电容项公式:$i_C = \frac{E}{R_S} e^{-\frac{t}{R_S C_{DL}}}$
  • 你错误的实现:math.pow(E/Rs, -(x/Rs*CDL))

修正后的模型函数直接用numpy数组运算替代np.vectorize(更高效且避免标量运算问题):

import numpy as np

def model_f(x, E, Rs, CDL, B):
    # 电容项:指数衰减形式
    capacitive = (E / Rs) * np.exp(-x / (Rs * CDL))
    # 扩散项:B/√x
    diffusive = B / np.sqrt(x)
    # 总电流:电容项 + 扩散项 + 基线常数E
    return capacitive + diffusive + E

2. 调整拟合的初始值与边界

你设置的bounds=(1,3)把所有参数限制在1-3之间,但数据中Y存在负数(最低至-0.0018),常数项E明显应为负数,这个不合理的边界直接导致拟合失效。同时初始值p0=(1,1,1,1)和数据量级严重不匹配:

  • 建议初始值:p0 = [-0.002, 10, 1e-6, 4](E对应数据基线,Rs取欧姆级典型值,CDL取微法级,B根据扩散项量级估算)
  • 合理边界:bounds=([-0.01, 0.1, 1e-8, 0], [0, 100, 1e-3, 10])(给每个参数符合物理意义的范围)

3. 优化拟合代码

去掉冗余的循环和np.vectorize,用numpy数组直接计算各分量,简化代码:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

# 读取数据(假设df已加载)
x_data = df['X'].values
y_data = df['Y'].values

# 修正后的模型函数
def model_f(x, E, Rs, CDL, B):
    capacitive = (E / Rs) * np.exp(-x / (Rs * CDL))
    diffusive = B / np.sqrt(x)
    return capacitive + diffusive + E

# 设置初始值与边界
p0 = [-0.002, 10, 1e-6, 4]
bounds = ([-0.01, 0.1, 1e-8, 0], [0, 100, 1e-3, 10])

# 执行拟合
popt, pcov = curve_fit(f=model_f, xdata=x_data, ydata=y_data, p0=p0, bounds=bounds)
E, Rs, CDL, B = popt

# 计算各分量与拟合总曲线
diffusive_y = B / np.sqrt(x_data)
capacitive_y = (E / Rs) * np.exp(-x_data / (Rs * CDL))
total_fit_y = capacitive_y + diffusive_y + E

# 绘图展示
plt.figure(figsize=(10,6))
plt.plot(x_data, y_data, label='Original data', alpha=0.6)
plt.plot(x_data, diffusive_y, 'r--', label='Difusiva')
plt.plot(x_data, capacitive_y, 'b--', label='Capacitiva')
plt.plot(x_data, total_fit_y, 'g-', label='Fitted total')
plt.legend()
plt.xlabel('Time')
plt.ylabel('i_T')
plt.show()

# 打印拟合参数
print(f"拟合参数:E={E:.6f}, Rs={Rs:.3f}, CDL={CDL:.8f}, B={B:.3f}")

4. 额外优化建议

  • 异常值处理:数据中x=1149时Y=0.11远高于其他点,属于异常值,建议先剔除或用移动平滑处理,避免干扰拟合结果。
  • 单位一致性检查:确保时间x的单位(秒)与Rs(欧姆)、CDL(法拉)的单位匹配,否则指数项量级会完全错误。
  • lmfit进阶拟合:如果scipy拟合仍不理想,可使用lmfit进行更灵活的参数约束与结果分析:
from lmfit import Model

model = Model(model_f)
params = model.make_params(E=-0.002, Rs=10, CDL=1e-6, B=4)
params['E'].set(min=-0.01, max=0)
params['Rs'].set(min=0.1, max=100)
params['CDL'].set(min=1e-8, max=1e-3)
params['B'].set(min=0, max=10)

result = model.fit(y_data, params, x=x_data)
print(result.fit_report())
result.plot_fit()
plt.show()

内容的提问来源于stack exchange,提问作者Carlos Torres

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 21:15:23