GBDT
GBDT= gradient boosting + decision tree + shrinkage
GBDT是指基学习器为决策树的gradient boosting。以下是gradient boosting的代码,参见wiki。
1. 首先初始化,探索
2. For m = 1 to M:
(1) 计算残差
(2) 使用
(3) 经过上一步计算,
(4)更新模型。
3. 输出
gradient boosting中的残差学习器
其中
注:
1.
2. regularization(正则化)。一个重要的参数就是gradient boosting循环次数M,也就是树的个数。M太大可能导致过拟合。通常通过验证集来选择M的大小。
3. shrinkage(缩减)。在更新的时候添加一个学习率
通常使用较小的学习率(
4. GBDT是回归树,适用于回归和分类。对于分类问题,损失函数
5. 优点:可以灵活地处理离散值和连续值,泛化能力强,对异常值鲁棒性强;非线性变换比较多,表达能力强,而且不需要做复杂的特征工程和特征变换。
6. 缺点:由于弱学习器之间存在依赖关系,难以并行训练数据。计算复杂度高,不太适合高维洗漱特征。
Xgboost
xgboost地址:https://github.com/dmlc/xgboost
xgboost全称:extreme gradient boost
目标函数包括两部分:
(1) 训练误差
(2) 正则化
假设有K棵树:
目标函数为:
怎么优化目标函数呢?由于此时f是树,而非向量,因此不能使用SGD之类的方法来找合适的f。选用gradient boosting方法。
在回合t的预测值是
由泰勒公式
其中
将常量移去,得到:
我们通过叶子节点的分数值和叶子索引函数(映射一个instance到叶子节点)向量定义树:
其中
定义复杂度(以下不是唯一的定义):
定义
令
将
当我们可以判断树好坏时,理想情况下,我们枚举所有可能的树,然后选择最优。但这是不可能的,因此我们尽量最优化一棵树。当我们试图将一个叶节点分为两个叶节点时,它获得的分数值是:
也就是左边新节点的分数、右边新节点的分数、原始节点的分数、新的节点的正则化。这个分数值可以决定是否切分该节点。扫描排序过的所有特征实例的分数,寻找最优切分点。
最后总结以下Xgboost的算法:
- 每个迭代(each iteration)添加一棵树
- 每个迭代的开始阶段,计算
gi=∂y^(t−1)l(yi,y^(t−1)) ,hi=∂2y^(t−1)l(yi,y^(t−1)) - 用贪心算法寻找切分点,生产一棵树
ft(x) ,目标函数为:
Obj=−12∑Tj=1G2jHj+λ+γT - 将
ft(x) 添加到模型y^(t)i=y^(t−1)i+ft(xi) 。通常我们会添加一个ϵ ,称为缩减量(shrinkage)或者步长(step_size),通常设为0.1。
y^(t)i=y^(t−1)i+ϵft(xi)
这意味着在每个回合我们并不完全最优化,而是为后面的回合保留机会,这可以避免过拟合。
Xgboost的优点:对输入的尺度不敏感,不用标准化特征;能够学习到特征之间的高度联系;可扩展性,可用于工业。和GBDT相比,除了用tree,还可以使用线性分类器,用到了二阶导数信息,而普通的GBDT只用到一阶,支持并行。
参考:
GBDT维基百科:
https://en.wikipedia.org/wiki/Gradient_boosting#cite_note-6
GBDT:http://www.cnblogs.com/pinard/p/6140514.html
GBDT调参:http://www.cnblogs.com/DjangoBlog/p/6201663.html
xgboost:http://blog.csdn.net/sb19931201/article/details/52557382
xgboost tutorial:http://xgboost.readthedocs.io/en/latest/model.html