监督学习中关于线性回归问题的系统讨论
2015-01-04 22:19
113 查看
前言
本文将系统的介绍机器学习中监督学习的回归部分,系统的讲解如何利用回归理论知识来预测出一个分类的连续值。
显然,与监督学习中的分类部分相比,它有很鲜明的特点:输出为连续值,而不仅仅是标称类型的分类结果。
基本线性回归解决方案 - 最小二乘法
“给出一堆散点,求出其回归方程。" -> 对于这个问题,很多领域都碰到过,而其中最为经典普遍的做法通常是:
1. 用式子表示出各个散点到回归线之间的距离之和:
m 为散点数量,yi 为散点值,xi 为散点坐标,w 为回归系数向量。
2. 对上式以向量 w 求导,求出导数值为 0 时的回归系数 (具体求导过程涉及到对向量求导的相关法则,略):
这种方法就叫做最小二乘法。
最小二乘法的具体实现
下面这个小程序从文本中读取散点,然后拟合出回归直线,并使用 matplotlib 展示出来 (注: 为了清楚直观,特征 0 没展示出来):
测试结果:
观察预测与真实的相关系数:
测试结果:
0.98+的相关系数,可见拟合的效果还是不错的。
局部加权线性回归
基本的线性回归经常会碰到一些问题。
比如由于线性回归本身导致的欠拟合问题。以最基本的一个特征的情况为例,如果散点图本身呈现一个非线性化的轮廓,而强行的将它拟合成一条直线:
显然,两端的拟合是非常不科学的,偏离的很远。
针对这个问题,局部加权线性回归应运而生。它能够得到类似下图这样更为科学的拟合线段:
所谓局部,就是最大程度考虑待预测点附近的点,所谓加权,就是离待预测点越近,其参考系数(权重)就越大。
因此,在原先的最小二乘法中加入一个用于衡量权重的对角矩阵W。这样,回归系数的求解式就变为:
权重矩阵W又称为 "核",典型的高斯核的计算方法如下:
下面是采用局部加权线性回归思想的回归系数求解函数:
如下代码展示回归结果:
当k(衰减系数) = 1时,测试结果:
k(衰减系数) = 0.003时,测试结果:
k(衰减系数) = 0.01时,测试结果:
观察可以发现,k = 1就是和基本线性回归一样了 - 欠拟合;而 k = 0.003 则是过拟合了;k = 0.01 刚好,是最优的选择。
岭回归
假如碰到了这样的情况:散点个数小于特征数了。
这种情况有啥问题呢 ---- (xTx)-1 必然会求解失败!解决办法可以采用岭回归技术。
所谓岭回归,就是在回归系数求解式中的 xTx 之后加上 λI 使求逆部分可顺利求解,更改后的求解式如下:
其中,I 是单位对角矩阵,看起来有点像山岭。这也是为什么这种回归方式叫做岭回归,哈哈!
具体的实现代码本文就不具体给出了,但是有两个地方要特别注意一下:
1. 需要对所有的数据进行标准化
2. 根据不同的 λ 取到不同组的回归系数之后,还需要对不同组的权重进行择优。比较常用的有 lasso 方法(和岭回归的区别在于 w 和 λ 的约束关系)。
具体方案的制定
提到了这么多种的回归方案,那么具体应该采用哪种好呢?
首先,得根据问题的特性选择合适的方案。然后,使用同一组测试集测试每组方案的相关系数情况。
另外,实践表明在同样适用的情况下,"偏差与方差折中" 是一条很重要的经验法则。
红点位置对应的方案便是最佳方案。
小结
回归和分类一样,针对不同问题不同领域都有着不同算法。关键是要把握其整体思路,根据需要去进行选择。
然而,本文所讲解的都是线性回归。线性回归始终有其弊端,因为很多实际问题本身是非线性的。
即使是本文中介绍过的局部加权线性回归,想到每次测试都要拟合一次,也是挺蛋疼的。
因此在下篇文章中,将会专门详细地介绍一种高级的非线性回归法 - 树回归。
本文将系统的介绍机器学习中监督学习的回归部分,系统的讲解如何利用回归理论知识来预测出一个分类的连续值。
显然,与监督学习中的分类部分相比,它有很鲜明的特点:输出为连续值,而不仅仅是标称类型的分类结果。
基本线性回归解决方案 - 最小二乘法
“给出一堆散点,求出其回归方程。" -> 对于这个问题,很多领域都碰到过,而其中最为经典普遍的做法通常是:
1. 用式子表示出各个散点到回归线之间的距离之和:
m 为散点数量,yi 为散点值,xi 为散点坐标,w 为回归系数向量。
2. 对上式以向量 w 求导,求出导数值为 0 时的回归系数 (具体求导过程涉及到对向量求导的相关法则,略):
这种方法就叫做最小二乘法。
最小二乘法的具体实现
下面这个小程序从文本中读取散点,然后拟合出回归直线,并使用 matplotlib 展示出来 (注: 为了清楚直观,特征 0 没展示出来):
#!/usr/bin/env python # -*- coding:UTF-8 -*- ''' Created on 2015-01-04 @author: fangmeng ''' from numpy import * 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 #=================================== # 输入: # xArr: 特征坐标矩阵 # yArr: 特征值矩阵 # 输出: # w: 回归系数向量 #=================================== def standRegres(xArr,yArr): '采用最小二乘法求拟合系数' xMat = mat(xArr); yMat = mat(yArr).T xTx = xMat.T*xMat if linalg.det(xTx) == 0.0: print "该矩阵无法求逆" return ws = xTx.I * (xMat.T*yMat) return ws def test(): '展示结果' # 采用最小二乘求出回归系数并预测出各特征点对应的特征值 xArr, yArr = loadDataSet('/home/fangmeng/ex0.txt') ws = standRegres(xArr, yArr) xMat = mat(xArr) yMat = mat(yArr) yHat = xMat * ws import matplotlib.pyplot as plt # 绘制所有样本点 fig = plt.figure() ax = fig.add_subplot(111) ax.scatter(xMat[:,1].flatten().A[0], yMat.T[:, 0].flatten().A[0]) # 绘制回归线 xCopy = xMat.copy() xCopy.sort(0) yHat = xCopy*ws ax.plot(xCopy[:, 1], yHat) plt.show() if __name__ == '__main__': test()
测试结果:
观察预测与真实的相关系数:
print corrcoef(yHat.T, yMat)
测试结果:
0.98+的相关系数,可见拟合的效果还是不错的。
局部加权线性回归
基本的线性回归经常会碰到一些问题。
比如由于线性回归本身导致的欠拟合问题。以最基本的一个特征的情况为例,如果散点图本身呈现一个非线性化的轮廓,而强行的将它拟合成一条直线:
显然,两端的拟合是非常不科学的,偏离的很远。
针对这个问题,局部加权线性回归应运而生。它能够得到类似下图这样更为科学的拟合线段:
所谓局部,就是最大程度考虑待预测点附近的点,所谓加权,就是离待预测点越近,其参考系数(权重)就越大。
因此,在原先的最小二乘法中加入一个用于衡量权重的对角矩阵W。这样,回归系数的求解式就变为:
权重矩阵W又称为 "核",典型的高斯核的计算方法如下:
下面是采用局部加权线性回归思想的回归系数求解函数:
#=================================== # 输入: # testPoint: 测试点 # xArr: 特征坐标矩阵 # yArr: 特征值矩阵 # k: 高斯核权重衰减系数 # 输出: # testPoint * ws: 测试点集对应的结果 #=================================== def lwlr(testPoint,xArr,yArr,k=1.0): '对指定点进行局部加权线性回归' xMat = mat(xArr); yMat = mat(yArr).T m = shape(xMat)[0] # 采用向量方式计算高斯核 weights = mat(eye((m))) for j in range(m): diffMat = testPoint - xMat[j,:] weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2)) xTx = xMat.T * (weights * xMat) if linalg.det(xTx) == 0.0: print "错误: 系数矩阵无法求逆" return ws = xTx.I * (xMat.T * (weights * yMat)) return testPoint * ws #=================================== # 输入: # testArr: 测试点集 # xArr: 特征坐标矩阵 # yArr: 特征值矩阵 # 输出: # yHat: 测试点集对应的结果集 #=================================== def lwlrTest(testArr,xArr,yArr,k=1.0): '对指定点集进行局部加权回归' m = shape(testArr)[0] yHat = zeros(m) # 求出所有测试点集的 for i in range(m): yHat[i] = lwlr(testArr[i],xArr,yArr,k) return yHat
如下代码展示回归结果:
def test(): '展示结果' # 载入数据 xArr, yArr = loadDataSet('/home/fangmeng/ex0.txt') # 获取所有样本点的局部加权回归的预测值 yHat = lwlrTest(xArr, xArr, yArr, 0.01) xMat = mat(xArr) srtInd = xMat[:,1].argsort(0) xSort = xMat[srtInd][:,0,:] #print xMat[srtInd][:,0,:] # 显示所有样本点和局部加权拟合线段 import matplotlib.pyplot as plt 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()
当k(衰减系数) = 1时,测试结果:
k(衰减系数) = 0.003时,测试结果:
k(衰减系数) = 0.01时,测试结果:
观察可以发现,k = 1就是和基本线性回归一样了 - 欠拟合;而 k = 0.003 则是过拟合了;k = 0.01 刚好,是最优的选择。
岭回归
假如碰到了这样的情况:散点个数小于特征数了。
这种情况有啥问题呢 ---- (xTx)-1 必然会求解失败!解决办法可以采用岭回归技术。
所谓岭回归,就是在回归系数求解式中的 xTx 之后加上 λI 使求逆部分可顺利求解,更改后的求解式如下:
其中,I 是单位对角矩阵,看起来有点像山岭。这也是为什么这种回归方式叫做岭回归,哈哈!
具体的实现代码本文就不具体给出了,但是有两个地方要特别注意一下:
1. 需要对所有的数据进行标准化
2. 根据不同的 λ 取到不同组的回归系数之后,还需要对不同组的权重进行择优。比较常用的有 lasso 方法(和岭回归的区别在于 w 和 λ 的约束关系)。
具体方案的制定
提到了这么多种的回归方案,那么具体应该采用哪种好呢?
首先,得根据问题的特性选择合适的方案。然后,使用同一组测试集测试每组方案的相关系数情况。
另外,实践表明在同样适用的情况下,"偏差与方差折中" 是一条很重要的经验法则。
红点位置对应的方案便是最佳方案。
小结
回归和分类一样,针对不同问题不同领域都有着不同算法。关键是要把握其整体思路,根据需要去进行选择。
然而,本文所讲解的都是线性回归。线性回归始终有其弊端,因为很多实际问题本身是非线性的。
即使是本文中介绍过的局部加权线性回归,想到每次测试都要拟合一次,也是挺蛋疼的。
因此在下篇文章中,将会专门详细地介绍一种高级的非线性回归法 - 树回归。
相关文章推荐
- 第十一篇:监督学习中关于线性回归问题的系统讨论
- 【Android学习】关于Android4.4沉浸模式的进入和退出时系统栏状态栏遮盖问题
- sql server 关于表中只增标识问题 C# 实现自动化打开和关闭可执行文件(或 关闭停止与系统交互的可执行文件) ajaxfileupload插件上传图片功能,用MVC和aspx做后台各写了一个案例 将小写阿拉伯数字转换成大写的汉字, C# WinForm 中英文实现, 国际化实现的简单方法 ASP.NET Core 2 学习笔记(六)ASP.NET Core 2 学习笔记(三)
- USB2.0学习笔记连载(十):关于WIN8及以上系统哈希值问题
- 整理关于牛人们对图书管理系统领域建模的精彩讨论,以此希望大家学习下别人是如何思考的
- 计算机系统的初次学习(持续更新)------关于showbytes的相关问题
- 整理关于牛人们对图书管理系统领域建模的精彩讨论,以此希望大家学习下别人是如何思考的
- 今天又学习了,关于windows和Linux双系统删除Linux遇到的问题。
- 关于“在efi系统上,windows只能安装到gpt分区”的问题的解决方法的讨论(典型的宏基4750g)
- 关于系统时间格式的问题
- 关于系统托盘图标的小问题
- 引用,关于98/ME和2000/XP双系统的安装和启动原理的讨论。
- HSQLDB学习心得(1)-关于SERVER模式下多个数据库的启动问题与数据库连接
- 一个关于 客户端非法取消正在进行的数据提交操作 的问题 的讨论
- 关于remoting的系统配置问题
- 关于软件注册问题的讨论
- C++中关于操作符先(++)后(++)问题的讨论
- 原型方法论 ---关于软件原型方法若干问题的讨论
- 关于使用runtimeStyle属性问题讨论
- 关于asp.net开发B/S应用系统的思索和讨论