引言

集成学习, 在机器学习中是一个非常重要的思想: 把多个弱分类器精巧地组合在一起,成为一个很强大的学习器. 集成学习也因此一直处在风口浪边. 集成学习主要分为bagging 及boosting, 二者分别(主要)解决偏倚-方差分解中的方差与偏倚. 目前, 一般会认为boosting的效果会更好一些,故在这方面研究的就会多一些, 而陈天奇绝对是这一众人等的明星, 他携屠龙宝刀Xgboost 杀出重围, 莫敢争锋. xgboost在各大机器学习相关的竞赛中,文治武功,望尘莫及, 大有一统江湖之势… 这么'犀利'的一把利器, 如果不了解它, 是不是都不好意思自己是做机器学习, 人工智能的?

Xgboost 是boosting 学习方法的一种. 是对gbdt的改进升级. Xgboost 效果明显好于之前的boosting算法, 而且速度快, 更'可气的'是其竟支持并行计算, 这对工业界来说可是一个不小的福音. 这些优势成就了它今天的美名.

Xgboost

在介绍之前,先'初始化'一些'参数': 数据集 \(D = \{(x_i,y_i) | x_i\in R^m, \ \ y_i \in R \ \ i = 1,2,…,n\}\).

机器学习的目的是找到一个映射 f(x) 使得:
\[
L(y,\hat{y}) = L(y,f(x)) = \sum_{i = 1}^N L(y_i, f(x_i))
\]
最小化, 其中 \(\hat{y}\) 是经过模型得到的对 y 的估计, L 代表损失函数(Loss Function).

Boosting 解决上式的方法是采用前向分步算法, f(x) 是在训练过程中, 一步一步逐渐(组合)得到的:
\[
f(x) = w_0 + \sum_{k= 1}^K w_k b_k(x) = \sum_{k=1}^K t_k(x)
\]
其中, b(x) 是基学习器, w 是学习器的权重($w_0 $ 为偏置, 常取0,为简便,后面忽略, 因其为常数,对优化方式完全没有影响). 另, 再强调下:

\[f_k(x) = \sum_{j=1}^kw_jb_j(x)) = \sum_{j = 1}^k t_j(x)\]

有时 t(x) 也会乘上一个衰减因子(shrinkage), 通常为0.1, 这个衰减因子可过拟合(因如果过早到达最优附近, 很可能越过最优点, 导致表现下降).

(Ps: 请注意, 本文的符号表示,与xgboost的论文符号表示不尽相同, 原因是原论文的符号与我之前的boosting符号有冲突, 为了统一,只好修改了. 如果理解原理了, 用什么符号都无所谓了,对吧~ =^_^=)

在Xgboost中, 这里出现了第一次改进, 其思想也很自然, 即加上了正则项, 防止过拟合.
\[
f(x) = \sum_{k = 1}^K t_k(x ) + \sum_{k = 1}^K \Omega_k(t_k(x))
\]
其中 \(\Omega_k(t_k(x))\) 是第 k 步中的 \(t_k(x)\) 的正则项. 因这里的基学习器(通常)为CART, 故这里的 正则项可理解为对树的复杂度的惩罚, 树的复杂度可以用树的叶结点的个数及各个叶结点的权重表示, 陈给出下了面的一种形式:
\[
\Omega(t_k) = r T + \frac{1}{2} \lambda \sum_{ j= 1}^T c^2_j
\]
其中 T 为第 k 棵树的叶点结点个数, \(c_j\) 为此树上第 j 个叶结点上的权重(或称为 第 j 个叶结点的输出值). 这只是其中一种正则形式, 只要合理,完全可以用其他的代替.

这个改进确实很自然, 现在的机器学习的目标函数基本上都可以抽象为损失,正则项的组合:
\[
Object = Loss + Regulation
\]
在前向分步算法中, 第 k 步 的优化目标函数可表示为:
\[
\begin{array}\\
Object_k(\Theta) &=& L(y, f_k)+ \Omega(f_k) \\
&=& \sum_{i = 1}^N l(y_i,f_k(x_i)) + \Omega(f_k)\\
&=& \sum_{i=1}^Nl(y_i,f_{k-1}(x_i)+t_k(x_i)) + \sum_{j=1}^k\Omega(t_j)\\
&=& \sum_{i=1}^Nl(y_i,f_{k-1}(x_i)+t_k(x_i)) + \Omega(t_j) + constant\\
\end{array}
\]
其中 constant 表示常数(后面为简洁优化会忽略, 因常数对优化无影响).

