岭回归

岭回归

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 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)
    #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)
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值