2014-03-25 155 views
2

嗨我試圖產生一個適合我的三個指數衰減。產生令人滿意的結果我沒有成功。這是我得到:http://i.imgur.com/Nx44wsS.jpgPython指數衰減curve_fit給我一個線性擬合

任何幫助,非常感謝。我的代碼如下。

import pylab as plb 
import matplotlib.pyplot as plt 
import matplotlib.axes as ax 
import scipy as sp 
from scipy.optimize import curve_fit 
from matplotlib import rc 
rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']}) 
## for Palatino and other serif fonts use: 
#rc('font',**{'family':'serif','serif':['Palatino']}) 
rc('text', usetex=True) 

data = plb.loadtxt('data.csv',skiprows=2) 
yp = data[:,4] 
yr = data[:,5] 
yl = data[:,6] 
x = data[:,0] 

def func(x,a,b,c): 
    return a*np.exp(-b*x) + c 

popt, pcov = curve_fit(func, x, yl,maxfev=20000) 
a = popt[0] 
b = popt[1] 
c = popt[2] 
print a 
print b 
print c 
print func(x,a,b,c) 

xf = np.linspace(0,70,100) 
yf = a*np.exp(-b*x) + c 

plt.clf() 
plt.plot(x,yf,'r-', label="Fitted Curve") 
plt.plot(x,func(x,*popt)) 

plt.plot(x,yp,'bo',label='Polished') 
plt.plot(x,yr,'ro',label='Rough') 
plt.plot(x,yl,'go',label='Lacquered') 

plt.legend() 
plt.ylabel("Temperature (K)") 
plt.xlabel("Time (min)") 
plt.show() 

回答

2

非線性擬合很困難,訣竅是你必須提供一個合理的初始猜測。

這裏是一個版本的代碼,它做了兩配合,一個具有近似的初始猜測和一個帶默認初始猜測:

import pylab as plb 
import matplotlib.pyplot as plt 
import matplotlib.axes as ax 
import scipy as sp 
from scipy.optimize import curve_fit 
from matplotlib import rc 
import numpy as np 
rc('font', **{'family':'sans-serif', 'sans-serif':['Helvetica']}) 
rc('text', usetex=True) 

# Fake data 
x = np.arange(0, 70., 2.) 
yl = 300 + 63*np.exp(-x/35.) 

def func(x, a, b, c): 
    return a*np.exp(-b*x) + c 

popt, pcov = curve_fit(func, x, yl, p0=(40, 0.012, 250), maxfev=20000) 
a, b, c = popt 
print 'a=', a, 'b=', b, 'c=', c 
print 'func=', func(x, a, b, c) 

popt2, pcov2 = curve_fit(func, x, yl, p0=None, maxfev=20000) 
a2, b2, c2 = popt2 
print 'a2=', a2, 'b2=', b2, 'c2=', c2 
print 'func=', func(x, a2, b2, c2) 

xf = np.linspace(0, 70, 100) 
yf = a*np.exp(-b*x) + c 

plt.clf() 
plt.plot(x, yf, 'r-', label="Fitted Curve") 
plt.plot(x, func(x, *popt)) 
plt.plot(x, func(x, *popt2), 'b-', label='Fit w/o guess') 

plt.plot(x, yl, 'go', label='Lacquered') 

plt.legend() 
plt.ylabel("Temperature (K)") 
plt.xlabel("Time (min)") 
plt.show() 

這裏是造成千篇一律:

enter image description here

正如你所看到的,用合理的初始猜測擬合效果非常好(紅線)。如果你沒有提供初始猜測,scipy假設所有參數都爲1,並且效果很差(藍線)。

+0

非常感謝,這很好。我現在看到初始參數的重要性。 –