2014-04-15 39 views
1

我正在嘗試使用Scipy.Optimise Curve_fit來擬合一些數據下面的簡單示例here的指數。指數擬合與Scipy.Optimise Curve_fit無法正常工作

該腳本運行沒有錯誤,但適合是可怕的。當我在curve_fit的每一步查看popt的輸出時,似乎並沒有從初始參數跳到一系列的1.0s,儘管它似乎讓第三個參數回到了一個相當不錯的值:

92.0 0.01 28.0 
1.0 1.0 1.0 
1.0 1.0 1.0 
1.0 1.0 1.0 
1.00012207031 1.0 1.0 
1.0 1.00012207031 1.0 
1.0 1.0 1.00012207031 
1.0 1.0 44.3112882656 
1.00012207031 1.0 44.3112882656 
1.0 1.00012207031 44.3112882656 
1.0 1.0 44.3166973584 
1.0 1.0 44.3112896048 
1.0 1.0 44.3112882656 

我不知道這可能是造成這也許除了模型只是不合身的數據,雖然我強烈懷疑它應該(物理是物理學)。有沒有人有任何想法?我已經發布了我的(非常簡單)腳本。謝謝。

#!/usr/bin/python 

import matplotlib.pyplot as plt 
import os 
import numpy as np 
from scipy.optimize import curve_fit 
from matplotlib.ticker import* 
from glob import glob 
from matplotlib.backends.backend_pdf import PdfPages 
import fileinput 

path_src=os.getcwd() 
dirlist= glob(path_src + '/Gel_Temp_Res.txt') 
dirlist.sort() 

plots_file='Temp_Curve.pdf' 
plots= PdfPages(path_src+'/'+plots_file) 

time=[] 
temp=[] 

for row in fileinput.input(path_src + '/Gel_Temp_Res.txt'): 

    time.append(row.split()[0]) 
    temp.append(row.split()[1]) 

nptime=np.array(time, dtype='f') 
nptemp=np.array(temp, dtype='f') 

del time[:] 
del temp[:] 

# Newton cooling law fitting 
def TEMP_FIT(t, T0, k, Troom): 
    print T0, k, Troom 
    return T0 * np.exp(-k*t) + Troom 

y = TEMP_FIT(nptime[41:], nptemp[41]-nptemp[0], 1e-2, nptemp[0]) 
yn = y + 0.2*np.random.normal(size=len(nptime[41:])) 
popt, pcov = curve_fit(TEMP_FIT, nptime[41:], yn) 

# Plotting 
ax1 = plt.subplot2grid((1,1),(0, 0)) 
ax1.set_position([0.1,0.1,0.6,0.8]) 
plt.plot(nptime[41:], nptemp[41:], 'bo--',label='Heater off', alpha=0.5) 
plt.plot(nptime[41:], TEMP_FIT(nptime[41:], *popt), label='Newton Cooling Law Fit') 
plt.xlim(-25, 250) 
plt.xlabel('Time (min)') 
plt.ylabel('Temperature ($^\circ$C)') 
ax1.grid(True, which='both', axis='both') 
plt.legend(numpoints=1, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.) 
plt.savefig(plots, format='pdf',orientation='landscape') 
plt.close() 
plots.close() 

而且,這裏是一個我試圖以適應數據:

100 124 
130 120 
135 112 
140 105 
145 99 
150 92 
155 82 
160 75 
165 70 
170 65 
175 60 
180 56 
185 55 
190 52 
195 49 
200 45 
205 44 
210 40 
215 39 
220 37 
225 35 

回答

4

我清理你的代碼,並在0做的時候開始,我做了什麼不止一次與指數爲了功能,使它們正常工作:

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

time, temp = np.loadtxt('test.txt', unpack=True) 

# Newton cooling law fitting 
time -= time.min() 
def TEMP_FIT(t, T0, k, Troom): 
    print T0, k, Troom 
    return T0 * np.exp(-k*t) + Troom 

popt, pcov = curve_fit(TEMP_FIT, time, temp) 

# Plotting 
plt.figure() 
plt.plot(time, temp, 'bo--',label='Heater off', alpha=0.5) 
plt.plot(time, TEMP_FIT(time, *popt), label='Newton Cooling Law Fit') 
plt.xlim(-25, 250) 
plt.xlabel('Time (min)') 
plt.ylabel('Temperature ($^\circ$C)') 
ax = plt.gca() 
ax.xaxis.set_ticks_position('bottom') 
ax.yaxis.set_ticks_position('left') 
ax.spines['top'].set_visible(False) 
ax.spines['right'].set_visible(False) 
plt.legend(fontsize=8) 
plt.savefig('test.png', bbox_inches='tight') 

結果是:

enter image description here

刪除您的樣品的第一點:

enter image description here

+0

優秀,感謝Saullo。所以爲了澄清,你認爲curve_fit不能處理非零的起始x位置?問題是,我實際上在這個範圍之外有更多的數據,所以我實際上只對擬合一個部分感興趣。我唯一的選擇是從0開始創建一個人工擬合範圍嗎? – DaveB

+0

這不是curve_fit,而不是您的模型,無法處理它。如果你添加一個時間轉換到模型,它會工作得很好。 t0 * np.exp(-k *(t-t0))+ Troom –

+0

@ user34716以任意值開始的'time'的問題是它的'exp'會返回一個巨大的數字,這樣靈敏度「x」值的最佳參數更接近數值精度閾值。它不是'curve_fit'的問題 –