【问题标题】:Unable to do fitting of data using curve_fit()无法使用 curve_fit() 进行数据拟合
【发布时间】:2021-11-05 21:52:39
【问题描述】:

我想用 txt 文件中提到的数据拟合函数 ax +blog((x-x0)/c)。 x 轴是注入电流,y 轴是 gain_X。我正在使用函数 curve_fit() ,但它不起作用并显示“未找到最佳参数:函数调用次数已达到 maxfev = 1000000”。我在下面附上了我的代码,可以使用link 查看文本文件。 你能帮我拟合数据吗?

import matplotlib.pyplot as plt
import pandas as pd
from scipy.optimize import curve_fit
import numpy as np
import scipy.optimize as opt
def func(x, a, b, c,x0):
    return a*x+b*np.log((x-x0)/c)

data1 = pd.read_csv(r'C:\Users\TanviPradhan\OneDrive - EFFECT Photonics\Desktop\CD581379_A-12469303362S__GAIN_DIODE_TEST__2021-08-03_16.57.36.txt',skipinitialspace=True,comment="%")
print(data1)


#Creates one figure for the plots
fig =  plt.figure(figsize=(7,14))
fig.suptitle('Wafer xx')
#Creates the subplots 1x2 plots 1st plot is 121
ax_X= fig.add_subplot(211)
plt.xlabel("Injected Current (mA)")
plt.ylabel("Measured voltage (V)")
ax_X.set_title('xx')
#ax_X.set(xlim=(0, 80), ylim=(0, 1.5))
plt.grid(True)




#add plot for each chip to total plot

ax_X.plot(data1["InjectedCurrent(mA)"],data1["GAIN_X(V)"])

x = data1["InjectedCurrent(mA)"]
y = data1["GAIN_X(V)"]

#training the data
train_x = x[:80]
train_y = y[:80]

#testing the data
test_x = x[80:]
test_y = y[80:]

plt.scatter(train_x, train_y)
plt.show()


plt.scatter(test_x, test_y)
plt.show()

#fitting_data
params,popt = curve_fit(func,x,y,maxrev=1000000)

【问题讨论】:

    标签: python pandas numpy matplotlib


    【解决方案1】:

    正如@Ammon 已经提到的,提供合理的初始猜测和边界(如果可能)确实有很大帮助。排除 x=0 的值也可能有助于函数表现得更好。

    p0 = [0.002, 0.05, 0.001, 0.0]
    bounds = (
        [0.0001, 0.0001, 0.0,     0.0], # lower
        [0.1,    0.1,    0.1,     0.5], # upper
    )
    params, popt = curve_fit(func, x[x>0], y[x>0], p0=p0, bounds=bounds)
    

    这导致拟合参数:

    array([3.27556699e-03, 5.76995401e-02, 1.56406668e-05, 2.80572662e-01])
    

    这只是一个示例,但已经表明,通过合理的初始猜测,您会得到相当不错的拟合,但仍不完美。希望这会向您展示如何应用 curve_fit 函数。

    我不熟悉您正在使用的功能,因此您可以通过结合更好的初始猜测和边界知识来改进。

    编辑: 完成sn-p:

    导入和读取输入数据:

    import matplotlib.pyplot as plt
    import pandas as pd
    from scipy.optimize import curve_fit
    import numpy as np
    
    data1 = pd.read_csv(r'D:\CD581379_A-12469303362S__GAIN_DIODE_TEST__2021-08-03_16.57.36.TXT', skipinitialspace=True, comment="%")
    x = data1["InjectedCurrent(mA)"]
    y = data1["GAIN_X(V)"]
    

    拟合函数:

    def func(x, a, b, c, x0):
        return a*x+b*np.log((x-x0)/c)
    
    #fitting_data
    p0 = [0.002, 0.05, 0.001, 0.0]
    bounds = (
        [0.0001, 0.0001, 0.0,     0.0], # lower
        [0.1,    0.1,    0.1,     0.5], # upper
    )
    params, popt = curve_fit(func, x[x>0], y[x>0], p0=p0, bounds=bounds)
    

    绘制结果:

    #Creates one figure for the plots
    fig, ax =  plt.subplots(figsize=(5,5), constrained_layout=True, dpi=86, facecolor='w')
    fig.suptitle('Wafer xx')
    
    ax.set_xlabel("Injected Current (mA)")
    ax.set_ylabel("Measured voltage (V)")
    ax.set_title('xx')
    ax.grid(True)
    
    ax.plot(x, y, 'k--', label='all data')
    
    ax.plot(x, func(x, *p0), label='init guess', lw=2)
    ax.plot(x, func(x, *params), label='fit', lw=2)
    
    ax.legend(loc=4)
    

    【讨论】:

    • 嗨,Rutger,你能分享完整的代码吗?
    • @TanviPradhan,我已经更新了帖子以包含所有内容。不过和你的OP基本一样。
    【解决方案2】:

    你应该使用curve_fit()初始化参数,否则很难得到正确的结果。 https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html

    popt, pcov = curve_fit(func, xdata, ydata, bounds=(0, [3., 1., 0.5]))
    

    尝试优化边界并添加 p0 作为起始参数:

    popt, pcov = curve_fit(func, xdata, ydata, bounds=([a1,a2],[b1,b2]),p0=[c0,c1])
    

    【讨论】:

      猜你喜欢
      • 2012-06-07
      • 2019-01-23
      • 2020-06-08
      • 1970-01-01
      • 1970-01-01
      • 2017-03-17
      • 2016-11-29
      • 2018-11-04
      • 1970-01-01
      相关资源
      最近更新 更多