《机器学习实战》笔记——regression
本章介绍了不同场景下使用的线性回归方法
一般情况:简单的线性回归
欠拟合:局部加权线性回归
特征数大于样本数:岭回归 或 lasso法
最后引出交叉验证,用来定量地找到最佳参数值
1 # _*_ coding:utf-8_*_ 2 3 # 8-1 标准回归函数和数据导入函数 4 from numpy import * 5 # 将数据格式化 6 def loadDataSet(fileName): 7 numFeat = len(open(fileName).readlines()[0].split('\t')) - 1 8 dataMat = [] 9 labelMat = [] 10 fr = open(fileName) 11 for line in fr.readlines(): 12 lineArr = [] 13 curLine = line.strip().split('\t') 14 for i in range(numFeat): # float()不能将整个list中的元素进行类型转换,所以用一个循环,一个元素一个元素地转换 15 lineArr.append(float(curLine[i])) 16 dataMat.append(lineArr) 17 labelMat.append(float(curLine[-1])) 18 return dataMat, labelMat 19 20 # 计算系数向量w的最佳估计,其中要求xTx的逆,所以先要判断它是否为满秩矩阵(行列式不为0), 21 # 若否,则不能进一步计算。这里并没有提供伪逆矩阵的做法 22 def standRegres(xArr, yArr): # 矩阵相乘要把结构改成matrix,否则array的*只能对元素进项相乘 23 xMat = mat(xArr) 24 yMat = mat(yArr).T 25 xTx = xMat.T * xMat 26 if linalg.det(xTx) == 0.0: # numpy提供了一个线性代数库linalg(linear algebra), 27 # 其中包含计算行列式(determinant)的方法det(), 28 # 为什么可以用==比较浮点数????????????? 29 print "This matrix is singular, cannot do inverse" 30 return 31 ws = xTx.I * (xMat.T * yMat) 32 return ws 33 34 # 效果 35 36 xArr,yArr = loadDataSet('ex0.txt') 37 print xArr[0:2] 38 39 ws = standRegres(xArr,yArr) 40 41 xMat=mat(xArr) 42 yMat=mat(yArr) 43 yHat=xMat*ws #y的预测值 44 45 import matplotlib.pyplot as plt 46 fig = plt.figure() 47 ax = fig.add_subplot(111) 48 ax.scatter(xMat[:,1].flatten().A[0],yMat.T[:,0].flatten().A[0],10) # flatten()方法能将matrix的元素变成一维的, 49 # .A能使matrix变成array .A[0]能少一个[] 虽然我不明白到底什么意思,以后注意一下 50 # 另外,为什么前两个参数需要转变成array?明明matrix也能画出来 51 print (corrcoef(yHat.T, yMat)) 52 53 xCopy = xMat.copy() 54 xCopy.sort(0) 55 yHat = xCopy *ws 56 ax.plot(xCopy[:,1],yHat,'red') 57 58 59 plt.show() 60 61 62 # 8-2 局部加权线性回归函数 63 def lwlr(testPoint, xArr, yArr, k=1.0): # 参数k控制衰减速度; testPoint为输入,函数返回根据加权线性回归得出的预测值 64 xMat = mat(xArr) 65 yMat = mat(yArr).T 66 m = shape(xMat)[0] 67 weights = mat(eye(m)) 68 for j in range(m): 69 diffMat = testPoint - xMat[j,:] 70 weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2)) 71 xTx = xMat.T*(weights*xMat) 72 if linalg.det(xTx) == 0.0: 73 print "this matrix is singular, cannot do inverse" 74 return 75 ws = xTx.I*(xMat.T*(weights*yMat)) 76 return testPoint * ws 77 78 def lwlrTest(testArr, xArr, yArr, k=1.0): 79 m = shape(testArr)[0] 80 yHat = zeros(m) 81 for i in range(m): 82 yHat[i] = lwlr(testArr[i], xArr, yArr, k) 83 return yHat 84 85 xArr,yArr = loadDataSet('ex0.txt') 86 yHat = lwlrTest(xArr, xArr, yArr, 0.01) 87 xMat = mat(xArr) 88 srtInd = xMat[:,1].argsort(0) # argsort()方法返回的是排序后个元素排序前的下标 89 xSort = xMat[srtInd][:,0,:] # 这个功能看懂了 但是语法没搞懂??????? 90 91 import matplotlib.pyplot as plt 92 fig = plt.figure() 93 ax = fig.add_subplot(111) 94 ax.plot(xSort[:,1], yHat[srtInd]) 95 ax.scatter(xMat[:,1].flatten().A[0], mat(yArr).T.flatten().A[0], s=2, c='red') 96 plt.show() 97 98 99 # 8-3 岭回归(xTx肯定不是满秩矩阵,加上一个lam*I使其变为满秩的,I是单位矩阵) 100 101 def ridgeRegres(xMat, yMat, lam=0.2): 102 xTx = xMat.T * xMat 103 denom = xTx+lam*eye(len(xTx[0])) 104 if linalg.det(denom) == 0.0: 105 print "this matrix is not singular, cannot do inverse" 106 return 107 ws = denom.I * (xMat.T*yMat) 108 return ws 109 110 # 先对特征进行标准化处理,是每维特征具有相同重要性,这里的做法是所有特征减去各自的均值并处理方差 111 def ridgeTest(xArr, yArr): 112 xMat = mat(xArr) 113 yMat = mat(yArr).T 114 yMean = mean(yMat,0) 115 yMat = yMat - yMean 116 xMeans = mean(xMat,0) 117 xVar = var(xMat, 0) 118 xMat = (xMat - xMeans)/xVar 119 numTestPts = 30 # 在30个不同的lambda下调用ridgeRegres()函数 120 wMat = zeros((numTestPts, shape(xMat)[1])) 121 for i in range(numTestPts): 122 ws = ridgeRegres(xMat, yMat, exp(i-10)) # lambda以指数级变化,这样能看出lambda在去非常小的值时和取非常大的值时对结果造成的影响 123 wMat[i,:]=ws.T 124 return wMat 125 126 # 8-4 前向逐步线性回归 127 128 # 标准化特征(书上漏了这部分) 129 def regularize(xMat): 130 inMat = xMat.copy() 131 inMeans = mean(inMat,0) 132 inVar = var(inMat,0) 133 inMat = (inMat - inMeans)/inVar 134 return inMat 135 136 def rssError(yArr, yHatArr): 137 return ((yArr-yHatArr)**2).sum() 138 139 # 对每个特征,将他的系数从一个初始值开始以特定步长增大或减少,一旦误差变小就用lowestError来记录最小误差,用wsMax来记录最优权重。 140 def stageWise(xArr, yArr, eps=0.01, numIt=100): # eps表示每次迭代需要调整的步长 141 xMat = mat(xArr) 142 yMat = mat(yArr).T 143 yMean = mean(yMat,0) 144 yMat = yMat - yMean 145 xMat = regularize(xMat) 146 m,n = shape(xMat) 147 returnMat = zeros((numIt,n)) 148 ws = zeros((n,1)) 149 wsTest = ws.copy() 150 wsMax = ws.copy() 151 for i in range(numIt): 152 print ws.T 153 lowestError = inf 154 for j in range(n): 155 for sign in [-1,1]: 156 wsTest = ws.copy() 157 wsTest[j] += eps*sign 158 yTest = xMat * wsTest 159 rssE = rssError(yMat.A, yTest.A) 160 if rssE < lowestError: 161 lowestError = rssE 162 wsMax = wsTest 163 ws =wsMax.copy() 164 returnMat[i,:] = ws.T 165 return returnMat