A-05 前向选择法和前向梯度法
更新、更全的《机器学习》的更新网站,更有python、go、数据结构与算法、爬虫、人工智能教学等着你:https://www.cnblogs.com/nickchen121/p/11686958.html
前向选择法和前向梯度法
由于前向选择法和前向梯度法的实现原理涉及过多的矩阵运算,本文只给出两种算法的思路。两者实现都是把矩阵中的向量运算具体化成平面几何中的向量运算。
一、前向选择法
前向选择法是一种典型的贪心算法。
通常用前向选择法解决线性模型的回归系数。对于一个有\(m\)个样本,每个样本有\(n\)个特征的训练集而言,假设可以拟合一个线性模型\(Y=\omega^TX\),其中\(Y\)是\(m*1\)的向量,\(X\)是\(m*n\)的矩阵,\(\omega\)是\(n*1\)的向量。即可通过前向选择法求得最小化该模型的参数\(\omega\)。
1.1 余弦相似度求投影
首先把矩阵\(X\)看成\(n\)个\(m*1\)的向量\(X_i \quad(i=1,2,\cdots,n)\),之后选择与向量\(Y\)余弦相似度最大,即与\(Y\)最为接近的一个变量\(X_i\),然后用\(X_i\)逼近\(Y\),即可得到
\]
其中\(\omega_i={\frac{<X_i,Y>}{{||X_i||}^2}}\quad\text{余弦相似度}\),其中\(<X_i,Y>=|Y|*\cos\alpha\),\(\alpha\)是\(X_i\)和\(Y\)的夹角。
上述公式因此可以认为\(\hat{Y}\)是\(Y\)在\(X_i\)上的投影。
得到\(Y\)的接近值\(\hat{Y}\)后既可以得到残差值为\(Y_{err}=Y-\hat{Y}\),由于\(\hat{Y}\)是投影,则\(\hat{Y}\)和\(X_i\)是正交的,因此可以以\(Y_{err}\)为新的变量,从剩下的\(X_i\quad(i=1,2,i-1,i+2,\cdots,n)\)中,选择一个新的最接近残差\(Y_{err}\)的\(X_i\)重复上述投影和计算残差的流程,直至残差为0,停止算法。即可得到\(\omega\)。
1.2 举例
# 举例图例
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
%matplotlib inline
font = FontProperties(fname='/Library/Fonts/Heiti.ttc')
# X1*w1
plt.annotate(xytext=(2, 5), xy=(8, 5), s='', color='r',
arrowprops=dict(arrowstyle="->", color='r'))
plt.text(6, 4.5, s='$X_1*\omega_1$', color='g')
# X2*w2
plt.annotate(xytext=(8, 5), xy=(9.3, 7.5), s='', color='r',
arrowprops=dict(arrowstyle="->", color='r'))
plt.text(9.3, 7, s='$X_2*\omega_2$', color='g')
# X1
plt.annotate(xytext=(2, 5), xy=(4, 5), s='', color='r',
arrowprops=dict(arrowstyle="->", color='k'))
plt.text(2.5, 4.5, s='$X_1$', color='g')
# X2
plt.annotate(xytext=(2, 5), xy=(3, 7), s='', color='r',
arrowprops=dict(arrowstyle="->", color='k'))
plt.text(2, 6, s='$X_2$', color='g')
# X2
plt.annotate(xytext=(8, 5), xy=(9, 7), s='', color='r',
arrowprops=dict(arrowstyle="->", color='k'))
plt.text(8.2, 6.5, s='$X_2$', color='g')
# Y
plt.annotate(xytext=(2, 5), xy=(8, 8), s='', color='r',
arrowprops=dict(arrowstyle="->", color='k'))
plt.text(5, 7.5, s='$Y$', color='g')
#
plt.annotate(xytext=(8, 5), xy=(8, 8), s='', color='r',
arrowprops=dict(arrowstyle="-", color='gray'))
plt.text(7.5, 6.5, s='$Y_1$', color='g')
#
plt.annotate(xytext=(8, 8), xy=(9.3, 7.5), s='',
arrowprops=dict(arrowstyle="-", color='gray'))
plt.text(8.5, 8, s='$Y_2$', color='g')
plt.xlim(0, 11)
plt.ylim(2, 10)
plt.title('前向选择法举例', fontproperties=font, fontsize=20)
plt.show()
![png](http://www.chenyoude.com/ml/A-05 前向选择法和前向梯度法_7_0.png?x-oss-process=style/watermark)
上图假设\(X\)为\(2\)维,首先可以看出,离\(Y\)最接近的是\(X_1\),因此画出\(Y\)在\(X_1\)上的投影红线\(X_1*\omega_1\),此时残差为灰线\(Y_1\)。由于目前只剩下\(X_2\),所以接着用残差\(Y_1\)在\(X_2\)上投影得到红线\(X_2*\omega_2\),如果不只是\(X_2\),则选择最接近\(Y_1\)的\(X_i\)。此时的\(X_1\omega_1+X_2\omega_2\)则模拟了\(Y\),即\(\omega=[\omega_1,\omega_2]\)。
1.3 前向选择法优缺点
1.3.1 优点
- 算法对每个\(X_i\)只做一次操作,速度快。
1.3.2 缺点
- 由于变量\(X_i\)之间不是正交的,所以每次都必须做投影缩小残差,所以前向选择法最后只能给出一个局部近似解。(可以考虑下面的前向梯度法)
二、前向梯度法
前向梯度法类似于前向选择法,不同之处在于前向梯度法废除了前向选择法的投影逼近\(Y\),取而代之的是在每次最接近\(Y\)的向量\(X_i\)的方向上移动一小步,并且向量\(X_i\)移动会不会被剔除,而是继续从\(X_i \quad(i=1,2,i-1,i,i+1,\cdots,n)\)中选择一个最接近残差\(Y_{err}\)(注:残差计算方式类似于前向选择法)的向量\(X_i\),然后再走一小步,直至残差为0,停止算法,即可得到\(\omega\)。
2.1 举例
# 举例图例
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
%matplotlib inline
font = FontProperties(fname='/Library/Fonts/Heiti.ttc')
# X1
plt.annotate(xytext=(2, 5), xy=(3, 5), s='', color='r',
arrowprops=dict(arrowstyle="->", color='r'))
plt.text(2.4, 4.8, s='$\epsilon{X_1}$', color='g')
# eX1
plt.annotate(xytext=(2, 5), xy=(4, 5), s='', color='r',
arrowprops=dict(arrowstyle="->", color='r'))
plt.text(3.2, 4.8, s='$\epsilon{X_1}$', color='g')
# eX1
plt.annotate(xytext=(2, 5), xy=(5, 5), s='', color='r',
arrowprops=dict(arrowstyle="->", color='r'))
plt.text(4.2, 4.8, s='$\epsilon{X_1}$', color='g')
# eX1
plt.annotate(xytext=(2, 5), xy=(2.8, 5), s='', color='r',
arrowprops=dict(arrowstyle="->", color='k'))
plt.text(1.9, 4.8, s='$X_1$', color='g')
# eX1
plt.annotate(xytext=(6.1, 6.2), xy=(7, 6.2), s='', color='r',
arrowprops=dict(arrowstyle="->", color='r'))
plt.text(6.2, 6, s='$\epsilon{X_1}$', color='g')
# ex2
plt.annotate(xytext=(5, 5), xy=(6.2, 6.2), s='', color='r',
arrowprops=dict(arrowstyle="->", color='r'))
plt.text(5.2, 5.8, s='$\epsilon{X_2}$', color='g')
# X2
plt.annotate(xytext=(2, 5), xy=(3, 6), s='', color='r',
arrowprops=dict(arrowstyle="->", color='k'))
plt.text(2, 5.5, s='$X_2$', color='g')
# X2
plt.annotate(xytext=(5, 5), xy=(6, 6), s='', color='r',
arrowprops=dict(arrowstyle="->", color='k'))
plt.text(5.6, 5.5, s='$X_2$', color='g')
# Y
plt.annotate(xytext=(2, 5), xy=(8, 7), s='', color='r',
arrowprops=dict(arrowstyle="->", color='k'))
plt.text(5, 6.2, s='$Y$', color='g')
plt.annotate(xytext=(5, 5), xy=(8, 7), s='', color='r',
arrowprops=dict(arrowstyle="-", color='gray'))
plt.xlim(1, 9)
plt.ylim(4, 8)
plt.title('前向梯度法举例', fontproperties=font, fontsize=20)
plt.show()
![png](http://www.chenyoude.com/ml/A-05 前向选择法和前向梯度法_17_0.png?x-oss-process=style/watermark)
上图假设\(X\)为\(2\)维,首先可以看出,离\(Y\)最接近的是\(X_1\),因此沿着向量\(X_i\)的方向走上一段距离,此处的\(\epsilon\)是一个手动调整的超参数,走了一段距离后发现,离残差\(Y_{err}\)最近接的还是\(X_1\),因此继续接着走一段距离,直到走到离残差\(Y_{err}\)最近的为\(X_2\)的时候,沿着向量\(X_2\)的方向走上一段距离,发现此时残差\(Y_{err}\)离\(X_1\)更近,则沿着\(X_1\)走一段距离,直到走到最后残差为0,停止算法,即可得到\(\omega\)。
2.2 前向梯度法优缺点
2.2.1 优点
- 可以手动控制\(\epsilon\)的大小,即可以控制算法的精准度,如果\(\epsilon\)较小的时候算法精准度很高
2.2.2 缺点
- \(\epsilon\)小,算法精准度高,同时算法迭代次数增加;\(\epsilon\)大,算法精准度降低。类似于梯度下降,这是前向梯度法较大的一个问题。(参考最小角回归法)
A-05 前向选择法和前向梯度法的更多相关文章
- iOS之计算上次日期距离现在多久, 如 xx 小时前、xx 分钟前等
/** * 计算上次日期距离现在多久 * * @param lastTime 上次日期(需要和格式对应) * @param format1 上次日期格式 * @para ...
- 使用C#把发表的时间改为几年前,几个月,几天前,几小时前,几分钟前,或几秒前
我们在评论中往往会看到多少天前,多少小时前. 实现原理:现在时间-过去时间 得到的时间差来做比较 下面我定义了一个Helper类,大家直接引用即可,参数就是时间差,注意时间差类型是TimeSpan类型 ...
- php 显示某一个时间相当于当前时间在多少秒前,多少分钟前,多少小时前
/* *function:显示某一个时间相当于当前时间在多少秒前,多少分钟前,多少小时前 *timeInt:unix time时间戳 *format:时间显示格式 */ public function ...
- php计算几分钟前、几小时前、几天前的几个函数
函数方法: /*php计算几分钟前.几小时前.几天前的几个函数*/ function get_date($time){ $t=time()-$time; $f=array( '31536000'=&g ...
- js 实现几分钟前、几小时前、几天前,以及几分钟后、几小时后、几天前后
js 实现几分钟前.几小时前.几天前,以及几分钟后.几小时后.几天前后 /* * * 把传入的时间戳与当前时间比较,计算几分钟前.几小时前.几天前,以及几分钟后.几小时后.几天前后 * unixtim ...
- ****timeago.js插件:jquery实现几分钟前、几小时前、几天前等时间差显示效果的代码实例
前端 时间个性化 插件 jquery.timeago.js 关键词 : 时间格式化 刚刚 N分钟前 N小时前 N天前 N月前 N年前 MM-dd hh:mm 或者 yyyy-MM-dd 前端: & ...
- python 获取几小时之前,几分钟前,几天前,几个月前,及几年前的具体时间
引入以下两个包: import datetime import arrow 具体代码 # import datetime # import arrow def getTime(self, flag,d ...
- 使用C#把发表的时间改为几个月,几天前,几小时前,几分钟前,或几秒前
//使用C#把发表的时间改为几个月,几天前,几小时前,几分钟前,或几秒前 //2008年03月15日 星期六 02:35 public string DateStringFromNow(DateTim ...
- js把字符串格式的时间转换成几秒前、几分钟前、几小时前、几天前等格式
最近在做项目的时候,需要把后台返回的时间转换成几秒前.几分钟前.几小时前.几天前等的格式:后台返回的时间格式为:2015-07-30 09:36:10,需要根据当前的时间与返回的时间进行对比,最后显示 ...
随机推荐
- 为什么不建议使用Date,而是使用Java8新的时间和日期API?
Java 8:新的时间和日期API 在Java 8之前,所有关于时间和日期的API都存在各种使用方面的缺陷,因此建议使用新的时间和日期API,分别从旧的时间和日期的API的缺点以及解决方法.Java ...
- Django框架下的增强分页组件
本文通过文章同步功能推送至博客园,显示排版可能会有所错误,请见谅! 描述:Django框架内置了分页功能,但其只能满足简单需求,难以实现复杂功能. 实现代码: #!/usr/bin/env pytho ...
- Bootstrap4默认样式不对胃口?教你使用NPM+Webpack+SASS来定制
Bootstrap 是一个流行的前端样式库,可以方便快速的构建应用,但默认样式可能不尽人意,本文就介绍如何使用 NPM, Webpack, SASS 针对它的源码来定制自己的主题.版本使用的是 Boo ...
- 粗糙版ORM(附详细注释)
目录 ORM 其他 ORM代码 数据库表代码 mysql代码 db/models.py db/pymysql_opreator.py ORM 作为数据库表记录 和 python中对象的映射关系中间件 ...
- Mars视频笔记——Animation
Animations的使用(1) 什么是Animations 提供了一系列的动画效果,可以应用在绝大多数控件中 Animations的分类 1 Tweened Animations 渐变动画 提供了旋 ...
- 02:H.264学习笔记
H.264组成 1.网络提取层 (Network Abstraction Layer,NAL) 2.视讯编码层 (Video Coding Layer,VCL) a.H.264/AVC影像格式阶层架构 ...
- 解决Android数据库异步操作的大问题
前言 相信大家在开发过程中,也遇到过下面的这种异常: java.lang.IllegalStateException: attempt to re-open an already-closed obj ...
- 简单粗暴的关键两部实现连接远程云服务器数据库SqlServer 2012
要连上远程服务器的数据库,前面的那些数据库配置就不说了,网上都一样. 下面讲讲关键的两点,也是我尝试普通的方法无效后通过下面的方法成功连上的. 1.点开云服务器的安全组,看看里面的端口是否都放行了.我 ...
- App的功能测试要点
一 UI测试 (1)界面(菜单.窗口.按钮)布局.风格是否满足客户要求,文字和图片组合是否美观,操作是否友好. (2)清晰.简洁.美观.响应.一致 (3)图形测试.内容测试.导航测试 (图形包括 ...
- 基于Docker搭建大数据集群(二)基础组件配置
主要内容 jdk环境搭建 scala环境搭建 zookeeper部署 mysql部署 前提 docker容器之间能免密钥登录 yum源更换为阿里源 安装包 微云分享 | tar包目录下 JDK 1.8 ...