1、算法思想
2、程序实现
from numpy import *
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 standRegres(xArr,yArr): #计算最佳拟合曲线( 用ws=(X^TX)^-1X^TY求W)
xMat = mat(xArr); yMat = mat(yArr).T
xTx = xMat.T*xMat #(X^TX)
if linalg.det(xTx) == 0.0: #检测行列式4
print ("This matrix is singular, cannot do inverse")
return
ws = xTx.I * (xMat.T*yMat) #(X^TX)^-1X^TY
return ws
################################################ 局部加权线性回归法
def lwlr(testPoint,xArr,yArr,k=1.0): #局部加权线性回归法(加入高斯核来处理)w^=(X^T WX)^-1X^TY,W=exp(|x(i)-x|/-2k^2)
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): #为每个样本点调用lwlr(有助解K的大小)
m = shape(testArr)[0]
yHat = zeros(m)
for i in range(m):
yHat[i] = lwlr(testArr[i],xArr,yArr,k)
return yHat
def lwlrTestPlot(xArr,yArr,k=1.0): #绘制局部加权线性回归下的拟合曲线
yHat = zeros(shape(yArr))
xCopy = mat(xArr)
xCopy.sort(0)
for i in range(shape(xArr)[0]):
yHat[i] = lwlr(xCopy[i],xArr,yArr,k)
return yHat,xCopy
################################################ 岭回归法
def ridgeRegres(xMat,yMat,lam=0.2): #岭回归(给定lam求w)ws=(X^TX + lam I)^-1 X^TY
xTx = xMat.T*xMat
denom = xTx + eye(shape(xMat)[1])*lam #(X^TX + lam I)
if linalg.det(denom) == 0.0: #还需要检测,lam可能为0
print ("This matrix is singular, cannot do inverse")
return
ws = denom.I * (xMat.T*yMat)
return ws
def ridgeTest(xArr,yArr): #岭回归,选择不同的lam测试而得到一个误差最小的lam,再调用ridgeRegres求ws
xMat = mat(xArr); yMat=mat(yArr).T
#数据标准化
yMean = mean(yMat,0)
yMat = yMat - yMean
#regularize X's
xMeans = mean(xMat,0)
xVar = var(xMat,0)
xMat = (xMat - xMeans)/xVar
numTestPts = 30 #迭代次数
wMat = zeros((numTestPts,shape(xMat)[1]))
for i in range(numTestPts):
ws = ridgeRegres(xMat,yMat,exp(i-10))
wMat[i,:]=ws.T
return wMat
测试1:
#############################################绘制标准回归函数的拟合曲线
import matplotlib.pyplot as plt
mydata,myleb=loadDataSet('ex0.txt') #处理训练数据集
ws=standRegres(mydata,myleb)
xmat=mat(mydata)
ymat=mat(myleb)
yhat=xmat*ws
#################绘制散点图
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()
运行结果:
测试2:
#############################################绘制局部加权线性回归法的拟合曲线
import matplotlib.pyplot as plt
mydata,myleb=loadDataSet('ex0.txt')
yhat=lwlrTest(mydata,mydata,myleb,0.01)#改变K值可改变曲线的拟合程度
xmat=mat(mydata)
ymat=mat(myleb)
srtind=xmat[:,1].argsort(0)
xsort=xmat[srtind][:,0,:]
fig=plt.figure()
ax=fig.add_subplot(111)
ax.plot(xsort[:,1],yhat[srtind])#绘制拟合直线
ax.scatter(xmat[:,1].flatten().A[0],ymat.T[:,0].flatten().A[0],s=2,c='red')#绘制散点图
plt.show()
运行结果:
k=1时:
k=0.5时:
k=0.01时
k=0.003时
测试3:
#############################################绘制岭回归的回归系数变化图
import matplotlib.pyplot as plt
mydata,myleb=loadDataSet('abalone.txt')
ww=ridgeTest(mydata,myleb)
fig=plt.figure()
ax=fig.add_subplot(111)
ax.plot(ww)
plt.show()
运行结果:
测试2: