用線性回歸找到最佳擬合直線
回歸的目的是預(yù)測(cè)數(shù)值型的目標(biāo)值。最直接的辦法是依據(jù)輸入寫出一個(gè)目標(biāo)值的計(jì)算公式。例如:
其中稱作回歸系數(shù)
是截距 一旦有了回歸系數(shù)和截距,再次輸入一個(gè)給定的值就能得到相應(yīng)的結(jié)果值。所有說(shuō)線性回歸就是在一組數(shù)據(jù)中找出這樣的回歸系數(shù)和截距。
假定輸入的數(shù)據(jù)存放在矩陣中,而回歸系數(shù)存放在向量
中。那么通過(guò)給定的數(shù)據(jù)
,預(yù)測(cè)結(jié)果將會(huì)通過(guò)
給出。現(xiàn)在的問(wèn)題是,手里有一些
和對(duì)應(yīng)的
,怎樣才能找到
?
一個(gè)常用方法就是找出是誤差最佳最小的。這里的誤差指的是真實(shí)值與預(yù)測(cè)值之間的差值。這里為了避免簡(jiǎn)單累加是的正負(fù)誤差相互抵消,采用平方誤差
用矩陣表示則。對(duì)w求導(dǎo)得到
令其為零解除w的值
from numpy import *
import matplotlib.pyplot as plt
def loadDataSet(fileName):
numFeat = len(open(fileName).readline().split('\t')) - 1
dataMat = [];labelMat = []
fr = open(fileName)
for line in fr.readlines():
lineArr = []
curLine = line.strip().split('\t')
for i in range(numFeat):
lineArr.append(float(curLine[i]))
dataMat.append(lineArr)
labelMat.append(float(curLine[-1]))
return dataMat,labelMat
def standRegress(xArr,yArr):
xMat = mat(xArr); yMat = mat(yArr).T
xTx = xMat.T*xMat #X^T * X
if linalg.det(xTx) == 0.0: #如果矩陣的行列式為0 這表示這個(gè)矩陣沒(méi)有逆矩陣不能采用此方法進(jìn)行回歸
print("This matrix is singular, cannot do inverse")
return
ws = xTx.I*(xMat.T*yMat) #xTx.I 表示(X^T * X)^-1
return ws
def drawMap(xArr,yArr,ws):
xMat = mat(xArr);
yMat = mat(yArr)
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)
plt.show()
if __name__ == '__main__':
xArr,yArr = loadDataSet('ex0.txt')
ws = standRegress(xArr,yArr)
drawMap(xArr, yArr, ws)
樣例數(shù)據(jù).png
局部加權(quán)性回歸
線性回歸的一個(gè)問(wèn)題是有可能出現(xiàn)欠擬合的現(xiàn)象,因?yàn)樗蟮氖蔷哂凶钚【秸`差的無(wú)偏估計(jì)。所有有些方法允許在估計(jì)中加入一些偏差,從而降低預(yù)測(cè)的均方誤差。其中一個(gè)方法就是局部加權(quán)線性回歸。該算法中我們給代預(yù)測(cè)點(diǎn)附近的每個(gè)點(diǎn)賦予一定的權(quán)重,在這個(gè)子集上基于最小均方差來(lái)進(jìn)行普通的回歸。
def lwlr(testPoint,xArr,yArr,k = 1.0):
xMat = mat(xArr);yMat = mat(yArr).T
m = shape(xMat)[0]
weights = mat(eye((m)))
for j in range(m):
diffMat = testPoint - xMat[j,:]
weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2)) #權(quán)重值大小以指數(shù)衰減
xTx = xMat.T*(weights*xMat)
if linalg.det(xTx) == 0.0:
print("this matrix is singular, cannot do inverse")
return
ws = xTx.I*(xMat.T*(weights*yMat))
return testPoint*ws
def lwlrTest(testArr,xArr,yArr,k = 1.0):
m = shape(testArr)[0]
yHat = zeros(m)
for i in range(m):
yHat[i] = lwlr(testArr[i],xArr,yArr,k)
return yHat
if __name__ == '__main__':
xArr,yArr = loadDataSet('ex0.txt')
yHat = lwlrTest(xArr,xArr,yArr,0.003)
xMat = mat(xArr);yMat = mat(yArr)
srtInd = xMat[:,1].argsort(0)
xSort = xMat[srtInd][:,0,:]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xMat[:, 1].flatten().A[0], yMat.T[:, 0].flatten().A[0],c='red',s=0.1)
ax.plot(xSort[:, 1], yHat[srtInd])
plt.show()
局部加權(quán).png