diff --git a/docs/8.预测数值型数据:回归.md b/docs/8.预测数值型数据:回归.md index 026c1e02..e2bb7730 100644 --- a/docs/8.预测数值型数据:回归.md +++ b/docs/8.预测数值型数据:回归.md @@ -21,9 +21,11 @@ HorsePower = 0.0015 * annualSalary - 0.99 * hoursListeningToPublicRadio ## 回归 原理 -### 回归 须知概念 +### 1、线性回归 -#### 1、矩阵求逆 +#### 1.1、线性回归 须知概念 + +##### 1.1.1、矩阵求逆 因为我们在计算回归方程的回归系数时,用到的计算公式如下: @@ -34,11 +36,11 @@ HorsePower = 0.0015 * annualSalary - 0.99 * hoursListeningToPublicRadio 判断矩阵的行列式是否为 0,若为 0 ,矩阵就不存在逆矩阵,不为 0 的话,矩阵才存在逆矩阵。 -#### 2、最小二乘法 +##### 1.1.2、最小二乘法 最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。 -### 回归 工作原理 +#### 1.2、线性回归 工作原理 ``` 读入数据,将数据特征想、特征标签y存储在矩阵x、y中 @@ -46,7 +48,7 @@ HorsePower = 0.0015 * annualSalary - 0.99 * hoursListeningToPublicRadio 使用最小二乘法求得 回归系数 w 的最佳估计 ``` -### 回归 开发流程 +#### 1.3、线性回归 开发流程 ``` 收集数据: 采用任意方法收集数据 @@ -57,7 +59,7 @@ HorsePower = 0.0015 * annualSalary - 0.99 * hoursListeningToPublicRadio 使用算法: 使用回归,可以在给定输入的时候预测出一个数值,这是对分类方法的提升,因为这样可以预测连续型数据而不仅仅是离散的类别标签 ``` -### 回归 算法特点 +#### 1.4、线性回归 算法特点 ``` 优点:结果易于理解,计算上不复杂。 @@ -65,27 +67,484 @@ HorsePower = 0.0015 * annualSalary - 0.99 * hoursListeningToPublicRadio 适用于数据类型:数值型和标称型数据。 ``` +#### 1.5、线性回归 项目案例 -> 线性回归的效果图 +##### 1.5.1、线性回归 项目概述 -![线性回归效果图](/images/8.Regression/线性回归效果图.png "线性回归效果图") +根据下图中的点,找出该数据的最佳拟合直线。 -## 局部加权线性回归 +![线性回归数据示例图](../images/8.Regression/LinearR_2.png "线性回归数据示例图") -> 局部加权线性回归简介 +数据格式为: ``` - 线性回归的一个问题是有可能出现欠拟合现象,因为它求的是具有最小均方误差的无偏估计。显而易见,如果模型欠拟合将不能取得最好的预测效果。 -所以有些方法允许在估计中引入一些偏差,从而降低预测的均方差。 - 其中的一个方法是局部加权线性回归(Locally Weighted Linear Regression, LWLR)。在该算法中,我们给带预测点附近的每个点赋予一定的权重, -在这个子集上基于最小均方差来进行普通的回归。与kNN一样,这种算法每次预测均需要实现选取出对应的数据子集。该算法解出回归系数w的形式如下: - w = (X^T W X)^(-1)X^T Wy +1.000000 0.067732 3.176513 +1.000000 0.427810 3.816464 +1.000000 0.995731 4.550095 +1.000000 0.738336 4.256571 +``` + +##### 1.5.2、线性回归 编写代码 + +```python +def loadDataSet(fileName): + """ 加载数据 + 解析以tab键分隔的文件中的浮点数 + Returns: + dataMat : feature 对应的数据集 + labelMat : feature 对应的分类标签,即类别标签 + + """ + # 获取样本特征的总数,不算最后的目标变量 + numFeat = len(open(fileName).readline().split('\t')) - 1 + dataMat = [] + labelMat = [] + fr = open(fileName) + for line in fr.readlines(): + # 读取每一行 + lineArr =[] + # 删除一行中以tab分隔的数据前后的空白符号 + curLine = line.strip().split('\t') + # i 从0到2,不包括2 + for i in range(numFeat): + # 将数据添加到lineArr List中,每一行数据测试数据组成一个行向量 + lineArr.append(float(curLine[i])) + # 将测试数据的输入数据部分存储到dataMat 的List中 + dataMat.append(lineArr) + # 将每一行的最后一个数据,即类别,或者叫目标变量存储到labelMat List中 + labelMat.append(float(curLine[-1])) + return dataMat,labelMat + + +def standRegres(xArr,yArr): + ''' + Description: + 线性回归 + Args: + xArr :输入的样本数据,包含每个样本数据的 feature + yArr :对应于输入数据的类别标签,也就是每个样本对应的目标变量 + Returns: + ws:回归系数 + ''' + + # mat()函数将xArr,yArr转换为矩阵 mat().T 代表的是对矩阵进行转置操作 + xMat = mat(xArr) + yMat = mat(yArr).T + # 矩阵乘法的条件是左矩阵的列数等于右矩阵的行数 + xTx = xMat.T*xMat + # 因为要用到xTx的逆矩阵,所以事先需要确定计算得到的xTx是否可逆,条件是矩阵的行列式不为0 + # linalg.det() 函数是用来求得矩阵的行列式的,如果矩阵的行列式为0,则这个矩阵是不可逆的,就无法进行接下来的运算 + if linalg.det(xTx) == 0.0: + print "This matrix is singular, cannot do inverse" + return + # 最小二乘法 + # http://www.apache.wiki/pages/viewpage.action?pageId=5505133 + # 书中的公式,求得w的最优解 + ws = xTx.I * (xMat.T*yMat) + return ws + + +def regression1(): + xArr, yArr = loadDataSet("input/8.Regression/data.txt") + xMat = mat(xArr) + yMat = mat(yArr) + ws = standRegres(xArr, yArr) + fig = plt.figure() + ax = fig.add_subplot(111) #add_subplot(349)函数的参数的意思是,将画布分成3行4列图像画在从左到右从上到下第9块 + ax.scatter(xMat[:, 1].flatten(), yMat.T[:, 0].flatten().A[0]) #scatter 的x是xMat中的第二列,y是yMat的第一列 + xCopy = xMat.copy() + xCopy.sort(0) + yHat = xCopy * ws + ax.plot(xCopy[:, 1], yHat) + plt.show() +``` + +##### 1.5.3、线性回归 拟合效果 + +![线性回归数据效果图](../images/8.Regression/LinearR_3.png "线性回归数据效果图") + + +### 2、局部加权线性回归 + +线性回归的一个问题是有可能出现欠拟合现象,因为它求的是具有最小均方差的无偏估计。显而易见,如果模型欠拟合将不能取得最好的预测效果。所以有些方法允许在估计中引入一些偏差,从而降低预测的均方误差。 + +一个方法是局部加权线性回归(Locally Weighted Linear Regression,LWLR)。在这个算法中,我们给预测点附近的每个点赋予一定的权重,然后与 线性回归 类似,在这个子集上基于最小均方误差来进行普通的回归。与 kNN 一样,这种算法每次预测均需要事先选取出对应的数据子集。该算法解出回归系数 w 的形式如下: + +![局部加权线性回归回归系数公式](../images/8.Regression/LinearR_4.png) + 其中 w 是一个矩阵,用来给每个数据点赋予权重。 + +LWLR 使用 “核”(与支持向量机中的核类似)来对附近的点赋予更高的权重。核的类型可以自由选择,最常用的核就是高斯核,高斯核对应的权重如下: + +![局部加权线性回归高斯核](../images/8.Regression/LinearR_5.png) + +这样就构建了一个只含对角元素的权重矩阵 **w**,并且点 x 与 x(i) 越近,w(i, i) 将会越大。上述公式中包含一个需要用户指定的参数 k,它决定了对附近的点赋予多大的权重,这也是使用 LWLR 时唯一需要考虑的参数,下面的图给出了参数 k 与权重的关系。 + +![参数k与权重的关系](../images/8.Regression/LinearR_6.png) + +上面的图是 每个点的权重图(假定我们正预测的点是 x = 0.5),最上面的图是原始数据集,第二个图显示了当 k = 0.5 时,大部分的数据都用于训练回归模型;而最下面的图显示当 k=0.01 时,仅有很少的局部点被用于训练回归模型。 + +#### 2.1、局部加权线性回归 工作原理 + +``` +读入数据,将数据特征想、特征标签y存储在矩阵x、y中 +利用高斯核构造一个权重矩阵 W,对预测点附近的点施加权重 +验证 X^TWX 矩阵是否可逆 +使用最小二乘法求得 回归系数 w 的最佳估计 ``` -> 局部加权线性回归效果图 +#### 2.2、局部加权线性回归 项目案例 + +##### 2.2.1、局部加权线性回归 项目概述 + +我们仍然使用上面 线性回归 的数据集,对这些点进行一个 局部加权线性回归 的拟合。 + +![局部加权线性回归数据示例图](../images/8.Regression/LinearR_2.png) + +数据格式为: + +``` +1.000000 0.067732 3.176513 +1.000000 0.427810 3.816464 +1.000000 0.995731 4.550095 +1.000000 0.738336 4.256571 +``` + +##### 2.2.2、局部加权线性回归 编写代码 + +```python + # 局部加权线性回归 +def lwlr(testPoint,xArr,yArr,k=1.0): + ''' + Description: + 局部加权线性回归,在待预测点附近的每个点赋予一定的权重,在子集上基于最小均方差来进行普通的回归。 + Args: + testPoint:样本点 + xArr:样本的特征数据,即 feature + yArr:每个样本对应的类别标签,即目标变量 + k:关于赋予权重矩阵的核的一个参数,与权重的衰减速率有关 + Returns: + testPoint * ws:数据点与具有权重的系数相乘得到的预测点 + Notes: + 这其中会用到计算权重的公式,w = e^((x^((i))-x) / -2k^2) + 理解:x为某个预测点,x^((i))为样本点,样本点距离预测点越近,贡献的误差越大(权值越大),越远则贡献的误差越小(权值越小)。 + 关于预测点的选取,在我的代码中取的是样本点。其中k是带宽参数,控制w(钟形函数)的宽窄程度,类似于高斯函数的标准差。 + 算法思路:假设预测点取样本点中的第i个样本点(共m个样本点),遍历1到m个样本点(含第i个),算出每一个样本点与预测点的距离, + 也就可以计算出每个样本贡献误差的权值,可以看出w是一个有m个元素的向量(写成对角阵形式)。 + ''' + # mat() 函数是将array转换为矩阵的函数, mat().T 是转换为矩阵之后,再进行转置操作 + xMat = mat(xArr) + yMat = mat(yArr).T + # 获得xMat矩阵的行数 + m = shape(xMat)[0] + # eye()返回一个对角线元素为1,其他元素为0的二维数组,创建权重矩阵weights,该矩阵为每个样本点初始化了一个权重 + weights = mat(eye((m))) + for j in range(m): + # testPoint 的形式是 一个行向量的形式 + # 计算 testPoint 与输入样本点之间的距离,然后下面计算出每个样本贡献误差的权值 + diffMat = testPoint - xMat[j,:] + # k控制衰减的速度 + weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2)) + # 根据矩阵乘法计算 xTx ,其中的 weights 矩阵是样本点对应的权重矩阵 + xTx = xMat.T * (weights * xMat) + if linalg.det(xTx) == 0.0: + print ("This matrix is singular, cannot do inverse") + return + # 计算出回归系数的一个估计 + ws = xTx.I * (xMat.T * (weights * yMat)) + return testPoint * ws + +def lwlrTest(testArr,xArr,yArr,k=1.0): + ''' + Description: + 测试局部加权线性回归,对数据集中每个点调用 lwlr() 函数 + Args: + testArr:测试所用的所有样本点 + xArr:样本的特征数据,即 feature + yArr:每个样本对应的类别标签,即目标变量 + k:控制核函数的衰减速率 + Returns: + yHat:预测点的估计值 + ''' + # 得到样本点的总数 + m = shape(testArr)[0] + # 构建一个全部都是 0 的 1 * m 的矩阵 + yHat = zeros(m) + # 循环所有的数据点,并将lwlr运用于所有的数据点 + for i in range(m): + yHat[i] = lwlr(testArr[i],xArr,yArr,k) + # 返回估计值 + return yHat + +def lwlrTestPlot(xArr,yArr,k=1.0): + ''' + Description: + 首先将 X 排序,其余的都与lwlrTest相同,这样更容易绘图 + Args: + xArr:样本的特征数据,即 feature + yArr:每个样本对应的类别标签,即目标变量,实际值 + k:控制核函数的衰减速率的有关参数,这里设定的是常量值 1 + Return: + yHat:样本点的估计值 + xCopy:xArr的复制 + ''' + # 生成一个与目标变量数目相同的 0 向量 + yHat = zeros(shape(yArr)) + # 将 xArr 转换为 矩阵形式 + xCopy = mat(xArr) + # 排序 + xCopy.sort(0) + # 开始循环,为每个样本点进行局部加权线性回归,得到最终的目标变量估计值 + for i in range(shape(xArr)[0]): + yHat[i] = lwlr(xCopy[i],xArr,yArr,k) + return yHat,xCopy + + +#test for LWLR +def regression2(): + xArr, yArr = loadDataSet("input/8.Regression/data.txt") + yHat = lwlrTest(xArr, xArr, yArr, 0.003) + xMat = mat(xArr) + srtInd = xMat[:,1].argsort(0) #argsort()函数是将x中的元素从小到大排列,提取其对应的index(索引),然后输出 + xSort=xMat[srtInd][:,0,:] + fig = plt.figure() + ax = fig.add_subplot(111) + ax.plot(xSort[:,1], yHat[srtInd]) + ax.scatter(xMat[:,1].flatten().A[0], mat(yArr).T.flatten().A[0] , s=2, c='red') + plt.show() +``` + +##### 2.2.3、局部加权线性回归 拟合效果 + +![局部加权线性回归数据效果图](../images/8.Regression/LinearR_7.png) + +上图使用了 3 种不同平滑值绘出的局部加权线性回归的结果。上图中的平滑系数 k =1.0,中图 k = 0.01,下图 k = 0.003 。可以看到,k = 1.0 时的模型效果与最小二乘法差不多,k=0.01时该模型可以挖出数据的潜在规律,而 k=0.003时则考虑了太多的噪声,进而导致了过拟合现象。 + +#### 2.3、局部加权线性回归 注意事项 + +局部加权线性回归也存在一个问题,即增加了计算量,因为它对每个点做预测时都必须使用整个数据集。 + + +### 3、线性回归 & 局部加权线性回归 项目案例 + +到此为止,我们已经介绍了找出最佳拟合直线的两种方法,下面我们用这些技术来预测鲍鱼的年龄。 + +#### 3.1、项目概述 + +我们有一份来自 UCI 的数据集合的数据,记录了鲍鱼(一种介壳类水生动物)的年龄。鲍鱼年龄可以从鲍鱼壳的层数推算得到。 + +#### 3.2、开发流程 + +``` +收集数据: 采用任意方法收集数据 +准备数据: 回归需要数值型数据,标称型数据将被转换成二值型数据 +分析数据: 绘出数据的可视化二维图将有助于对数据做出理解和分析,在采用缩减法求得新回归系数之后,可以将新拟合线绘在图上作为对比 +训练算法: 找到回归系数 +测试算法: 使用 rssError()函数 计算预测误差的大小,来分析模型的效果 +使用算法: 使用回归,可以在给定输入的时候预测出一个数值,这是对分类方法的提升,因为这样可以预测连续型数据而不仅仅是离散的类别标签 +``` + +> 收集数据: 采用任意方法收集数据 + +> 准备数据: 回归需要数值型数据,标称型数据将被转换成二值型数据 + +数据存储格式: + +``` +1 0.455 0.365 0.095 0.514 0.2245 0.101 0.15 15 +1 0.35 0.265 0.09 0.2255 0.0995 0.0485 0.07 7 +-1 0.53 0.42 0.135 0.677 0.2565 0.1415 0.21 9 +1 0.44 0.365 0.125 0.516 0.2155 0.114 0.155 10 +0 0.33 0.255 0.08 0.205 0.0895 0.0395 0.055 7 +``` + +> 分析数据: 绘出数据的可视化二维图将有助于对数据做出理解和分析,在采用缩减法求得新回归系数之后,可以将新拟合线绘在图上作为对比 + +> 训练算法: 找到回归系数 + +使用上面我们讲到的 局部加权线性回归 训练算法,求出回归系数 + +> 测试算法: 使用 rssError()函数 计算预测误差的大小,来分析模型的效果 + +```python +# test for abloneDataSet +def abaloneTest(): + ''' + Desc: + 预测鲍鱼的年龄 + Args: + None + Returns: + None + ''' + # 加载数据 + abX, abY = loadDataSet("input/8.Regression/abalone.txt") + # 使用不同的核进行预测 + oldyHat01 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 0.1) + oldyHat1 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 1) + oldyHat10 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 10) + # 打印出不同的核预测值与训练数据集上的真实值之间的误差大小 + print "old yHat01 error Size is :" , rssError(abY[0:99], oldyHat01.T) + print "old yHat1 error Size is :" , rssError(abY[0:99], oldyHat1.T) + print "old yHat10 error Size is :" , rssError(abY[0:99], oldyHat10.T) + + # 打印出 不同的核预测值 与 新数据集(测试数据集)上的真实值之间的误差大小 + newyHat01 = lwlrTest(abX[100:199], abX[0:99], abY[0:99], 0.1) + print "new yHat01 error Size is :" , rssError(abY[0:99], yHat01.T) + newyHat1 = lwlrTest(abX[100:199], abX[0:99], abY[0:99], 1) + print "new yHat1 error Size is :" , rssError(abY[0:99], yHat1.T) + newyHat10 = lwlrTest(abX[100:199], abX[0:99], abY[0:99], 10) + print "new yHat10 error Size is :" , rssError(abY[0:99], yHat10.T) + + # 使用简单的 线性回归 进行预测,与上面的计算进行比较 + standWs = standRegres(abX[0:99], abY[0:99]) + standyHat = mat(abx[100:199]) * standWs + print "standRegress error Size is:", rssError(abY[100:199], standyHat.T.A) +``` + +根据我们上边的测试,可以看出: + +简单线性回归达到了与局部加权现行回归类似的效果。这也说明了一点,必须在未知数据上比较效果才能选取到最佳模型。那么最佳的核大小是 10 吗?或许是,但如果想得到更好的效果,应该用 10 个不同的样本集做 10 次测试来比较结果。 + +> 使用算法: 使用回归,可以在给定输入的时候预测出一个数值,这是对分类方法的提升,因为这样可以预测连续型数据而不仅仅是离散的类别标签 + + +### 4、缩减系数来 “理解” 数据 + +如果数据的特征比样本点还多应该怎么办?是否还可以使用线性回归和之前的方法来做预测?答案是否定的,即我们不能再使用前面介绍的方法。这是因为在计算 ![矩阵求逆](../images/8.Regression/LinearR_8.png) 的时候会出错。 + +如果特征比样本点还多(n > m),也就是说输入数据的矩阵 x 不是满秩矩阵。非满秩矩阵求逆时会出现问题。 + +为了解决这个问题,我们引入了 `岭回归(ridge regression)` 这种缩减方法。接着是 `lasso法`,最后介绍 `前向逐步回归`。 + +#### 4.1、岭回归 + +简单来说,岭回归就是在矩阵 ![矩阵_1](../images/8.Regression/LinearR_9.png) 上加一个 λI 从而使得矩阵非奇异,进而能对 ![矩阵_2](../images/8.Regression/LinearR_10.png ) 求逆。其中矩阵I是一个 m * m 的单位矩阵, +对角线上元素全为1,其他元素全为0。而λ是一个用户定义的数值,后面会做介绍。在这种情况下,回归系数的计算公式将变成: + +![岭回归的回归系数计算](../images/8.Regression/LinearR_11.png ) + +岭回归最先用来处理特征数多于样本数的情况,现在也用于在估计中加入偏差,从而得到更好的估计。这里通过引入 λ 来限制了所有 w 之和,通过引入该惩罚项,能够减少不重要的参数,这个技术在统计学中也叫作 `缩减(shrinkage)`。 + +缩减方法可以去掉不重要的参数,因此能更好地理解数据。此外,与简单的线性回归相比,缩减法能取得更好的预测效果。 + +这里通过预测误差最小化得到 λ: 数据获取之后,首先抽一部分数据用于测试,生育的作为训练集用于训练参数 w。训练完毕后在测试集上测试预测性能。通过选取不同的 λ 来重复上述测试过程,最终得到一个使预测误差最小的 λ 。 + +##### 4.1.1、岭回归 原始代码 + +```python +def ridgeRegres(xMat,yMat,lam=0.2): + ''' + Desc: + 这个函数实现了给定 lambda 下的岭回归求解。 + 如果数据的特征比样本点还多,就不能再使用上面介绍的的线性回归和局部现行回归了,因为计算 (xTx)^(-1)会出现错误。 + 如果特征比样本点还多(n > m),也就是说,输入数据的矩阵x不是满秩矩阵。非满秩矩阵在求逆时会出现问题。 + 为了解决这个问题,我们下边讲一下:岭回归,这是我们要讲的第一种缩减方法。 + Args: + xMat:样本的特征数据,即 feature + yMat:每个样本对应的类别标签,即目标变量,实际值 + lam:引入的一个λ值,使得矩阵非奇异 + Returns: + 经过岭回归公式计算得到的回归系数 + ''' + + xTx = xMat.T*xMat + # 岭回归就是在矩阵 xTx 上加一个 λI 从而使得矩阵非奇异,进而能对 xTx + λI 求逆 + denom = xTx + eye(shape(xMat)[1])*lam + # 检查行列式是否为零,即矩阵是否可逆,行列式为0的话就不可逆,不为0的话就是可逆。 + 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): + ''' + Desc: + 函数 ridgeTest() 用于在一组 λ 上测试结果 + Args: + xArr:样本数据的特征,即 feature + yArr:样本数据的类别标签,即真实数据 + Returns: + wMat:将所有的回归系数输出到一个矩阵并返回 + ''' + + xMat = mat(xArr) + yMat=mat(yArr).T + # 计算Y的均值 + yMean = mean(yMat,0) + # Y的所有的特征减去均值 + yMat = yMat - yMean + # 标准化 x,计算 xMat 平均值 + xMeans = mean(xMat,0) + # 然后计算 X的方差 + xVar = var(xMat,0) + # 所有特征都减去各自的均值并除以方差 + xMat = (xMat - xMeans)/xVar + # 可以在 30 个不同的 lambda 下调用 ridgeRegres() 函数。 + numTestPts = 30 + # 创建30 * m 的全部数据为0 的矩阵 + wMat = zeros((numTestPts,shape(xMat)[1])) + for i in range(numTestPts): + # exp() 返回 e^x + ws = ridgeRegres(xMat,yMat,exp(i-10)) + wMat[i,:]=ws.T + return wMat + + +#test for ridgeRegression +def regression3(): + abX,abY = loadDataSet("input/8.Regression/abalone.txt") + ridgeWeights = ridgeTest(abX, abY) + fig = plt.figure() + ax = fig.add_subplot(111) + ax.plot(ridgeWeights) + plt.show() +``` + +##### 4.1.2、岭回归在鲍鱼数据集上的运行效果 + +![岭回归的运行效果](../images/8.Regression/LinearR_12.png) + +上图绘制除了回归系数与 log(λ) 的关系。在最左边,即 λ 最小时,可以得到所有系数的原始值(与线性回归一致);而在右边,系数全部缩减为0;在中间部分的某值将可以取得最好的预测效果。为了定量地找到最佳参数值,还需要进行交叉验证。另外,要判断哪些变量对结果预测最具有影响力,在上图中观察它们对应的系数大小就可以了。 + + +#### 4.2、lasso + +在增加如下约束时,普通的最小二乘法回归会得到与岭回归一样的公式: + +![lasso_1](../images/8.Regression/LinearR_13.png) + +上式限定了所有回归系数的平方和不能大于 λ 。使用普通的最小二乘法回归在当两个或更多的特征相关时,可能会得到一个很大的正系数和一个很大的负系数。正式因为上述限制条件的存在,使用岭回归可以避免这个问题。 + +与岭回归类似,另一个缩减方法lasso也对回归系数做了限定,对应的约束条件如下: + +![lasso_2](../images/8.Regression/LinearR_14.png) + + + + + + + + + + + + + + + + + + + + + + + -![局部加权线性回归效果图](/images/8.Regression/局部加权线性回归效果图.png "局部加权线性回归效果图") ## 岭回归和逐步线性回归 diff --git a/images/8.Regression/LinearR_10.png b/images/8.Regression/LinearR_10.png new file mode 100644 index 00000000..a7bc1ecc Binary files /dev/null and b/images/8.Regression/LinearR_10.png differ diff --git a/images/8.Regression/LinearR_11.png b/images/8.Regression/LinearR_11.png new file mode 100644 index 00000000..aae01206 Binary files /dev/null and b/images/8.Regression/LinearR_11.png differ diff --git a/images/8.Regression/LinearR_12.png b/images/8.Regression/LinearR_12.png new file mode 100644 index 00000000..c80e7573 Binary files /dev/null and b/images/8.Regression/LinearR_12.png differ diff --git a/images/8.Regression/LinearR_13.png b/images/8.Regression/LinearR_13.png new file mode 100644 index 00000000..0f56c9ee Binary files /dev/null and b/images/8.Regression/LinearR_13.png differ diff --git a/images/8.Regression/LinearR_14.png b/images/8.Regression/LinearR_14.png new file mode 100644 index 00000000..edf14023 Binary files /dev/null and b/images/8.Regression/LinearR_14.png differ diff --git a/images/8.Regression/LinearR_2.png b/images/8.Regression/LinearR_2.png new file mode 100644 index 00000000..486b362d Binary files /dev/null and b/images/8.Regression/LinearR_2.png differ diff --git a/images/8.Regression/LinearR_3.png b/images/8.Regression/LinearR_3.png new file mode 100644 index 00000000..ea453763 Binary files /dev/null and b/images/8.Regression/LinearR_3.png differ diff --git a/images/8.Regression/LinearR_4.png b/images/8.Regression/LinearR_4.png new file mode 100644 index 00000000..d64cb997 Binary files /dev/null and b/images/8.Regression/LinearR_4.png differ diff --git a/images/8.Regression/LinearR_5.png b/images/8.Regression/LinearR_5.png new file mode 100644 index 00000000..55b82c58 Binary files /dev/null and b/images/8.Regression/LinearR_5.png differ diff --git a/images/8.Regression/LinearR_6.png b/images/8.Regression/LinearR_6.png new file mode 100644 index 00000000..bdd26efb Binary files /dev/null and b/images/8.Regression/LinearR_6.png differ diff --git a/images/8.Regression/LinearR_7.png b/images/8.Regression/LinearR_7.png new file mode 100644 index 00000000..55675eef Binary files /dev/null and b/images/8.Regression/LinearR_7.png differ diff --git a/images/8.Regression/LinearR_8.png b/images/8.Regression/LinearR_8.png new file mode 100644 index 00000000..a95b0226 Binary files /dev/null and b/images/8.Regression/LinearR_8.png differ diff --git a/images/8.Regression/LinearR_9.png b/images/8.Regression/LinearR_9.png new file mode 100644 index 00000000..ce251652 Binary files /dev/null and b/images/8.Regression/LinearR_9.png differ diff --git a/src/python/8.PredictiveNumericalDataRegression/regression.py b/src/python/8.PredictiveNumericalDataRegression/regression.py index 16f2bd00..ce31f117 100644 --- a/src/python/8.PredictiveNumericalDataRegression/regression.py +++ b/src/python/8.PredictiveNumericalDataRegression/regression.py @@ -396,6 +396,41 @@ def regression2(): plt.show() +# test for abloneDataSet +def abaloneTest(): + ''' + Desc: + 预测鲍鱼的年龄 + Args: + None + Returns: + None + ''' + # 加载数据 + abX, abY = loadDataSet("input/8.Regression/abalone.txt") + # 使用不同的核进行预测 + oldyHat01 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 0.1) + oldyHat1 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 1) + oldyHat10 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 10) + # 打印出不同的核预测值与训练数据集上的真实值之间的误差大小 + print "old yHat01 error Size is :" , rssError(abY[0:99], oldyHat01.T) + print "old yHat1 error Size is :" , rssError(abY[0:99], oldyHat1.T) + print "old yHat10 error Size is :" , rssError(abY[0:99], oldyHat10.T) + + # 打印出 不同的核预测值 与 新数据集(测试数据集)上的真实值之间的误差大小 + newyHat01 = lwlrTest(abX[100:199], abX[0:99], abY[0:99], 0.1) + print "new yHat01 error Size is :" , rssError(abY[0:99], yHat01.T) + newyHat1 = lwlrTest(abX[100:199], abX[0:99], abY[0:99], 1) + print "new yHat1 error Size is :" , rssError(abY[0:99], yHat1.T) + newyHat10 = lwlrTest(abX[100:199], abX[0:99], abY[0:99], 10) + print "new yHat10 error Size is :" , rssError(abY[0:99], yHat10.T) + + # 使用简单的 线性回归 进行预测,与上面的计算进行比较 + standWs = standRegres(abX[0:99], abY[0:99]) + standyHat = mat(abx[100:199]) * standWs + print "standRegress error Size is:", rssError(abY[100:199], standyHat.T.A) + + #test for ridgeRegression def regression3(): abX,abY = loadDataSet("input/8.Regression/abalone.txt")