Patchouli的機器學習系列教程四:基底函數——『器』
這一章的教程十分簡短,因為該講的東西在『道』篇Patchouli的機器學習系列教程四:基底函數——『道』里都講完了,只教會大家在基底函數已設計完畢的情況下如何使用基底函數對現實中的數據進行非線性擬合。
首先先導入並處理數據:
import pylab as pltnimport numpy as npnimport pandas as pdnimport scipy as spnfrom pandas import DataFramendata=DataFrame(pd.read_csv(marathon.csv))nx=DataFrame(data[year])ny=DataFrame(data[hour])ny-=y.mean()ny/=y.std()n
隨後如『道』篇里一樣定義我們的基底函數:
def polynomial(x, num_basis, data_limits=[-1., 1.]):n "Polynomial basis"n centre = data_limits[0]/2. + data_limits[1]/2.n span = data_limits[1] - data_limits[0]n z = x - centren z = 2*z/spann Phi = np.zeros((x.shape[0], num_basis))n for i in range(num_basis):n Phi[:, i:i+1] = z**in return Phinndef radial(x, num_basis, data_limits=[-1., 1.], width=None):n if num_basis>1:n centres=np.linspace(data_limits[0], data_limits[1], num_basis)n if width is None:n width = (centres[1]-centres[0])/2.n else:n centres = np.asarray([data_limits[0]/2. + data_limits[1]/2.])n if width is None:n width = (data_limits[1]-data_limits[0])/2. n Phi = np.zeros((x.shape[0], num_basis))n for i in range(num_basis):n Phi[:, i:i+1] = np.exp(-0.5*((x-centres[i])/width)**2)n return Phinndef fourier(x, num_basis=4, data_limits=[-1., 1.]):n tau = 2*np.pin span = float(data_limits[1]-data_limits[0])n Phi = np.zeros((x.shape[0], num_basis))n for i in range(num_basis):n count = float((i+1)//2)n frequency = count/spann if i % 2:n Phi[:, i:i+1] = np.sin(tau*frequency*x)n else:n Phi[:, i:i+1] = np.cos(tau*frequency*x)n return Phin
分別計算他們的 和誤差:
Phi_p = polynomial(x, num_basis=4, data_limits=[1888, 2020])nw_p = np.linalg.solve(np.dot(Phi_p.T,Phi_p), np.dot(Phi_p.T,y))nprediction_p = np.dot(Phi_p,w_p)nerror_p = np.sum((y-prediction_p)**2)nnPhi_r = radial(x, num_basis=4, data_limits=[1888, 2020])nw_r = np.linalg.solve(np.dot(Phi_r.T,Phi_r), np.dot(Phi_r.T,y))nprediction_r = np.dot(Phi_r,w_r)nerror_r = np.sum((y-prediction_r)**2)nnPhi_f= fourier(x, num_basis=4, data_limits=[1888, 2020])nw_f = np.linalg.solve(np.dot(Phi_f.T,Phi_f), np.dot(Phi_f.T,y))nprediction_f = np.dot(Phi_f,w_f)nerror_f = np.sum((y-prediction_f)**2)n
展示出來:
fig,ax=plt.subplots(figsize=(16,8))nax.plot(x,prediction_p,label = polynomial)nax.plot(x,prediction_r,label=radial)nax.plot(x,prediction_f,label=fourier)nax.plot(x,y,rx)nprint("polynomial基底的誤差為",error_p)nprint("radial基底的誤差為",error_r)nprint("fourier基底的誤差為",error_f)n
結果如下:
其中:
polynomial基底的誤差為3.649409
radial基底的誤差為3.413982
fourier基底的誤差為6.379364
在一個你已經學會的套路面前,什麼複雜變化都是紙老虎,更何況這個變化並不複雜,只是由原來的單列數據集進行操作變為多列數據集,道理還是那麼個道理。無非就是用已有的數據求特徵向量的解,再把特徵向量帶回去擬合一條曲線出來而已,沒什麼多說的,直接下一章。
推薦閱讀:
※你做夢也想不到人類有多麼可怕!
※下一個主要AI平台是什麼?蘋果說:手機
※人工智慧技術入門該讀哪些書?StackOverflow上最推薦這些
※Alexa估值近百億美元,AI巨頭為何在語音交互市場搶奪賽道?
※腦子不如鞋子聰明?孫正義的「狂言」日記