初步岭回归

来源:互联网 发布:数据库分析工具 编辑:程序博客网 时间:2024/04/19 03:49

  • 岭回归
    • 1 机器学习实战
    • 2 交叉验证

岭回归

1、 机器学习实战

    在机器学习实战中,是这么引入岭回归的:
如果特征比样本还多(n > m),也就是说输入的数据矩阵X不是满秩矩阵。非满秩矩阵在求逆时会出错( (XTX)1)为了解决这个问题统计学家引入了这么个概念。岭回归最先用来处理特征数多于样本情况,现在也用于在估计中加入偏差,从而得到更好的估计。这里引入λ来限制W之和,通过引入惩罚项,能减少不重要的参数。
    但是公式具体是怎么个意思,书上并没有讲啊……,心情很烦啊!!

2、 交叉验证

k折交叉验证 k-fold cross validation
将全部训练数据S分成k个不相交的子集,假设S中的训练样例个数为m,那么每一个子集有m/k个训练样例,相应的子集为 {s1,s2,…,sk};
每次从分好的子集中中拿出一个作为测试集,其它k-1个作为训练集;
根据训练训练出模型或者假设函数;
把这个模型放到测试集上,得到分类率;
计算k次求得的分类率的平均值,作为该模型或者假设函数的真实分类率。
这个方法充分利用了所有样本。但计算比较繁琐,需要训练k次,测试k次。

先贴代码吧

#encoding:utf-8import numpy as pyfrom numpy import *#加载数据def loadDataSet(filename):    datMat=[]    labelMat=[]    numfat = len(open(filename).readline().split('\t')) - 1    for line in open(filename).readlines():        linArr =[]        curline = line.strip().split('\t')        for i in range(numfat):            linArr.append(float(curline[i]))        datMat.append(linArr)        labelMat.append(float(curline[-1]))    return datMat,labelMatdef rigeRes(xMat, yMat,lam = 0.2):    xTx = xMat.T*xMat    denom = xTx+eye(shape(xMat)[1])*lam    if linalg.det(denom) == 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]))#存储不同lambda对应的回归系数    #处理30个不同lambda对应岭回归  通过交叉验证选出最好的lambda最为回归系数    for i in range(numTestPts):        ws = rigeRes(xMat, yMat, exp(i - 10))        wMat[i,:] = ws.T    return wMatdef rssError(xArr,yArr):    return ((xArr - yArr)**2).sum()'''交叉验证测试岭回归'''  def crossValidation(xArr, yArr, numVal = 10):#默认交叉验证次数10    errorMat=zeros((numVal, 30))#每行 代表每次验证不同lambda 对应回归系数产生的误差,    xMat = mat(xArr)    m,n = shape(xMat)    indexList = range(m)#存储样本个数的下标    for i in range(numVal):#交叉验证的次数        #数据分为训练集和测试集容器        testX=[];trainX=[]#        testY=[];trainY=[]        random.shuffle(indexList)  #对其中的元素进行混洗,因此可以进行随机提取        for j in range(m):            if j < m * 0.9:#90%为训练集                trainX.append(xArr[indexList[j]])                trainY.append(yArr[indexList[j]])            else:                testX.append(xArr[indexList[j]])                testY.append(yArr[indexList[j]])        ws = ridgeTest(trainX, trainY)#会产生30行n列(n个特征值)de回归系数 具体上面岭回归函数那块        for k in range(30):#30代表前面30个lambda            #岭回归需要使用标准化后的数据,因此测试数据也需要用与测试集相同的参数来执行标准化            matTestX = mat(testX)            matTrainX = mat(trainX)            meanTrain = mean(matTrainX, 0)            varTrain = var(matTrainX, 0)            matTestX = (matTestX - meanTrain)/varTrain#标准化            yEst = matTestX*mat(ws[k,:]).T+mean(trainY)#计算误差            errorMat[i,k] = rssError(yEst.T.A, testY)#第i次验证,第k个lambda对应的误差    meanErrors = mean(errorMat, 0)#求出不同lambda对应的平均误差值    minMean = float(min(meanErrors))#找出最小值    bestWeights = ws[nonzero(meanErrors == minMean)]#找出最小误差值lambda在ws里面所对应的位置    #对数据进行还原    xMat = mat(xArr)    yMat =mat(yArr).T    meanX = mean(xMat, 0)    varX = var(xMat, 0)    unReg = bestWeights/varX    print "the model from Regression is:\n",unReg#还原后的回归系数    print "with constant term:"    print -1*sum(multiply(meanX, unReg)) + mean(yMat)def show(ridgeWeights):    import matplotlib.pyplot as plt    fig = plt.figure()    ax = fig.add_subplot(111)#     ax.plot(ridgeWeights)#接收一个矩阵,横坐标就是第几列,纵坐标就是矩阵第一列里面的所有数    #比如说我要化w0 w1#     ax.plot(ridgeWeights[:,0]) #所有行第一列的代表w0随lambda值变化而变化#     ax.plot(ridgeWeights[:,1])#所有行第二列的代表w1随lambda值变化而变化    plt.show()abx,aby = loadDataSet('abalone.txt')ridgeWeights = ridgeTest(abx, aby)print ridgeWeightsshow(ridgeWeights)crossValidation(abx, aby)
原创粉丝点击