接下来, xgboost在这里进一步改进, 传统的gradient boosting算法, 从名字就可以知道是应用的梯度(或一阶导数)优化的, 而xgboost 则用 牛顿法 来进行优化,即应用二阶导数优化:
\[
\begin{array}\\
Object_k(\Theta) &=& \sum_{i=1}^Nl(y_i,f_{k-1}(x_i)+t_k(x_i)) + \Omega(t_j) \\
& = & \sum_{i = 1}^N \left(l(y_i,f_{k-1}(x_i)) + g_{k,i} \cdot t_k(x_i) + \frac{1}{2}h_{k,i}\cdot t^2_k(x_i)\right) + \Omega(t_j) \\
\end{array}
\]
其中:
\[
\begin{array}\\
g_{k,i} = \frac{\partial l(y_i, f_{k-1}(x_i))}{\partial f_{k-1}(x_i)}\\
h_{k,i} = \frac{\partial^2 l(y_i, f_{k-1}(x_i))}{\partial f_{k-1}(x_i)^2}\\
\end{array}
\]
即一阶偏导与二阶偏导. 这里的展开,其实用到的就是泰勒公式的二阶展开:
\[
f(x) = f(x_0) + f'(x_0)(x-x_0) + \frac{1}{2}f''(x_0)(x-x_0)^2+ o((x-x_0)^2)
\]
其中 \(x_0\) 相当于面的\(f_{k-1}\), \(\Delta x = x-x_0\) 相当于 \(t_k(x)\).

忽略掉常数项, 并把正则项展开得:
\[
\begin{array}\\
Object_k(\Theta) & = & \sum_{i = 1}^N \left( g_{k,i} \cdot t_k(x_i) + \frac{1}{2}h_{k,i}\cdot t^2_k(x_i)\right) + rT_k+\frac{1}{2}\lambda\sum_{j=1}^T c^2_{k,j}\\
\end{array}
\]
\(t_k(x)\) 是 CART, 则 可表示为:
\[
t_k(x) = \sum_{j = 1}^T c_{k,j} \cdot I_{x \in R_j}
\]
其中, \(R_j\) 是 第 k 棵 CART 的 第 j 个节点, \(c_{k,j}\) 为此叶结点的输出值.

于是:
\[
\begin{array}\\
Object_k(\Theta) & = & \sum_{j = 1}^T \left[(\sum_{x\in R_j}g_{k,i})\cdot c_{k,j} +\frac{1}{2} (\sum_{x\in R_j} h_{k,j} + \lambda)\cdot c^2_{k,j}\right] + r T_k\\
\end{array}
\]
对\(c_{k,j}\) 求偏导:
\[
c_{k,j} = \frac{\sum_{x\in R_j}g_{k,i}}{\sum_{x\in R_j} h_{k,j} + \lambda} = \frac{G_{k,j}}{H_{k,j}+\lambda}
\]
这个公式揭示了最佳树结构的条件, 再代入目标函数:
\[
Obj = -\frac{1}{2}\sum_{j =1}^T \frac{G_{k,j}^2}{H_{k,j}+\lambda} + rT
\]
以上两式是Xgboost 最重要的公式! (因这两个公式不但是boosting 的generallized additive 的优化目标,而且也是每棵树获得的最优目标(gain)的关键.)

然而, 就算这样, 满足最优结构的树也可能有无数棵, 为此, 第 k 棵 CART 的获取采用贪心算法, 贪心的标准即是寻找最大分离增益(splitting Gain):
\[
Gain = \frac{1}{2}\left[ \frac{G_{L}^2}{H_{L}+\lambda}+ \frac{G_{R}^2}{H_{R}+\lambda} - \frac{G^2}{H+\lambda} \right] - r
\]
其中 L, R 分点表示分离之后的左右两叶结点, 无下标的 G,H 则属于未分离时结点的相关参数.

参考文献

  1. BoostedTree(slides), 2014, Tianqi Chen.
  2. XgBoost: A scalable Tree Boosting System

