机器学习-XGBoost-07-灵析社区

搜不鸟了

1、XGBoost算法

XGBoost 是 eXtreme Gradient Boosting 的缩写称呼,它是一个非常强大的 Boosting 算法工具包,优秀的性能(效果与速度)让其在很长一段时间内霸屏数据科学比赛解决方案榜首,现在很多大厂的机器学习方案依旧会首选这个模型。

XGBoost 在并行计算效率、缺失值处理、控制过拟合、预测泛化能力上都变现非常优秀。本文我们给大家详细展开介绍 XGBoost,包含「算法原理」和「工程实现」两个方面。

2、算法原理可视化解读

关于 XGBoost 的原理,其作者陈天奇本人有一个非常详尽的Slides做了系统性的介绍,我们在这里借助于这个资料给大家做展开讲解。

2.1、监督学习核心要素

符号(Notations):��∈��xi​∈Rd表示训练集中的第i个样本。

模型(Model):对于已知的��xi​如何预测��^yi​^​

线性模型(Linear Model):�^=∑������y^​=∑​j​wj​xi​j(包括线性回归和逻辑回归),预测值��^yi​^​根据不同的任务有不同的解释:

  • 线性回归(Linear Regression): ��^yi​^​表示预测的分数。
  • 逻辑回归(Logistic Regression):1/(1+�−�^�)1/(1+e−y^​i​) 预测了实例为正的概率。
  • 其他:例如在排名任务中  ��^yi​^​可以是排名分数。

2.2、监督学习进阶知识

Ridge回归(L2正则化)

notion image

• Ridge 是线性模型(Linear Model),用的是平方损失(Square Loss),正则化项是 L2 Norm。

Lasso回归(L1正则化):

notion image

• Lasso是线性模型(Linear Model),用的是平方损失(Square Loss),正则化项是L1 Norm。

逻辑回归:

notion image

• 逻辑回归是线性模型(Linear Model),用的是逻辑损失(Logistic Loss),正则化项是 L2 Norm。

2.3、目标函数及偏差方差权衡

notion image

  • 优化训练损失函数(Training Loss)有助于建立预测模型,很好地拟合训练数据至少能让你更接近潜在的训练数据的分布。
  • 优化正则化项(Regularization)有助于建立简单的模型:模型越简单,未来预测的方差越小,预测越稳定。

3、XGBoost算法原理

案例:

如上图所示,将左侧的数据输入到模型1中,会得到预测收入。预测收入和真实的收入之间的差值记做残差
。由于这个模型1有一定的能力,但是能力比较弱,遗留了一些问题。这个残差就能表征这个遗留的问题。

紧接着,再训练一个模型2去预测这些样本,只不过目标值改为刚刚得到的残差。上图所示,预测的结果不再是收入,而是模型1得到的残差。上图中的模型2还会得到残差,但是我们发现第一行样本的残差已经为零了。也就是说第一个样本,通过模型1和模型2能够预测对收入。但是除了第一行,其他的还是有残差的,这时候可以在这基础上训练一个模型3

上图所示,在刚刚 模型2得到的残差(准确的说是模型1和模型2共同作用的结果)
 的基础上去拟合,得到模型3。这时候的残差可以理解为是前两个模型遗留下来的问题。该模型去预测模型2的残差,我们发现通过前三个模型的预测,得到的残差是上图中最新的残差这一列。

这时候最新的残差都是非常小了,如果能达到我们满意的标准,我们就可以停下。这样我们就得到了三个不同的模型。如下图所示,最终的预测就是三个模型预测的结果和。如下图:

我们解决问题的步骤:

如何构造目标函数 -> 目标函数直接优化难,如何近似? -> 如何把树的结构引入到目标函数?-> 仍然难优化,要不要使用贪心算法?

3.1 构建目标函数

首先举个例子,用多棵树来预测张三、李四的薪资。如下图所示,用年龄这个因素构建的树预测张三的值为12,用工作年限这个因素构建的树张三为2. 两个相加就是对张三薪资的预测:12+2=14。

假设已经训练了�K颗树,则对于第�i个样本的最终预测值为:

notion image

��xi​是样本的特征,��(��)fk​(xi​)是用第�k颗树��xi​样本进行预测。将结果加在一起就得到了最终的预测值�^�y^​i​,而该样本的真实label是��yi​。这样我们就能构建损失函数了。

构建的目标函数如下:

损失函数计算模型预测值和真实值的 loss,其中�l是损失函数,可以是 MSE、Cross Entropy 等等。第二项是正则项,来控制模型的复杂度,防止过拟合。这个正则项可以类比 L2 正则。

3.2叠加式的训练

notion image

notion image

notion image

notion image

3.3用泰勒级数近似目标函数

3.4如何用参数表示一颗树

3.5、定义树的复杂度

notion image

3.6、新的目标函数

经过上面的一步步的简化,我们把最初的目标函数:

notion image

简化为了:

notion image

紧接着,看下图,假设第一个叶节点上(即 15 的地方)有样本[1, 3]落在这里 ,第二个节点有样本[2]落在这个地方,样本[4,5]落在了第三个叶子结点处这里 :

所以:

notion image

notion image

notion image

二次函数求最优解问题。

知识回顾,典型的二次函数:

notion image

最小点的值为:

notion image

notion image

3.7、如何寻找树的形状?

。所以,使用贪心的方式,选择新的树目标函数值较小的那颗树。

