岭回归

来源:互联网 发布:115 会员 淘宝 下架 编辑:程序博客网 时间:2024/04/20 21:26

岭回归

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、代码
# coding=utf-8 from numpy import *import numpy as npimport 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,labelMatdef 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 wsdef 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 wMatdef show(ws):    pl.plot(ws)    pl.show()def main():    xArr,yArr = loadDataSet(r"C:\Users\l\Desktop\abalone.txt")    ws = ridgeTest(xArr,yArr)    #print ws    show(ws)if __name__ == '__main__':    main();

8个系数

  • 5、交叉验证求最佳系数
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))# 每一行都有30个λ得到的结果    for i in range(numFold):        trainX = []; trainY = []        testX = []; testY = []        random.shuffle(indexList)# 把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]])        # 30组系数,返回维度为30*8的数组        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))    # 找到最优的λ之后,选取最后一轮迭代的wMat的对应的λ的权重作为最佳权重    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)
原创粉丝点击