简体   繁体   English

使用 Scipy 在 Python 中拟合曲线

[英]Curve fitting in Python with Scipy

Just would like to address that I am a very beginner programmer with python.只是想说明我是一个非常初级的 Python 程序员。 Most of my knowledge is what I use/learned for data analysis/plotting for my physics labs.我的大部分知识都是我在物理实验室中用于数据分析/绘图的知识。

I basically gathered data of capacitance as a function of temperature, and I am supposed to fit the data I plotted with a function to find its optimal parameters.我基本上收集了作为温度函数的电容数据,我应该用函数拟合我绘制的数据以找到其最佳参数。

Note that I put in random numbers for my initial values, then ran the code.请注意,我为初始值输入了随机数,然后运行了代码。 My POpt function gave me new optimal parameters for which I replaced with my initial random numbers我的POpt函数给了我新的最佳参数,我用我的初始随机数替换了这些参数

fig, plot = plt.subplots(figsize=(40,40))

def cap(T, Cmax, K, TC, gamma): #this is the function I am fitting to my data
    return Cmax/(1+K*(T-TC)**gamma)
CmaxInit = 5.16061523 #these are the optimal parameters it gave me
KInit = 3.87292298e-05
TCInit = 3.00020150e+01
gammaInit =  2.74812849
fmodel = np.linspace(0, 100, 1000)
plt.plot(fmodel, cap(fmodel, CmaxInit, KInit, TCInit, gammaInit), linewidth=8, label='Fitted model')

plot.errorbar(temperature, capacitance, linewidth=8, label='Data Points') #this is my data of temperature vs capacitance

pOpt, pCov = curve_fit(cap, temperature, capacitance, p0=[CmaxInit, KInit, TCInit, gammaInit], absolute_sigma=True) #this is what I use to curve-fit/get my optimal parameters
print("[CmaxOpt KOpt TCOpt gammaOpt] =", pOpt)
print()
print("pCov =") #This is a co-variant matrix function that calculates my error values
print(pCov)

plt.xticks(fontsize=60)
plt.yticks(fontsize=60)
plt.grid()
plt.legend(fontsize=80)
plt.show()

However when plotting my fitted model, it gives me:但是,在绘制我的拟合模型时,它给了我:

Capacitance as a function of Temperature作为温度函数的电容

The POpt function did somewhat fit the general look, but it is clearly way off. POpt函数确实有点符合总体外观,但显然POpt I do not understand why, but my guess would be of the number of parameters I am trying to optimize.我不明白为什么,但我的猜测是我试图优化的参数数量。

Edit: Changing the initial parameters to编辑:将初始参数更改为

CmaxInit = 6 
KInit = 0.01
TCInit = 50
gammaInit =  2

produced a more accurate fit of产生了更准确的拟合这个

But now it produced an error when calculating the optimal parameters.但是现在在计算最优参数时产生了错误。

[CmaxOpt KOpt TCOpt gammaOpt] = [nan nan nan nan]

Edit 2: After chopping my data, I am now trying to fit编辑 2:在砍掉我的数据后,我现在正在尝试适应这个

However I am still getting但是我仍然得到

[CmaxOpt KOpt TCOpt gammaOpt] = [nan nan nan nan]

An exponential function would seem to fit this better than the equation I am supposed to model.指数函数似乎比我应该建模的方程更适合这个。 Maybe that's why I am not getting optimal parameters?也许这就是为什么我没有得到最佳参数?

There are some numerical problems with the fitting function:拟合函数存在一些数值问题:

  • it seems to be too hard for the algorithm to have an exponent (gamma) as a fitting parameter.算法将指数(伽马)作为拟合参数似乎太难了。 This seems also to be true for something as exp(gamma)对于exp(gamma)东西来说,这似乎也是正确的
  • I replaced the fitting function by Cmax*np.exp(-K*(T-TC)**2) + c .我用Cmax*np.exp(-K*(T-TC)**2) + c替换了拟合函数。 With that it dependes on the x-range (data window) how good the fit is.因此,它取决于 x 范围(数据窗口)的拟合程度。
  • for numerical reasons it might be better to have an intercept c .出于数字原因,截距c可能更好。
  • it is often a good idea to bring the data by transformation to "an easy region" of the the fitting function, so that the peak is around zero and the x-range is around [-5..+5].通过转换将数据带到拟合函数的“简单区域”通常是一个好主意,这样峰值大约为零,x 范围大约为 [-5..+5]。 After fitting you transform the results back to the original data range.拟合后,您将结果转换回原始数据范围。
  • fitting the log(data) instaed of (data) can help sometimes too.拟合日志(数据)而不是(数据)有时也有帮助。

... ...

def cap(T, Cmax, K, TC, gamma):         
    return Cmax/(1+K*(T-TC)**gamma)

def func_1(T, Cmax, K, TC, c):
    return Cmax*np.exp(-K*(T-TC)**2) + c

#--- generate data --------------------
CmaxInit =  5.0         # 5.16061523      
KInit =     3.0e-3      # 3.87292298e-05
TCInit =    30.0         # 3.00020150e+01
gammaInit = 2.0         # 2.74812849
cInit =     0.0         # intercept

fmodel = np.linspace(20, 50, 280)
x0 = fmodel.copy()

y0 = cap   (x0, CmaxInit, KInit, TCInit, gammaInit)
y1 = func_1(x0, CmaxInit, KInit, TCInit, cInit)
y_noise = 0.05 * np.random.normal(size=x0.size)
Y0 = y0 + y_noise
Y1 = y1 + y_noise

#--- fit the data by a function ------------
pOpt, pCov = curve_fit(func_1, x0, Y0,  p0=[CmaxInit, KInit, TCInit, cInit], absolute_sigma=True)
Yfit = func_1(x0, *pOpt)

#--- print the results ---------------------------
print("CmaxInit, KInit, TCInit, c", CmaxInit, KInit, TCInit, c)
print("[CmaxOpt KOpt TCOpt cOpt] =", pOpt); print()
print("pCov ="); print(pCov)

#---- graphics --------------------------------------------
fig, plot = plt.subplots(figsize=(12, 12))
plt.plot(x0, Y0, linewidth=2, label='simulated data with CAP')
plt.plot(x0, Y1, ls=':', lw=1,label='simulated data with EXP')
plt.plot(x0, Yfit,  label='Yfit: Cmax=%5.3f, K=%5.3f, TC=%5.3f, c=%5.3f' % tuple(pOpt))
plt.legend(); plt.savefig('pic3.jpg'); plt.show()

.. .. 在此处输入图片说明

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM