树模型-常见问题点
简介XGboost可以引出GBDT,引出bagging和boosting,引出随机森林
集成学习是指用某种策略将多个分类器预测的结果集成起来,作为最终的预测结果,有boost和bagging两种方法(boosting 各分类器之间有依赖关系,bagging各分类器之间没有依赖关系,可并行),boosting分为两种,一种是AdaBoost(自适应增强)(前一个分类器分错/分对的样本的权值会得到加强/降低,加权后的全体样本再次被用来训练下一个基本分类器),一种是GBDT,GBDT的每一次计算都为了减少上一次的残差,进而在负梯度的方向上建立一个新的模型,而XGB采用的就是GBDT的形式,XGB的本质上还是一个GBDT,但是在速度和效率都发挥到了极致。XGB是GBDT工程版本的优化实现
XGB和GBDT比较大的不同就是目标函数的定义,XGB使用泰勒展开来近似目标函数;
xgboost类似于gbdt的优化版,不论是精度还是效率上都有了提升。与gbdt相比,具体的优点有:
1.损失函数是用泰勒展式二项逼近,而不是像gbdt里的就是一阶导数
2.对树的结构进行了正则化约束,防止模型过度复杂,降低了过拟合的可能性
3.节点分裂的方式不同,gbdt是用的平方差,xgboost是经过优化推导后的
1、Xgboost :分布式并行训练,两个方面
树之间还是串行的,因为他是一个boosting模型
1)特征并行:并行计算特征的重要度,然后确定切分点,
2)样本分在不同的存储块上,多个block可以并行计算
问题:(1)不能从本质上减少计算量;(2)通讯代价高。
2、XGBoost在什么地方做的剪枝,怎么做的?
(1) 目标函数中,使用叶子的数目和l2模的平方,控制模型的复杂度
(2) 在分裂节点的计算增益中,定义了一个阈值,当增益大于阈值才分裂
XGBoost 先从顶到底建立树直到最大深度,再从底到顶反向检查是否有不满足分裂条件的结点,进行剪枝。
3. XGBoost为什么使用泰勒二阶展开?为什么用二阶信息不用一阶?
(1) 由于之前求最优解的过程只是对平方损失函数进行的,一阶残差,二阶常数,当损失函数是其它函数时,
展开就没有这种形式了,为了能够有个统一的形式,使用泰勒二阶展开。为了统一损失函数求导的形式以支持自定义损失函数
(2) 二阶信息本身能够让梯度收敛的更快更准确(优化算法中牛顿法证实)可以简单认为一阶导数引导梯度方向,二阶导数引导梯度方向如何变化
4、缺失值的处理:
遇到缺失值,会分别将缺失值分配到左节点和右节点两种情形,计算增益后悬着增益大的方向进行分裂。
如果训练期间没有缺失值,预测时候有,自动将缺失值划分到右子树。
5. xgboost对预测模型特征重要性排序的原理?
由节点负责加权和记录次数。一个属性对分裂点改进性能度量越大(越靠近根节点),权值越大。
被越多提升树所选择,属性越重要。最终将一个属性在所有提升树中的结果进行加权后求平均,得到重要性得分。
6. XGBoost如何寻找最优特征?是又放回还是无放回的呢?
XGB属于boosting集成学习方法,样本是不放回的,每轮计算样本不重复。另外,XGB支持子采样,每轮计算不使用全部样本,减少过拟合。
XGB支持列采样,提高计算速度又减少过拟合。
7. lightgbm和xgboost有什么区别?他们的loss一样么? 算法层面有什么区别?
1、 XGB采用level-wise的分裂策略,LGB采用leaf-wise的策略,XGB对每一层所有节点做无差别分裂,但是可能有些节点增益非常小,对结果影响不大,带来不必要的开销。Leaf-wise是在所有叶子节点中选取分裂收益最大的节点进行的,但是很容易出现过拟合问题,所以需要对最大深度做限制
2、 XGB使用近似算法,LGB使用基于立方图的决策算法,histogram算法在内存和计算代价上都有不小的优势。
1)内存上:直方图算法和xgboost的exact算法,大约1:8消耗,因为对特征分桶后只需保存特征离散化之后的值(1个字节),
而xgboost既要保存原始feature的值,也要保存这个值的顺序索引,这些值需要32位的浮点数来保存(8个字节)。
2)XGBoost无法直接输入类别型变量,因此需要事先对类别型变量进行编码(例如独热编码);LightGBM可以直接处理类别型变量。
特征并行:二者的区别就导致了LGB中worker间通信成本明显降低,只需通信一个特征分裂点即可,而XGB中要广播样本索引
8. 比较一下LR和GBDT?GBDT在什么情况下比逻辑回归算法要差?
1、 LR是线性模型,具有很好的解释性,很容易并行化,处理亿条训练数据不是问题,但是学习能力有限,需要大量的特征工程;
GBDT可以处理线性和非线性的数据,具有天然优势进行特征组合
2、 LR可以很好的利用正则化解决稀疏性问题(lr 等线性模型的正则项是对权重的惩罚,也就是 W1一旦过大,惩罚就会很大,进一步压缩 W1的值,使他不至于过大,而树模型则不一样,树模型的惩罚项通常为叶子节点数和深度等,而我们都知道,对于上面这种 case,树只需要一个节点就可以完美分割9990和10个样本,惩罚项极其之小)
9. RF和GBDT的区别;RF怎么解决的过拟合问题;
相同点:都是由多棵树组成,最终的结果都是由多棵树一起决定。
不同点:
组成随机森林的树可以分类树也可以是回归树,而GBDT只由回归树组成
组成随机森林的树可以并行生成,而GBDT是串行生成
随机森林的结果是多数表决表决的,而GBDT则是多棵树累加之和
随机森林对异常值不敏感,而GBDT对异常值比较敏感
随机森林是减少模型的方差,而GBDT是减少模型的偏差
随机森林不需要进行特征归一化,而GBDT则需要进行特征归一化
10. 怎么理解决策树、xgboost能处理缺失值?而有的模型(svm)对缺失值比较敏感?
决策树(随机森林)
(1)使用对应类别中位数(数值)和出现次数最多的数(描述型变量)代替
(2)也是中位数和出现次数最多的数进行替换,引入了权重(替换数据和其它数据的相似度计算)
第二种效果好,但是费时,所以一般工具包不提供补全功能,影响工具包效率
涉及到距离度量的模型,当缺失值处理不当会导致效果很差(KNN,SVM)
1111111数据量和模型选择
数据量很小,用朴素贝叶斯
数据量适中或者较大,用树模型,优先 xgboost
数据量较大,也可以用神经网络
避免使用距离度量相关的模型,如KNN和SVM
11. 随机森林是怎样避免ID3算法信息增益的缺点的?
首先说下信息增益的过程,决策树算法本质上就是要找出每一列的最佳划分以及不同列划分的先后顺序及排布。
信息增益的缺点是比较偏向选择取值多的属性。而gini系数每次都是二分,所以跟属性多少没有关系。
另外:CART为什么选择基尼系数作为特征选择标准 ?
基尼指数的意义是从数据集D中随机抽取两个样本类别标识不一致的概率。
基尼指数越小,数据集的纯度越高。相比于信息增益,信息增益比等作为特征选择方法,基尼指数省略了对数计算,运算量比较小,也比较容易理解。
12.gbdt对标量特征要不要onehot编码?
微软在lightGBM的文档里也说了,category特征可以直接输入,不需要one-hot编码,准确度差不多,速度快8倍。
而sklearn的tree方法在接口上不支持category输入,所以只能用one-hot编码。
13. GBDT 如何用于分类 ?
GBDT无论用于分类还是回归一直使用的CART回归树。使用softmax来产生概率:
每样本的标签是分类到所属的叶子节点所有值的平均值。
14、RF的随机性体现在哪里?特征重要程度的计算?
样本随机性和特征随机性
15. Bagging,Boosting二者之间的区别?
1)样本选取:
Bagging训练集有放回随机抽取,每个样本权重一样
Boosting根据分类器的结果,分类错误的权重高
2)预测函数:
Bagging 每个分类器权重相等
Boosting根据分类器的效果,分类效果好权重高
3)并行:
Bagging 分类器并行训练
Boosting串行训练
16. 为什么决策树之前用pca会好一点
决策树的本质在于选取特征,然后分支。 pca解除了特征之间的耦合性(共线性),
并且按照贡献度给特征拍了个序,这样更加方便决策树选取特征
17. 为什么随机森林的树比gbdt的要深一点?
随机森林是通过投票的方式来降低方差,但是本质上需要每棵树有较强的表达能力,所以单颗树深点没关系,通过投票的方式降低过拟合。
而GBDT是通过加强前一棵树的表达能力,所以每颗树不必有太强的表达能力。可以通过boosting的方式来提高,也能提高训练速度
(gbdt害怕过拟合,rf不怕,通过投票的方式杜绝)
原文:https://blog.csdn.net/jamexfx/article/details/93780308
GBDT 面试总结:博客中关于,gbdt 如何用于分类,讲解很详细
https://www.cnblogs.com/ModifyRong/p/7744987.html
SVM常见问题:
https://zhuanlan.zhihu.com/p/76946313
LR常见问题:
https://zhuanlan.zhihu.com/p/76563562
xgboost对比gbdt/boosting Tree有了哪些方向上的优化?
- 显示的把树模型复杂度作为正则项加到优化目标中
- 优化目标计算中用到二阶泰勒展开代替一阶,更加准确
- 实现了分裂点寻找近似算法
- 暴力枚举
- 近似算法(分桶)
- 更加高效和快速
- 数据事先排序并且以block形式存储,有利于并行计算
- 基于分布式通信框架rabit,可以运行在MPI和yarn上
- 实现做了面向体系结构的优化,针对cache和内存做了性能优化
xgboost和gbdt的区别?
- 模型优化上:
- 基模型的优化:
- gbdt用的是cart回归树作为基模型,xgboost还可以用线性模型,加上天生的正则项,就是带L1和L2逻辑回归(分类)和线性回归(回归)
- 损失函数上的优化:
- gbdt对loss是泰勒一阶展开,xgboost是泰勒二阶展开
- gbdt没有在loss中带入结点个数和预测值的正则项
- 特征选择上的优化:
- 实现了一种分裂节点寻找的近似算法,用于加速和减小内存消耗,而不是gbdt的暴力搜索
- 节点分裂算法解决了缺失值方向的问题,gbdt则是沿用了cart的方法进行加权
- 正则化的优化:
- 特征采样
- 样本采样
- 基模型的优化:
- 工程优化上:
- xgboost在对特征进行了分block预排序,使得在做特征分裂的时候,最终选增益最大的那个特征去做分裂,那么各个特征的增益计算就可以开多线程进行
- cache-aware, out-of-core computation
- 支持分布式计算可以运行在MPI,YARN上,得益于底层支持容错的分布式通信框架rabit
xgboost如何寻找分裂节点的候选集?
- 暴力枚举
- 法尝试所有特征和所有分裂位置,从而求得最优分裂点。当样本太大且特征为连续值时,这种暴力做法的计算量太大
- 近似算法(approx)
- 近似算法寻找最优分裂点时不会枚举所有的特征值,而是对特征值进行聚合统计,然后形成若干个桶。然后仅仅将桶边界上的特征的值作为分裂点的候选,从而获取计算性能的提升
- 离散值直接分桶
- 连续值分位数分桶
- 近似算法寻找最优分裂点时不会枚举所有的特征值,而是对特征值进行聚合统计,然后形成若干个桶。然后仅仅将桶边界上的特征的值作为分裂点的候选,从而获取计算性能的提升
xgboost特征重要性是如何得到的?
- ’weight‘:代表着某个特征被选作分裂结点的次数;
- ’gain‘:使用该特征作为分类结点的信息增益;
- ’cover‘:某特征作为划分结点,覆盖样本总数的平均值;
xgboost如何调参数?
- 先确定learningrate和estimator
- 再确定每棵树的基本信息,max_depth和 min_child_weight
- 再确定全局信息:比如最小分裂增益,子采样参数,正则参数
- 重新降低learningrate,得到最优解
https://github.com/Allen15rg/Reflection_Summary/blob/master/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/%E9%9B%86%E6%88%90%E5%AD%A6%E4%B9%A0/Xgboost.md
LGB处理类别特征:
1、one-hot编码弊端
one-hot编码是处理类别特征的一个通用方法,然而在树模型中,这可能并不一定是一个好的方法,尤其当类别特征中类别个数很多的情况下。主要的问题是:
①可能无法在这个类别特征上进行切分(即浪费了这个特征)。使用one-hot编码的话,意味着在每一个决策节点上只能使用one vs rest(例如是不是狗,是不是猫等)的切分方式。当类别值很多时,每个类别上的数据可能会比较少,这时候切分会产生不平衡,这意味着切分增益也会很小(比较直观的理解是,不平衡的切分和不切分没有区别)。
②会影响决策树的学习。因为就算可以在这个类别特征进行切分,也会把数据切分到很多零碎的小空间上,如图1左边所示。而决策树学习时利用的是统计信息,在这些数据量小的空间上,统计信息不准确,学习会变差。但如果使用如图1右边的分裂方式,数据会被切分到两个比较大的空间,进一步的学习也会更好。
2、LGBM处理分类特征
2.1 大致流程
为了解决one-hot编码处理类别特征的不足。LGBM采用了Many vs many的切分方式,实现了类别特征的最优切分。用Lightgbm可以直接输入类别特征,并产生如图1右边的效果。在1个k维的类别特征中寻找最优切分,朴素的枚举算法的复杂度是,而LGBM采用了如参考文献【1】的方法实现了的算法。
算法流程如图2所示:在枚举分割点之前,先把直方图按每个类别的均值进行排序;然后按照均值的结果依次枚举最优分割点。从图2可以看到,Sum(y)/Count(y)为类别的均值。当然,这个方法很容易过拟合,所以在LGBM中加入了很多对这个方法的约束和正则化。
2.2 详细流程
下面具体来讲下在代码中如何求解类别特征的最优切分的流程:
(feature_histogram.hpp文件中FindBestThresholdCategorical函数)
A. 离散特征建立直方图的过程:
统计该特征下每一种离散值出现的次数,并从高到低排序,并过滤掉出现次数较少的特征值, 然后为每一个特征值,建立一个bin容器, 对于在bin容器内出现次数较少的特征值直接过滤掉,不建立bin容器。
B. 计算分裂阈值的过程:
B.1
先看该特征下划分出的bin容器的个数,如果bin容器的数量小于4,直接使用one vs other方式, 逐个扫描每一个bin容器,找出最佳分裂点;
B.2
对于bin容器较多的情况, 先进行过滤,只让子集合较大的bin容器参加划分阈值计算, 对每一个符合条件的bin容器进行公式计算(公式如下: 该bin容器下所有样本的一阶梯度之和 / 该bin容器下所有样本的二阶梯度之和 + 正则项(参数cat_smooth),这里为什么不是label的均值呢?其实上例中只是为了便于理解,只针对了学习一棵树且是回归问题的情况, 这时候一阶导数是Y, 二阶导数是1),得到一个值,根据该值对bin容器从小到大进行排序,然后分从左到右、从右到左进行搜索,得到最优分裂阈值。但是有一点,没有搜索所有的bin容器,而是设定了一个搜索bin容器数量的上限值,程序中设定是32,即参数max_num_cat。
LightGBM中对离散特征实行的是many vs many 策略,这32个bin中最优划分的阈值的左边或者右边所有的bin容器就是一个many集合,而其他的bin容器就是另一个many集合。
B.3
对于连续特征,划分阈值只有一个,对于离散值可能会有多个划分阈值,每一个划分阈值对应着一个bin容器编号,当使用离散特征进行分裂时,只要数据样本对应的bin容器编号在这些阈值对应的bin集合之中,这条数据就加入分裂后的左子树,否则加入分裂后的右子树。
https://blog.csdn.net/anshuai_aw1/article/details/83275299