LambdaMART简介——基于Ranklib源码(二 Regression Tree训练)
上一节中介绍了 $ \lambda $ 的计算,lambdaMART就以计算的每个doc的 $\lambda$ 值作为label,训练Regression Tree,并在最后对叶子节点上的样本 $lambda$ 均值还原成 $\gamma$ ,乘以learningRate加到此前的Regression Trees上,更新score,重新对query下的doc按score排序,再次计算deltaNDCG以及 $\lambda$ ,如此迭代下去直至树的数目达到参数设定或者在validation集上不再持续变好(一般实践来说不在模型训练时设置validation集合,因为validation集合一般比训练集合小很多,很容易收敛,达不到效果,不如训练时一步到位,然后另起test集合做结果评估)。
其实Regression Tree的训练很简单,最主要的就是决定如何分裂节点。lambdaMART采用最朴素的最小二乘法,也就是最小化平方误差和来分裂节点:即对于某个选定的feature,选定一个值val,所有<=val的样本分到左子节点,>val的分到右子节点。然后分别对左右两个节点计算平方误差和,并加在一起作为这次分裂的代价。遍历所有feature以及所有可能的分裂点val(每个feature按值排序,每个不同的值都是可能的分裂点),在这些分裂中找到代价最小的。
举个栗子,假设样本只有上一节中计算出 $\lambda$ 的那10个:
qId=1830 features and lambdas
qId=1830 1:0.003 2:0.000 3:0.000 4:0.000 5:0.003 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(1):-0.495
qId=1830 1:0.026 2:0.125 3:0.000 4:0.000 5:0.027 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(2):-0.206
qId=1830 1:0.001 2:0.000 3:0.000 4:0.000 5:0.001 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(3):-0.104
qId=1830 1:0.189 2:0.375 3:0.333 4:1.000 5:0.196 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(4):0.231
qId=1830 1:0.078 2:0.500 3:0.667 4:0.000 5:0.086 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(5):0.231
qId=1830 1:0.075 2:0.125 3:0.333 4:0.000 5:0.078 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(6):-0.033
qId=1830 1:0.079 2:0.250 3:0.667 4:0.000 5:0.085 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(7):0.240
qId=1830 1:0.148 2:0.000 3:0.000 4:0.000 5:0.148 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(8):0.247
qId=1830 1:0.059 2:0.000 3:0.000 4:0.000 5:0.059 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(9):-0.051
qId=1830 1:0.071 2:0.125 3:0.333 4:0.000 5:0.074 6:0.000 7:0.000 8:0.000 9:0.000 10:0.000 lambda(10):-0.061
上表中除了第一列是qId,最后一列是lambda外,其余都是feature,比如我们选择feature(1)的0.059做分裂点,则左子节点<=0.059的doc有: 1, 2, 3, 9;而>0.059的被安排到右子节点,doc有4, 5, 6, 7, 8, 10。由此左右两个子节点的lambda均值分别为:
$ \bar{\lambda_L}=\frac{\lambda_1+\lambda_2+\lambda_3+\lambda_9}{4}=\frac{-0.495-0.206-0.104-0.051}{4}=-0.214$
$\bar{\lambda_R}=\frac{\lambda_4+\lambda_5+\lambda_6+\lambda_7+\lambda_8+\lambda_{10}}{6}=\frac{0.231+0.231-0.033+0.240+0.247-0.061}{6}=0.143$
继续计算左右子节点的平方误差和:
$s_{L}=\sum_{i\in L}{(\lambda_i-\bar{\lambda_L})^2}=(-0.495+0.214)^2+(-0.206+0.214)^2+(-0.104+0.214)^2+(-0.051+0.214)^2=0.118$
$s_{R}=\sum_{i\in R}{(\lambda_i-\bar{\lambda_R})^2}=(0.231-0.143)^2+(0.231-0.143)^2+(-0.033-0.143)^2+(0.240-0.143)^2+(0.247-0.143)^2+(0.016-0.143)^2=0.083$
因此将feature(1)的0.059的均方差(分裂代价)是:
$Cost_{0.059@feature(1)}=s_{L}+s_{R}=0.118+0.083=0.201$
我们可以像上面那样遍历所有feature的不同值,尝试分裂,计算Cost,最终选择所有可能分裂中最小Cost的那一个作为分裂点。然后将 $s_{L}$ 和 $s_{R}$ 分别作为左右子节点的属性存储起来,并把分裂的样本也分别存储到左右子节点中,然后维护一个队列,始终按平方误差和 s 降序插入新分裂出的节点,每次从该队列头部拿出一个节点(并基于这个节点上的样本)进行分裂(即最大均方差优先分裂),直到树的分裂次数达到参数设定(训练时传入的leaf值,叶子节点的个数与分裂次数等价)。这样我们就训练出了一棵Regression Tree。
上面讲述了一棵树的标准分裂过程,需要多提一点的是,树的分裂还有一个参数设定:叶子节点上的最少样本数,比如我们设定为3,则在feature(1)处,0.001和0.003两个值都不能作为分裂点,因为用它们做分裂点,左子树的样本数分别是1和2,均<3。叶子节点的最少样本数越小,模型则拟合得越好,当然也容易过拟合(over-fitting);反之如果设置得越大,模型则可能欠拟合(under-fitting),实践中可以使用cross validation的办法来寻找最佳的参数设定。
LambdaMART简介——基于Ranklib源码(二 Regression Tree训练)的更多相关文章
- LambdaMART简介——基于Ranklib源码(一 lambda计算)
学习Machine Learning,阅读文献,看各种数学公式的推导,其实是一件很枯燥的事情.有的时候即使理解了数学推导过程,也仍然会一知半解,离自己写程序实现,似乎还有一道鸿沟.所幸的是,现在很多主 ...
- Java_io体系之PipedWriter、PipedReader简介、走进源码及示例——14
Java_io体系之PipedWriter.PipedReader简介.走进源码及示例——14 ——管道字符输出流.必须建立在管道输入流之上.所以先介绍管道字符输出流.可以先看示例或者总结.总结写的有 ...
- Java_io体系之BufferedWriter、BufferedReader简介、走进源码及示例——16
Java_io体系之BufferedWriter.BufferedReader简介.走进源码及示例——16 一:BufferedWriter 1.类功能简介: BufferedWriter.缓存字符输 ...
- Java_io体系之RandomAccessFile简介、走进源码及示例——20
Java_io体系之RandomAccessFile简介.走进源码及示例——20 RandomAccessFile 1. 类功能简介: 文件随机访问流.关心几个特点: 1.他实现的接口不再 ...
- AQS源码二探-JUC系列
本文已在公众号上发布,感谢关注,期待和你交流. AQS源码二探-JUC系列 共享模式 doAcquireShared 这个方法是共享模式下获取资源失败,执行入队和等待操作,等待的线程在被唤醒后也在这个 ...
- Unity UGUI图文混排源码(二)
Unity UGUI图文混排源码(一):http://blog.csdn.net/qq992817263/article/details/51112304 Unity UGUI图文混排源码(二):ht ...
- JMeter 源码二次开发函数示例
JMeter 源码二次开发函数示例 一.JMeter 5.0 版本 实际测试中,依靠jmeter自带的函数已经无法满足我们需求,这个时候就需要二次开发.本次导入的是jmeter 5.0的源码进行实际的 ...
- Alink漫谈(十七) :Word2Vec源码分析 之 迭代训练
Alink漫谈(十七) :Word2Vec源码分析 之 迭代训练 目录 Alink漫谈(十七) :Word2Vec源码分析 之 迭代训练 0x00 摘要 0x01 前文回顾 1.1 上文总体流程图 1 ...
- [源码分析] Facebook如何训练超大模型---(1)
[源码分析] Facebook如何训练超大模型---(1) 目录 [源码分析] Facebook如何训练超大模型---(1) 0x00 摘要 0x01 简介 1.1 FAIR & FSDP 1 ...
随机推荐
- Grid Search学习
转自:https://www.cnblogs.com/ysugyl/p/8711205.html Grid Search:一种调参手段:穷举搜索:在所有候选的参数选择中,通过循环遍历,尝试每一种可能性 ...
- Django中间件的5种自定义方法
阅读目录(Content) Django中间件 自定义中间件 中间件(类)中5种方法 中间件应用场景 回到顶部(go to top) Django中间件 在http请求 到达视图函数之前 和视图函 ...
- C语言中exit函数的使用
exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束 return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一 ...
- 20155239 2016-2017-2 《Java程序设计》第7周学习总结
教材学习内容总结 1.了解Lambda语言 "Lambda 表达式"(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的 ...
- MySQL connector c++使用笔记
MySQL的connector官方地址: http://dev.mysql.com/downloads/connector/ 针对c++来说, 可以选择c或者c++的库. c++的实现是参考了java ...
- JSDoc 注释规范
命令名描述 @param @argument 指定参数名和说明来描述一个函数参数@returns 描述函数的返回值@author 指示代码的作者@deprecated 指示一个函数已经废弃,而且在将来 ...
- 按月、按日进行数据统计的Mysql语句
<select id="getCustomerTJByUser" parameterType="map" resultType="map&quo ...
- PowerDesigner教程系列
文章转载至:http://www.cnblogs.com/yxonline/archive/2007/04/09/705479.html PowerDesigner教程系列(一)概念数据模型 目标:本 ...
- Linux 笔记 #04# Installing Tomcat 8 on Debian
失败一 ※ 失败二 ※ 失败三 ※ 完 1- 确认机型: root@iZwz:~# lsb_release -a LSB Version: core-2.0-amd64:core-2.0-noarc ...
- MySQL中的索引的引用
博文首先说明索引的分类及创建,然后会涉及到索引的可用性选择以及索引的优化. 索引是什么?先说创建索引的目的,创建索引是为提高对数据的查询速度.在字典的目录中,我们可以很快找到某个字的位置,索引的作用就 ...