用线性回归找到最佳拟合直线
回归的目的是预测数值型的目标值。最直接的办法是依据输入写出一个目标值的计算公式。例如:
其中称作回归系数 是截距 一旦有了回归系数和截距,再次输入一个给定的值就能得到相应的结果值。所有说线性回归就是在一组数据中找出这样的回归系数和截距。
假定输入的数据存放在矩阵中,而回归系数存放在向量中。那么通过给定的数据,预测结果将会通过给出。现在的问题是,手里有一些和对应的,怎样才能找到?
一个常用方法就是找出是误差最佳最小的。这里的误差指的是真实值与预测值之间的差值。这里为了避免简单累加是的正负误差相互抵消,采用平方误差
用矩阵表示则。对w求导得到 令其为零解除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 这表示这个矩阵没有逆矩阵不能采用此方法进行回归
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)
样例数据.png
局部加权性回归
线性回归的一个问题是有可能出现欠拟合的现象,因为它求的是具有最小均方误差的无偏估计。所有有些方法允许在估计中加入一些偏差,从而降低预测的均方误差。其中一个方法就是局部加权线性回归。该算法中我们给代预测点附近的每个点赋予一定的权重,在这个子集上基于最小均方差来进行普通的回归。
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)) #权重值大小以指数衰减
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()
局部加权.png
网友评论