關(guān)于回歸和擬合,從它們的求解過程以及結(jié)果來看,兩者似乎沒有太大差別,事實也的確如此。從本質(zhì)上說,回歸屬于數(shù)理統(tǒng)計問題,研究解釋變量與響應(yīng)變量之間的關(guān)系以及相關(guān)性等問題。而擬合是把平面的一系列點(diǎn),用一條光滑曲線連接起來,并且讓更多的點(diǎn)在曲線上或曲線附近。更確切的說,擬合是回歸用到的一種數(shù)學(xué)方法,而擬合與回歸的應(yīng)用場合不同。擬合常用的方法有最小二乘法、梯度下降法、高斯牛頓(即迭代最小二乘)、列-馬算法。其中最最常用的就是最小二乘法。并且擬合可以分為線性擬合與非線性擬合,非線性擬合比較常用的是多項式擬合。根據(jù)自變量的個數(shù),擬合也可以分為曲線擬合與曲面擬合等。
而回歸大多數(shù)采用最小二乘法?;貧w可以分為一元線性回歸、一元非線性回歸、多元線性回歸、多元非線性回歸等。
通常情況下,擬合通常所處理的是一元函數(shù)(即曲線擬合),求自變量與因變量之間的關(guān)系;對于多元回歸問題,一般會涉及很多個解釋變量。通常情況下,我們會把線性回歸與線性擬合定義等同。本文對于回歸問題,與擬合方法結(jié)合,講解對于不同情況下擬合方程的求法,對相關(guān)系數(shù)等知識不做展開。
一:最小二乘法。
無論是在高等數(shù)學(xué)、線性代數(shù),還是數(shù)理統(tǒng)計,我們都可以看到最小二乘法的身影。只不過每一部分側(cè)重點(diǎn)不同,最終是殊途同歸的。但是兔兔建議用矩陣的方法來做,這樣很便于理解,計算起來也很方便。
最小二乘法的基本思路是:確定函數(shù)f(x),使得各個點(diǎn)x1,x2..xn處的函數(shù)值偏差f(x1)-y1、f(x2)-y2...f(xn)-yn的平方和或絕對值和最小。如果是一元線性擬合(回歸),我們可以設(shè)方程為f(x)=ax+b。
這時我們求得函數(shù)值偏差平方和為。為了求它的最小值,利用高數(shù)的方法,就可以使M分別對a和b的偏導(dǎo)為0,最終求解得方程組:
把方程組解出來得a,b就得出擬合結(jié)果了。這個式子也就是我們在數(shù)理統(tǒng)計中一元回歸方程中常用的式子之一,不過比較麻煩。當(dāng)自變量(解釋變量)的個數(shù)是多個時,我們設(shè)方程為,或者是多項式擬合,設(shè)函數(shù)為
。這樣逐個求偏導(dǎo)就麻煩很多。
這個時候矩陣的方法就使得擬合結(jié)果十分簡潔。而且可以發(fā)現(xiàn),如果用矩陣進(jìn)行一元線性擬合,展開后和上面那個結(jié)果是一致的。
例如對于多元線性回歸(二元時也可以看作是平面擬合),我們設(shè)每組數(shù)據(jù)有p個指標(biāo),一共有n組數(shù)據(jù),在多元統(tǒng)計中,我們稱:
為樣本數(shù)據(jù)矩陣(觀測陣)。如果我們設(shè)方程為,把每一組數(shù)據(jù)帶入,求偏導(dǎo)等于0 時各個a的值。這個推導(dǎo)過程比較麻煩。不過,如果我們對于這個式子,定義X、Y、a為:
這樣等式就是。之后就是
這樣,我們就很容易得到a了,雖然不是嚴(yán)格的證明,但是推算和應(yīng)用卻十分的簡便!嚴(yán)格的矩陣求導(dǎo)證明方法兔兔寫在下面了,感興趣的同學(xué)可以看一下。(關(guān)于矩陣求導(dǎo)可以看兔兔的另一篇《矩陣求導(dǎo)(本質(zhì)、原理與推導(dǎo))詳解》)
?
那么,一元多項式擬合也是如此。如果設(shè)方程為。定義X,Y,a為:
這樣等式就是Xa=Y,解法與推導(dǎo)與以上過程一樣,結(jié)果為:。
對于多元非線性回歸(擬合),也可以設(shè)多元多項式形式,擬合出多元多項式函數(shù)。
算法實現(xiàn):
(1)二元線性回歸:
對表格的數(shù)據(jù)做二元線性回歸。
指標(biāo)x1 | 7 | 1 | 11 | 7 | 11 | 3 | 8 | 9 | 2 |
指標(biāo)x2 | 26 | 29 | 56 | 31 | 52 | 55 | 71 | 31 | 54 |
y | 93 | 91 | 190 | 108 | 177 | 172 | 231 | 111 | 167 |
代碼實現(xiàn):
import numpy as np
x1=[7,1,11,7,11,3,8,9,2]
x2=[26,29,56,31,52,55,71,31,54]
y=[93,91,190,108,177,172,231,111,167]
X=np.mat([[1 for i in range(len(x1))],x1,x2]).T #把樣本轉(zhuǎn)成X
Y=np.mat(y).T #把y轉(zhuǎn)成Y
a=np.linalg.inv(X.T*X)*X.T*Y #求a的公式
a0=a[0,0];a1=a[1,0];a2=a[2,0]
ax=plt.axes(projection='3d')
xx=np.arange(2,12,0.1)
yy=np.arange(20,75,0.5)
XX,YY=np.meshgrid(xx,yy)
Z=a0+a1*XX+a2*YY #平面方程
ax.scatter(x1,x2,y,color="red") #畫散點(diǎn)
ax.plot_surface(XX,YY,Z,cmap="winter") #畫擬合平面
plt.show()
散點(diǎn)圖如下:
?擬合平面圖:
?我們發(fā)現(xiàn),大部分點(diǎn)都落在平面附近。
(2)一元多項式回歸
可以對表格的數(shù)據(jù)做三次多項式擬合。
x | 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 13 |
y | 18 | 20 | 0 | -10 | -12 | 0 | 180 | 308 | 702 |
import numpy as np
x=[1,2,4,5,6,7,10,11,13]
y=[18,20,0,-10,-12,0,180,308,702]
def to_X(x,n):
'''把數(shù)據(jù)X轉(zhuǎn)成矩陣X,n是擬合多項式的次數(shù)'''
l=[]
for i in x:
s=[]
for j in range(n+1):
s.append(i**j)
l.append(s)
return np.mat(l)
Y=np.mat(y).T
X=to_X(x=x,n=3) #做三次多項式擬合
a=np.linalg.inv(X.T*X)*X.T*Y
xx=np.arange(0,14,0.1)
yy=a[0,0]+a[1,0]*xx+a[2,0]*xx**2+a[3,0]*xx**3
plt.scatter(x,y,color="red") #畫散點(diǎn)圖
plt.plot(xx,yy) #擬合曲線
plt.show()
散點(diǎn)圖與擬合曲線圖如下所示:
?我們發(fā)現(xiàn),用三次多項式擬合,效果比較好。至于其它的多項式同學(xué)們也可以嘗試以下,但需要注意的是:有時不一定多項式次數(shù)越多,擬合效果越好。
(3)二元多項式擬合(曲面擬合)
對于曲面擬合情況,我們可以和曲線擬合,分為n次多項式擬合。如果假設(shè)是二次曲面,就是。三次曲面:
計算方法仍是把數(shù)據(jù)轉(zhuǎn)換成矩陣X,代入公式。我們對下面數(shù)據(jù)做二次曲面擬合。
x1 | 1 | -2 | 6 | 3 | 4 | -4 | -2 | 3 | 10 | |
x2 | 2 | 9 | -4 | 3 | 6 | -3 | 2 | 2 | -4 | |
y | 9 | 49 | 4 | 80 | 101 | 50 | 0 | 25 | 6 |
import numpy as np
x1=[1,-2,6,3,4,-4,-2,3,10]
x2=[2,9,-4,3,6,-3,2,2,-4]
y=[9,49,4,80,101,50,0,25,6]
def to_X(x1,x2):
n=len(x1)
X=[[1 for i in range(n)],
[i**2 for i in x1],
[j**2 for j in x2],
[i*j for i,j in zip(x1,x2)]]
return np.mat(X).T
X=to_X(x1,x2)
Y=np.mat(y).T
a=np.linalg.inv(X.T*X)*X.T*Y
a0=a[0,0];a1=a[1,0];a2=a[2,0];a3=a[3,0]
ax=plt.axes(projection='3d') #畫散點(diǎn)圖
ax.scatter(x1,x2,y,color='red')
xt=np.arange(-5,10)
yt=np.arange(-5,10)
Xt,Yt=np.meshgrid(xt,yt)
Z=a0+a1*Xt**2+a2*Yt**2+a3*Xt*Yt
ax.plot_surface(Xt,Yt,Z) #畫擬合曲面
plt.show()
運(yùn)行結(jié)果如下圖所示。
?二:梯度下降法
關(guān)于梯度下降法,兔兔在《梯度下降法(Gradient descant)算法詳解》一文已經(jīng)講過。在這里,我們先設(shè)函數(shù)f(x),然后求損失函數(shù)取最小值時的a的值(這里用二分之一是為了方便,求導(dǎo)后乘以2后化為1)。如果用矩陣表示,可以是。為了使損失函數(shù)最小,可以用梯度下降的方法并求得a值。關(guān)于矩陣的導(dǎo)數(shù)兔兔在上面的矩陣求導(dǎo)過程中已經(jīng)寫過,這里就不再重復(fù)了。
算法實現(xiàn)
x | 1 | 3 | 5 | 7 | 9 |
y | 3 | 5 | 7 | 8 | 12 |
import numpy as np
x=[1,3,5,7,9]
y=[3,5,7,8,12]
X=np.mat([[1 for i in range(5)],x]).T
Y=np.mat(y).T
def Grand_descend(x,y,circle=100,alpha=0.001):
'''梯度下降'''
a=np.random.normal(size=(2,1)) #初始化a
for i in range(circle): #迭代次數(shù)
a-= alpha*(X.T*X*a-X.T*Y) #批量梯度下降
return a
a=Grand_descend(x=X,y=Y)
xt=np.arange(0,10)
yt=a[0,0]+a[1,0]*xt
plt.scatter(x,y,color='red')
plt.plot(xt,yt,color='green')
plt.show()
結(jié)果如下:
?這里學(xué)習(xí)率需要小一些,否則容易出現(xiàn)梯度爆炸。迭代次數(shù)也需要適當(dāng)。對于前面最小二乘法的三個例子,同樣可以用梯度下降這種方法來進(jìn)行擬合計算。文章來源:http://www.zghlxwxcb.cn/news/detail-412718.html
三:總結(jié)
關(guān)于回歸(擬合)問題,本文先介紹了最小二乘法與梯度下降法,二者在公式推導(dǎo)上有很多相似的地方,目的都是在確定函數(shù)形式后,求損失函數(shù)的最小值時的參數(shù)。關(guān)于線性擬合問題,相對容易一些,而對于非線性的問題,往往還要因具體情況而分析,選特定的方法,兔兔之后會單獨(dú)講解。關(guān)于高斯牛頓與列-馬算法,二者也有許多相似之處,兔兔將會在第二部分進(jìn)行講解。文章來源地址http://www.zghlxwxcb.cn/news/detail-412718.html
到了這里,關(guān)于線性回歸(線性擬合)與非線性回歸(非線性擬合)原理、推導(dǎo)與算法實現(xiàn)(一)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!