一、XgBoost算法
1.XgBoost简介
xgboost的核心算法思想:
- 不断地添加树,不断地进行特征分裂来生长一棵树,每次添加一个树,其实是学习一个新函数,去拟合上次预测的残差;
- 当我们训练完成得到k棵树,我们要预测一个样本的分数,其实就是根据这个样本的特征,在每棵树中会落到对应的一个叶子节点,每个叶子节点就对应一个分数;
- 最后只需要将每棵树对应的分数加起来就是该样本的预测值。
xgboost的优势:
优化的分布式梯度增强库,旨在实现高效,灵活和便携。
2.XgBoost定义
事实上,如果不考虑工程实现、解决问题上的一些差异,xgboost与gbdt比较大的不同就是目标函数的定义。xgboost的目标函数如下图所示:
- 目标函数第一部分(红色箭头)为损失函数;
- 目标函数第二部分(红色方框)为正则项;
- 目标函数第三部分(红色圆圈)为常数项
下面来解释目标函数如何展开为最终形式:
1)损失函数l是二次函数
上一步省略了一项与 f t f_{t} ft无关的平方项,需要注意。
2)损失函数l一般化(泰勒展开)
忽略损失函数l中的 f t f_{t} ft,因为它是已知的预测值,做如下对应:
- x对应 y i ^ ( t − 1 ) \hat{y_{i}}^{(t-1)} yi^(t−1)
- △ x \bigtriangleup x △x对应 f t ( x i ) f_{t}(x_{i}) ft(xi)
即可得到泰勒展开结果:
考虑正则项,即树的复杂度:
- 树里面叶子节点的个数T;
- 树上叶子节点的得分w的L2模平方;
则正则项可表达为:
Ω ( f t ) = γ T + 1 2 λ ∑ j = 1 T w j 2 \Omega (f_{t}) = \gamma T + \frac{1}{2} \lambda \sum_{j=1}^{T}w_{j}^2 Ω(ft)=γT+21λj=1∑Twj2
目标函数可变化为:
很显然,一棵树的生成是由一个节点一分为二,然后不断分裂最终形成为整棵树。那么树怎么分裂的就成为了接下来我们要探讨的关键。
对于一个叶子节点如何进行分裂,xgboost作者在其原始论文中给出了两种分裂节点的方法:
3)枚举所有不同树结构的贪心法
论文算法:
对于所有的特征x,我们只要做一遍从左到右的扫描就可以枚举出所有分割的梯度和GL和GR。然后用计算Gain的公式计算每个分割方案的分数就可以了。
然后后续则依然按照这种划分方法继续第二层、第三层、第四层、第N层的分裂。
第二个值得注意的事情就是引入分割不一定会使得情况变好,所以我们有一个引入新叶子的惩罚项。优化这个目标对应了树的剪枝, 当引入的分割带来的增益小于一个阀值γ 的时候,则忽略这个分割。
4)近似算法
主要针对数据太大,不能直接进行计算
3、XgBoost实例
查看地址:
安装代码:
conda install py-xgboost
之前不能使用conda install pxgboost
安装XgBoost,后面发现已经可以正常使用。
import xgboost as xgb
# read in data
dtrain = xgb.DMatrix('agaricus.txt.train')
dtest = xgb.DMatrix('agaricus.txt.test')
# 设置XGB的参数,使用字典形式传入
param = {'max_depth':2, 'eta':1, 'objective':'binary:logistic' }
num_round = 2 # 使用线程数
bst = xgb.train(param, dtrain, num_round) # 训练
# make prediction
preds = bst.predict(dtest) # 预测
preds
array([0.28583017, 0.9239239 , 0.28583017, ..., 0.9239239 , 0.05169873,
0.9239239 ], dtype=float32)
1)回归模型
import xgboost as xgb
from xgboost import plot_importance
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston
from sklearn.metrics import mean_squared_error
# 加载数据集
boston = load_boston()
X,y = boston.data,boston.target
# XGBoost训练过程
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
params = {
'booster': 'gbtree',
'objective': 'reg:squarederror',
'gamma': 0.1,
'max_depth': 5,
'lambda': 3,
'subsample': 0.7,
'colsample_bytree': 0.7,
'min_child_weight': 3,
'silent': 1,
'eta': 0.1,
'seed': 1000,
'nthread': 4,
}
dtrain = xgb.DMatrix(X_train, y_train)
num_rounds = 300
#这里需要转成list 否则会报错
plst = list(params.items())
model = xgb.train(plst, dtrain, num_rounds)
# 对测试集进行预测
dtest = xgb.DMatrix(X_test)
ans = model.predict(dtest)
# 显示重要特征
plot_importance(model)
plt.show()
注意上面的plst要改成list:
plst = list(params.items())
否则报错:
下面同理,不再赘述。
2)分类模型
from sklearn.datasets import load_iris
from xgboost import plot_importance
from sklearn.metrics import accuracy_score
iris = load_iris()
X,y = iris.data,iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234565) # 数据集分割
# 算法参数
params = {
'booster': 'gbtree',
'objective': 'multi:softmax',
'num_class': 3,
'gamma': 0.1,
'max_depth': 6,
'lambda': 2,
'subsample': 0.7,
'colsample_bytree': 0.75,
'min_child_weight': 3,
'silent': 0,
'eta': 0.1,
'seed': 1,
'nthread': 4,
}
plst = list(params.items())
dtrain = xgb.DMatrix(X_train, y_train) # 生成数据集格式
num_rounds = 500
model = xgb.train(plst, dtrain, num_rounds) # xgboost模型训练
# 对测试集进行预测
dtest = xgb.DMatrix(X_test)
y_pred = model.predict(dtest)
# 计算准确率
accuracy = accuracy_score(y_test,y_pred)
print("accuarcy: %.2f%%" % (accuracy*100.0))
# 显示重要特征
plot_importance(model)
plt.show()
二、LightGBM算法
目前Github各项数据:
LightGBM (Light Gradient Boosting Machine)是一个实现GBDT算法的框架,支持高效率的并行训练,并且具有以下优点:
-
更快的训练速度
-
更低的内存消耗
-
更好的准确率
-
分布式支持,可以快速处理海量数据
1.提出的动机
常用的机器学习算法,例如神经网络等算法,都可以以mini-batch的方式训练,训练数据的大小不会受到内存限制。
而GBDT在每一次迭代的时候,都需要遍历整个训练数据多次。如果把整个训练数据装进内存则会限制训练数据的大小;如果不装进内存,反复地读写训练数据又会消耗非常大的时间。尤其面对工业级海量的数据,普通的GBDT算法是不能满足其需求的。
LightGBM提出的主要原因就是为了解决GBDT在海量数据遇到的问题,让GBDT可以更好更快地用于工业实践。
2.优化内容
基于Histogram的决策树算法带深度限制的Leaf-wise的叶子生长策略直方图做差加速直接支持类别特征(Categorical Feature)Cache命中率优化基于直方图的稀疏特征优化多线程优化。
在探寻了LightGBM的优化之后,发现LightGBM还具有支持高效并行的优点。LightGBM原生支持并行学习,目前支持特征并行和数据并行的两种。特征并行的主要思想是在不同机器在不同的特征集合上分别寻找最优的分割点,然后在机器间同步最优的分割点。数据并行则是让不同的机器先在本地构造直方图,然后进行全局的合并,最后在合并的直方图上面寻找最优分割点。LightGBM针对这两种并行方法都做了优化,在特征并行算法中,通过在本地保存全部数据避免对数据切分结果的通信;在数据并行中使用分散规约(Reduce scatter)把直方图合并的任务分摊到不同的机器,降低通信和计算,并利用直方图做差,进一步减少了一半的通信量。基于投票的数据并行则进一步优化数据并行中的通信代价,使通信代价变成常数级别。在数据量很大的时候,使用投票并行可以得到非常好的加速效果。
三、感受
经过本次学习,个人对集成学习有了更加全面的感受,对于一些公式,敢于去推导,虽然有些地方仍然不是很懂,但是比学习前提高了不少,加油,坚持下去。
2021年4月27日