從只含一個自變量X的情況開始,成為一元線性回歸。假定回歸模型為
Y=b0+b1X+e
b0,b1為未知參數,b0為常數項或截距,b1為回歸系數,e為隨機誤差。實際工作中,也常使用變量變換法。即在散點圖與直線趨勢差距較大時,設法對自變量乃至因變量進行適當的變換,使變換后的散點圖更加接近與直線。這樣對變化后的新變量進行線性回歸分析,再回到原變量。
假定Y = b0+b1X+e
л和э分別為x和y的算術平均,故可以改寫為Yi=β0+β1(Xi-л)+ei (i = 1,....,n)
其關系是β0=b0+b1л,β1=b1,故如估計了β0和β1,可以得到b0和b1的估計。
當X=Xi處取值為Yi,估計值我們有Γ表示,這樣我們就有偏離Yi-Γ,我們當然希望偏離越小越好。衡量這種偏離大小的一個合理的單一指標為他們的平方和(通過平方去掉符號的影響,若簡單求和,則正負偏離抵消了)
最優,即導數等于0.
我們將這個平方和求導,且認定該導數為0,得到的β0,β1,使得偏離最小。
用線性代數的思想就是,假定輸入數據存在矩陣X中,而回歸系數存放在向量w中。那么對于給定的數據X1,預測結果將會通過Y1=(X.transpose)w給出。偏差的平方為
Paste_Image.png
如果對w求導,得到
Paste_Image.png
為求最優,令其等于0,則
Paste_Image.png
上述公式中包含
Paste_Image.png
因此這個方程只在逆矩陣存在的情況使用。因為矩陣的逆矩陣可能不存在,因此必須要在代碼中對此作出判斷。
用python進行代碼的實現
from numpy import *
def loadDataSet(filename):
numFeat = len(open(filename).readline().split(','))-1
datMat = []; labelMat = []
fr = open(filename)
for line in fr.readlines():
lineArr = []
curLine = line.strip().split(',')
for i in range(numFeat):
lineArr.append(float(curLine[i]))
datMat.append(lineArr)
labelMat.append(float(curLine[-1]))
return datMat,labelMat
def standRegres(xArr,yArr):
xMat = mat(xArr);yMat = mat(yArr).T
xTx = xMat.T*xMat
if linalg.det(xTx) == 0.0:
print("This matrix is singular, can not inverse")
return
ws = xTx.I * (xMat.T*yMat)
return ws
xArr,yArr = loadDataSet('gmvusers3.csv')
print("xArr is ",xArr)
print("yArr is ",yArr)
ws = standRegres(xArr,yArr)
print(ws)
xMat = mat(xArr)
yMat = mat(yArr)
yHat =xMat*ws
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xMat[:,1].flatten().A[0],yMat.T[:,0].flatten().A[0])
xCopy = xMat.copy()
xCopy.sort(0)
yHat=xCopy*ws
ax.plot(xCopy[:,1],yHat,'b-')
print(corrcoef(yHat.T,yMat))
plt.show()
感謝高斯,或者勒讓德,歷史無法評說,但這種思想是一種用于數據擬合的霸氣方法。這個事情的精妙之處就是將數理統計和矩陣完美的結合在了一起,通過矩陣對最小二乘法的描述,為數據擬合找到了簡單粗暴的路徑,線性回歸。
下面簡要列出梯度下降法和最小二乘法的主要區別
梯度下降法 | 最小二乘法 |
---|---|
必須指定learning rate | 無需指定learning rate |
必須訓練多次 | 無需訓練多次 |
無 | 必須可逆XTX |
對多維度數據效果好 | 多維度數據效果差(維度>1000) |