比如下面这个例子,我们有样本[1、2、3、4、5、6、7、8],第一颗树把这些样本分为了两部分,左侧的叶子结点是

[7,8],右侧节点是[1,2,3,4,5,6]。

此时我们知道了树的结构,可以根据如下的公式计算出此时树的最小目标函数值:

notion image

紧接着,我们根据新的特征对叶子结点再次进行了分割,得到了如下的树的形状:

notion image

notion image

紧接着计算两颗树最小目标函数值的差:

notion image

4.XGBoost工程优化

4.1、并行列块设计

XGBoost 将每一列特征提前进行排序,以块(Block)的形式储存在缓存中,并以索引将特征值和梯度统计量对应起来,每次节点分裂时会重复调用排好序的块。而且不同特征会分布在独立的块中,因此可以进行分布式或多线程的计算。

notion image

4.2、缓存访问优化

4.3、核外块计算

数据量非常大的情形下,无法同时全部载入内存。XGBoost 将数据分为多个 blocks 储存在硬盘中,使用一个独立的线程专门从磁盘中读取数据到内存中,实现计算和读取数据的同时进行。为了进一步提高磁盘读取数据性能,XGBoost 还使用了两种方法:

  • ① 压缩 block,用解压缩的开销换取磁盘读取的开销。
  • ② 将 block 分散储存在多个磁盘中,提高磁盘吞吐量。

5.XGBoost vs GBDT

GBDT和这里的 XGBoost 做一个对比总结:

notion image

  • GBDT 是机器学习算法,XGBoost 在算法基础上还有一些工程实现方面的优化。
  • GBDT 使用的是损失函数一阶导数,相当于函数空间中的梯度下降;XGBoost 还使用了损失函数二阶导数,相当于函数空间中的牛顿法。
  • 正则化:XGBoost 显式地加入了正则项来控制模型的复杂度,能有效防止过拟合。
  • 列采样:XGBoost 采用了随机森林中的做法,每次节点分裂前进行列随机采样。
  • 缺失值:XGBoost 运用稀疏感知策略处理缺失值,GBDT无缺失值处理策略。
  • 并行高效:XGBoost 的列块设计能有效支持并行运算,效率更优。

6、Code

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
 
# 导入数据集
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)
 
model = xgb.XGBRegressor(max_depth=5,learning_rate=0.1,n_estimators=160,silent=True,objective='reg:gamma')
model.fit(X_train,y_train)
 
# 对测试集进行预测
ans = model.predict(X_test)
 
# 显示重要特征
plot_importance(model)
plt.show()
PythonCopy



from sklearn.model_selection import train_test_split
from sklearn import metrics
from  sklearn.datasets  import  make_hastie_10_2
from xgboost.sklearn import XGBClassifier
X, y = make_hastie_10_2(random_state=0)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)##test_size测试集合所占比例
clf = XGBClassifier(
silent=0 ,#设置成1则没有运行信息输出,最好是设置为0.是否在运行升级时打印消息。
#nthread=4,# cpu 线程数 默认最大
learning_rate= 0.3, # 如同学习率
min_child_weight=1,
# 这个参数默认是 1,是每个叶子里面 h 的和至少是多少,对正负样本不均衡时的 0-1 分类而言
#,假设 h 在 0.01 附近,min_child_weight 为 1 意味着叶子节点中最少需要包含 100 个样本。
#这个参数非常影响结果,控制叶子节点中二阶导的和的最小值,该参数值越小,越容易 overfitting。
max_depth=6, # 构建树的深度,越大越容易过拟合
gamma=0,  # 树的叶子节点上作进一步分区所需的最小损失减少,越大越保守,一般0.1、0.2这样子。
subsample=1, # 随机采样训练样本 训练实例的子采样比
max_delta_step=0,#最大增量步长,我们允许每个树的权重估计。
colsample_bytree=1, # 生成树时进行的列采样
reg_lambda=1,  # 控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
#reg_alpha=0, # L1 正则项参数
#scale_pos_weight=1, #如果取值大于0的话,在类别样本不平衡的情况下有助于快速收敛。平衡正负权重
#objective= 'multi:softmax', #多分类的问题 指定学习任务和相应的学习目标
#num_class=10, # 类别数,多分类与 multisoftmax 并用
n_estimators=100, #树的个数
seed=1000 #随机种子
#eval_metric= 'auc'
)
clf.fit(X_train,y_train,eval_metric='auc')
#设置验证集合 verbose=False不打印过程
clf.fit(X_train, y_train,eval_set=[(X_train, y_train), (X_val, y_val)],eval_metric='auc',verbose=False)
#获取验证集合结果
evals_result = clf.evals_result()
y_true, y_pred = y_test, clf.predict(X_test)
print"Accuracy : %.4g" % metrics.accuracy_score(y_true, y_pred)
#回归
#m_regress = xgb.XGBRegressor(n_estimators=1000,seed=0)
PythonCopy



params = {'objective': 'reg:squarederror', 
# 默认reg:linear。 reg:squarederror,代表要解决的问题时分类还是回归,取值可以很多,一般只关心是分类还是回归,
# 在回归问题objective一般使用reg:squarederror ,即MSE均方误差或者:reg:linear , reg:logistic , count:poisson 。
# 二分类问题一般使用binary:logistic,rank:pairwise 
# 多分类问题一般使用multi:softmax


阅读量:2012

点赞量:0

收藏量:0