岭回归
1、 解决问题
2、 原理
3、 算法
4、 实现代码
5、 交叉验证
- 1、 当数据的特征比样本点还要多怎么办?即:n>m。也就是说输入数据的矩阵不是满秩矩阵,非满秩矩阵求逆就会出现问题。——这是《机器学习实战》上的问题
除此之外,在其他大佬的博客和研究生论文到看到岭回归是主要解决复共线问题。
秩:将矩阵进行行列变换成梯形矩阵,不为0的行(列)的行(列)数称为矩阵的秩 - 2、 简单来说岭回归就是在矩阵
XTX
上加一个λI从而使得矩阵奇异,进而能对
XTX+λI
求逆,其实I是一个n*n的单位矩阵,对角线全为1,其他元素全为0,而λ是一个用定义的数值,那么回归系数就变成了:
w^=(XTX+λI)−1XTy
岭回归是对最小二乘回归的一种补充,它损失了无偏性,来换取高的数值稳定性,从而得到较高的计算精度。
岭回归最先用来处理特征数对于样本数的情况,现在也用于在估计中加入偏差,从而得到更好的估计,这里通过引入λ来限制所有w之和,通过引入该惩罚项,能够减少不重要的参数,这个技术在统计学中也叫缩减。 - 3、(1)将特征值处理,数据标准化
(2)规定一组λ值
(3)循环求出w在不同情况下的数据建立矩阵
(4)交叉验证找出最佳的λ值 - 4、代码
from numpy import *
import numpy as np
import pylab as pl
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 ridgeRegres(xMat,yMat,lam=0.2):
xTx = xMat.T*xMat
denom = xTx + eye(shape(xMat)[1])*lam
if linalg.det(denom) == 0.0:
print "This matrix is singular, cannot do inverse"
return
ws = denom.I * (xMat.T*yMat)
return ws
def ridgeTest(xArr,yArr):
xMat = mat(xArr); yMat=mat(yArr).T
yMean = mean(yMat,0)
yMat = yMat - yMean
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
def show(ws):
pl.plot(ws)
pl.show()
def main():
xArr,yArr = loadDataSet(r"C:\Users\l\Desktop\abalone.txt")
ws = ridgeTest(xArr,yArr)
show(ws)
if __name__ == '__main__':
main();
def rssError(yArr,yHatArr):
return ((yArr-yHatArr)**2).sum()
def crossValidation(xArr, yArr, numFold = 10):
m = len(yArr)
indexList = range(m)
errorMat = zeros((numFold, 30))
for i in range(numFold):
trainX = []; trainY = []
testX = []; testY = []
random.shuffle(indexList)
for j in range(m):
if j < 0.9*m:
trainX.append(xArr[indexList[j]])
trainY.append(yArr[indexList[j]])
else:
testX.append(xArr[indexList[j]])
testY.append(yArr[indexList[j]])
wMat = ridgeTest(trainX, trainY)
for k in range(30):
matTestX = mat(testX)
matTrainX = mat(trainX)
meanTrainX = mean(trainX, 0)
varTrainX = var(matTrainX, 0)
meanTrainY = mean(trainY, 0)
matTestX = (matTestX - meanTrainX)/varTrainX
yEst = matTestX * mat(wMat[k, :]).T + mean(trainY)
errorMat[i, k] = rssError(yEst.T.A, array(testY))
print errorMat
meanErrors = mean(errorMat, 0)
minErrors = float(min(meanErrors))
bestWeights = wMat[nonzero(meanErrors == minErrors)]
xMat = mat(xArr)
yMat = mat(yArr)
meanX = mean(xMat, 0)
varX = var(xMat, 0)
print varX
unReg = bestWeights/varX
print unReg
print -1*sum(multiply(meanX,unReg)) + mean(yMat)