Xgboost: 一把屠龙刀的自我修养的更多相关文章

  1. IT技术管理者的自我修养

    1. 前言 本来写<IT技术管理者的自我修养>与<IT技术人员的自我修养>是一开始就有的想法.但发表<IT技术人员的自我修养>后,收到了不少良好的反馈,博客园的编辑 ...

  2. 《web全栈工程师的自我修养》读书笔记

    有幸读了yuguo<web全栈工程师的自我修养>,颇有收获,故在此对读到的内容加以整理,方便指导,同时再回顾一遍书中的内容. 概览 整本书叙述的是作者的成长经历,通过经验的分享,给新人或者 ...

  3. 程序员的自我修养(2)——计算机网络(转) good

    相关文章:程序员的自我修养——操作系统篇 几乎所有的计算机程序,都会牵涉到网络通信.因此,了解计算机基础网络知识,对每一个程序员来说都是异常重要的. 本文在介绍一些基础网络知识的同时,给出了一些高质量 ...

  4. GIS制图人员的自我修养(2)--制图意识

    GIS制图人员的自我修养(2)--制图意识 by 李远祥 上次提及到GIS制图人员的一些制图误区,主要是为GIS制图人员剖析在制图工作中的一些问题.但如何提高制图的自我修养,却是一个非常漫长的过程,这 ...

  5. GIS制图人员的自我修养(1)--制图误区

    GIS制图人员的自我修养 by 李远祥 最近一直坚持写GIS制图的技术专题,并不是为了要介绍有什么好的技术和方法去制图,而是要告诉所有从事这一方向的人员一个铁铮铮的实现--要做好GIS制图,必须加强自 ...

  6. web性能优化 来自《web全栈工程师的自我修养》

    最近在看<web全栈工程师的自我修养>一书,作者是来自腾讯的前端工程师.作者在做招聘前端的时候问应聘者web新能优化有什么了解和经验,应聘者思索后回答“在发布项目之前压缩css和 Java ...

  7. gcc ld 链接器相关知识,调试指令(程序员的自我修养----链接、装载与库)

    最近解决一个动态链接上的问题,因为以前从来没有接触过这方面的知识,所以恶补了一下,首先要了解gcc编译指令(makefile),ld链接器的选项(还有连接脚本section指定内存位置),熟悉查看连接 ...

  8. Python学习笔记(四十九)爬虫的自我修养(一)

    论一只爬虫的自我修养 URL的一般格式(带括号[]的为可选项): protocol://hostname[:port]/path/[;parameters][?query]#fragment URL由 ...

  9. Hacker的社交礼仪与自我修养【转】

    Hacker School是位于纽约的一所特殊的编程“学校”,他们的目标是帮助参与者变成“更好的程序员”,之所以说他们特殊是因为这所“学校”没有老师,没有考试,也不会颁发证书,他们信奉三人行必有我师, ...

随机推荐

  1. 执行git add .命令时报warning: LF will be replaced by CRLF in yarn.lock.

    解决办法是执行:git config --global core.autocrlf false 是符号 / 转义的问题

  2. iDigital2019数字营销广告主峰会

    iDigital 数字营销品牌广告主峰会是定向邀请形式的闭门社交峰会, 现已成长为享誉亚洲的营销广告行业活动, 致力于帮助品牌营销官, 决策者和业界同行在日益整合的数字商业时代下获得战略远景.组委会邀 ...

  3. ubuntu 安装完后对于开发需要做的事情

    是从 https://www.osboxes.org/ubuntu/ 下载的vdi文件,估计vmware对应的应该也有. 1. 安装 openssh-server apt-get install op ...

  4. linux下视频转gif

    title: linux下视频转gif date: 2017-11-23 16:55:26 tags: linux categories: linux 安装ffmpeg ffmpeg是一套非常强大的音 ...

  5. ECMAScript6 入门教程 初学记录let命令 块级作用域

    一.基本语法-let命令 (1)ES6新增了let命令,用来声明变量.所声明的变量,只在let命令所在的代码块内有效. 循环的计数器,就很合适使用let命令.计数器i只在for循环体内有效,在循环体外 ...

  6. solr简单搜索案例

    solr简单搜索案例 使用Solr实现电商网站中商品信息搜索功能,可以根据关键字搜索商品信息,根据商品分类.价格过滤搜索结果,也可以根据价格进行排序,实现分页. 架构分为: 1. solr服务器 2. ...

  7. proc:基本数据库操作

    导师布置了一作业: 主要目的是学习数据库最基本的操作:创建用户.创建库表,和用程序访问数据库的相关技能(编码.编译等) 1,交易流水表(包含但不限于以下字段):交易日期.交易流水(用sequence实 ...

  8. vue组件传值

    组件的传值(组件之间的通讯) 1.父子通信 1)父传子 传递:当子组件在父组件中当做标签使用的时候,通过给子组件绑定一个自定义属性,值为需要传递的数据 接收:在子组件内部通过props进行接收 接收的 ...

  9. K8S学习笔记之ETCD启动失败注意事项

    最近搭建K8S集群遇到ETCD的报错,报错信息如下,一定要关闭防火墙.iptables和SELINUX,三个都要关闭!! Mar 26 20:39:24 k8s-m1 etcd[6437]: heal ...

  10. Objective-C不能以new开头命名属性

    ARC是在Xcode4.2推出的方便内存管理的一个特性,支持OS10.6及iOS4以后版本.引入ARC之后,相对应的内存管理使用方面做了必要的调整,这里不一一赘述:其中有一项就是文章题目说的,为了与手 ...