机器学习:集成算法 - xgboost

xgboost(eXtreme Gradient Boosting)
  • 大规模并行 boosting tree 的工具,据说是现在最好用的 boosting 算法,针对传统 GBDT 算法做了很多改进

xgboost 和传统 GBDT 的区别
  • GBDT 基学习器只用 CART 树,而 xgboost 除了用 CART 树,还可以用其他分类器
  • 优化目标函数里,用到了二阶导数信息,能够更快地收敛,而普通的 GBDT 只用到一阶
  • 优化目标函数里,对衡量模型复杂度的正则项进行了改进,GBDT 只对叶子个数做惩罚,而 xgboost 对叶子个数做惩罚的同时,还对叶子节点的权值做惩罚,有效地避免了过拟合
  • 利用优化目标函数的推导作为树的分裂准则
  • 在分割节点、寻找最佳分割点的时候,可以引入并行计算
  • 利用了特征的稀疏性
  • 能处理特征缺失
  • 支持列采样

输出函数

设有样本数据
j 棵树记为
则由 m 棵树组成的 xgboost 输出为
  
看起来就和 GBDT 一样,但 xgboost 的优化函数不一样

优化目标函数

xgboost 的优化目标函数为
  
  
  其中 是所有树的叶子节点的总数, 是每个叶子节点的系数

泰勒展开公式
  
  
  其中 是泰勒公式的余项,是 的高阶无穷小

将优化目标函数按泰勒公式展开,并取前三项目得到近似值
  
    
    
      

将一阶导数记为 将二阶导数记为 改写为
  

由于在计算第 m 棵树的时候,前 m-1 棵树已经确定,所以可以只保留和第 m 棵树有关的项,将优化目标改写为
  

设 的每个叶子节点是输出一个固定的值
设 代表所有会被映射到叶子节点 的 集合
设 代表 的叶子节点数

进一步改写为
  
    

设有
  
  

可改写为
  

对 求导并另导数为 0
  

得到最优的

  

  

用于衡量树的优劣的就是 ,其值越小,树结构越好

分裂叶子节点的依据

假设现在有一个叶子节点,属于这个叶子节点的样本的一阶导数的和为 ,二阶导数的和为 ,如果需要对这个叶子节点分裂成两个节点,那么叶子节点数量就 +1,假设分到左叶子的样本的值为 和 ,分到右叶子的样本的值为 和 ,则有 以及 ,那么 减小的值为

  

     

选择使得 值最大的分割特征和分割点
  
并计算分割后新的叶子节点的系数
  
  
  
  
  
停止分割的条件
  ○ 如果最大的 比 还小
  ○ 树已经达到了最大深度
  ○ 样本权重和小于某一个阈值

寻找最佳分裂点
  • 精确算法 - 穷举法
      遍历所有特征的所有特征值,该方法精度高但计算量大
  • 近似算法 - 分位点分割
      每个特征按照样本特征值的百分比选择候选分裂点
      近似法又有两种
      (1) 全局法:生成树之前就确定候选分裂点,这可以减少计算,但要一次取比较多的点
      (2) 局部法:每个节点确定候选分裂点,每次取的点较少,且可不断改善,但计算量大
  • 近似算法 - 二阶导数的分位点分割
      同样是按百分比选择候选分裂点,但不是直接用特征值,而是用二阶导数

提高计算速度
  • 提前计算和排序
     生成树的过程是串行的,在生成第 m 棵树时,第 m-1 棵树已经有了
     这样每个样本的一阶和二阶导数是已知的,可提前计算所有样本的 和 值,并提前排序
     如果是近似算法,还可以提前将各个分位点之间的 和 值进行累加得到 和 值
  • 并行分裂节点
     每个节点的分裂都是独立互不影响的,所以可以并行计算
     每个节点的分裂要遍历所有特征,特征计算也可以并行处理
  • 存储优化
     采用 Block 结构以稀疏矩阵 CSC 存储特征数据并排序,后续的并行计算可以重复使用 Block
     Block 按列存储,方便计算
     Block 的特征需要指向对应样本的导数值,会导致非连续内存访问,使用缓存预取来避免
     不同的 Block 可以存在不同的机器上,该方法对局部近似法尤其有效
     当数据太大无法全写入内存时,需要将 Block 压缩落盘,然后有独立的线程做读取解压

特征评价

xgboost 有三个指标用于对特征进行评价

  • weight - 某个特征被用于分裂的次数
  • gain - 某个特征被用于分裂时得到的平均增益
  • cover - 某个特征在分裂时结点处的平均二阶导数

学习率(Shrinkage)

和 GBDT 一样,xgboost 也使用了学习率做 Shrinkage,在计算出了节点的 值后,会乘以一个小于 1 的系数,这能够防止过拟合

列采样

xgboost 支持列抽样,能避免过拟合,同时能减少计算

稀疏数据

xgboost 能学习缺失值的分裂方向,在分裂的过程中,会尝试把所有特征缺失的样本都分入左节点,或是都分入右节点,看是哪边增益大,然后决定其分裂方向



你可能感兴趣的:(机器学习:集成算法 - xgboost)