因為之前學習的神經網絡的算法大多都是擬合非線性函數的,所以在某些具有連續性的預測方面,神經網絡算法的函數擬合並沒有簡單函數好用。
今天學習一下關於曲線函數的擬合方式。
首先給定一組數據來對數據進行擬合,例如隨便想一個函數 y=2x^3+x^2+1
接下來分別取x=[1,2,3,4,5]
對應的y就為y=[4,21,64,145,276]
上面的數據x和y就為基礎的數據,然后我們需要通過x,y這些訓練數據,得到一個f(x)來得到具體的函數轉換器y=2x^3+x^2+1
所以現在我們吧x,y作為訓練數據代入 則有以下的過程
(對於上下波動的函數擬合暫時不太理想)
import numpy as np import scipy.stats as stats #自動型最大冪次,減小計算量 maxn=20 #自動多項式函數擬合(計算量相對較大) def auto_ax_bfit(x,y): x=np.array(x) y=np.array(y) n=maxn if len(x)-1>maxn else len(x)-1 alist=[] g_start=True suit=1 minsuit=0 import warnings warnings.filterwarnings("ignore") pi=np.where(x==max(x))[0][0] new_x = np.delete(x,pi) new_y = np.delete(y,pi) for i in range(1, n, 1): fit_coef, blist = ax_bfit(new_x, new_y, i) temp_minus = abs(func_general(fit_coef, [x[pi]])[0] - y[pi]) if (g_start or temp_minus < minsuit): minsuit = temp_minus suit = i if (g_start): g_start = False warnings.filterwarnings("default") fit_coef, blist = ax_bfit(x, y, suit) print("自適應最高冪次:",suit) minnum=1e-12 for one in fit_coef: if(not g_start): if(abs(one)>minnum): g_start=True alist.append(one) else: alist.append(one) alist=[round(one,9) for one in list(alist)] return fit_coef,alist #靠猜最高冪次多項式擬合,n是最高冪次,這個需要靠猜n的大小,n越大計算量也就越大,同時也越准確(泰勒展開公式,最高冪次越大越逼近准確函數),同時n需要小於len(x),當太大時直接取正整數型,想方便時也直接用自動型就好了 #但如果一個函數中包含冪函數,則需要將最高冪次調整至對應的范圍使其符合冪函數的增長趨勢才能讓擬合函數在一定區間內符合函數增長,這點自動型做不到 def ax_bfit(x,y,n): x=np.array(x) y=np.array(y) fit_coef=np.polyfit(x,y,n) alist=[round(one,9) for one in list(np.polyfit(x,y,n))] return fit_coef,alist #函數構建器 def func_general(fit_coef,predict_xlist): calculate_y = [round(one, 9) for one in list(np.polyval(fit_coef, predict_xlist))] return calculate_y
代入對應數據,並預測當x=[1,3,6]時,f(x)對應的值是多少(根據事先所想的函數,正確的值應該是[4,64,469]),下面我們代入數據看看結果
#數據列表 x=[1,2,3,4,5] y=[4,21,64,145,276] #需要預測的x值 calculate_x=[1,3,6] #期待值[4,64,469] # #擬合函數最高次冪(這部分可以靠猜,當為3時是准確值,計算量相對較小型) # n=3 # fit_coef,alist=ax_bfit(x,y,n) #自動型,計算量相對較大 fit_coef,alist=auto_ax_bfit(x,y) print("系數列表:",alist) print("calculate_x列表對應的預測值:",func_general(fit_coef,calculate_x))
最終結果如下:
可以看到預測出來的函數為: 與2x^3+x^2+1一致
預測值和期待值[4,64,469]一致
有人說,預測這么簡單的函數太簡單了,給我時間我也能計算預測出來結果。
所以我們來根據函數值,預測自然數的y=e^x的通項公式
根據訓練值
x=[2,2.11,3.24,3,4,5,2.1,4.2,3.2,1.3,1.36,1.6,2.7,5.7,3.6]
y=[np.exp(one) for one in x]
我們知道e是一個無理數,平常來說,我們基本上很難通過上述給定的數值來確定其通項公式
這個時候我們看看曲線擬合之后的結果(泰勒展開公式,預測結果的准確率將根據最高冪次和給定的訓練值的量的而變化,最高冪越高和值越多結果將越准確)
我們知道 e≈2.7182818284590452353602874713526624977572
我們看看預測出來的e的大小是多少,上述給定的訓練值中並沒有x=1的情況
當x=1時
#數據列表 x=[2,2.11,3.24,3,4,5,2.1,4.2,3.2,1.3,1.36,1.6,2.7,5.7,3.6] y=[np.exp(one) for one in x] #需要預測的x值 calculate_x=[1] #期待值[2.7182818284590452353602874713526624977572] # #擬合函數最高次冪(這部分可以靠猜,當為3時是准確值,計算量相對較小型) # n=3 # fit_coef,alist=ax_bfit(x,y,n) #自動型,計算量相對較大 fit_coef,alist=auto_ax_bfit(x,y) print("系數列表:",alist) print("calculate_x列表對應的預測值:",func_general(fit_coef,calculate_x))
結果對比
雖然提醒我們給定的訓練值太少了,但是我們可以看到預測結果接近2.7182818284590452353602874713526624977572了