机器学习算法——XGBoost

1.创新点

主要创新点:

  • 设计和构建高度可扩展的端到端提升树系统。
    提出了一个理论上合理的加权分位数略图(weighted quantile
    sketch )来计算候选集。
  • 引入了一种新颖的稀疏感知算法用于并行树学习。 令缺失值有默认方向。
  • 提出了一个有效的用于核外树形学习的缓存感知块结构。 用缓存加速寻找排序后被打乱的索引的列数据的过程。

链接:https://www.jianshu.com/p/a62f4dce3ce8

2.原理

XGBoost使用了和CART回归树一样的想法,利用贪婪算法,遍历所有特征的所有特征划分点,不同的是使用的目标函数不一样。具体做法就是分裂后的目标函数值比单子叶子节点的目标函数的增益,同时为了限制树生长过深,还加了个阈值,只有当增益大于该阈值才进行分裂。从而继续分裂,形成一棵树,再形成一棵树,每次在上一次的预测基础上取最优进一步分裂/建树。

3.XGBoost的优缺点

与GBDT对比

  1. GBDT的基分类器只支持CART树,而XGBoost支持线性分类器,此时相当于带有L1和L2正则项的逻辑回归(分类问题)和线性回归(回归问题)。
  2. GBDT在优化时只使用了一阶导数,而XGBoost对目标函数进行二阶泰勒展开,此外,XGBoost支持自定义损失函数,只要损失函数二阶可导
  3. XGBoost借鉴随机森林算法,支持列抽样和行抽样,这样即能降低过拟合风险,又能降低计算。
  4. XGBoost在目标函数引入了正则项,正则项包括叶节点的个数叶节点的输出值的L2范数。通过约束树结构,降低模型方差,防止过拟合。
  5. XGBoost对缺失值不敏感,能自动学习其分裂方向
  6. XGBoost在每一步中引入缩减因子降低单颗树对结果的影响,让后续模型有更大的优化空间,进一步防止过拟合。
  7. XGBoost在训练之前,对数据预先进行排序并保存为block,后续迭代中重复使用,减少计算,同时在计算分割点时,可以并行计算
  8. 可并行的近似直方图算法,树结点在进行分裂时,需要计算每个节点的增益,若数据量较大,对所有节点的特征进行排序,遍历的得到最优分割点,这种贪心法异常耗时,这时引进近似直方图算法,用于生成高效的分割点,即用分裂后的某种值减去分裂前的某种值,获得增益,为了限制树的增长,引入阈值,当增益大于阈值时,进行分裂;
    与LightGBM对比
  9. XGBoost采用预排序,在迭代之前,对结点的特征做预排序,遍历选择最优分割点,数据量大时,贪心法耗时,LightGBM方法采用histogram算法,占用的内存低,数据分割的复杂度更低,但是不能找到最精确的数据分割点。同时,不精确的分割点可以认为是降低过拟合的一种手段。
  10. LightGBM借鉴Adaboost的思想,对样本基于梯度采样,然后计算增益,降低了计算
  11. LightGBM对列进行合并,降低了计算
  12. XGBoost采样level-wise策略进行决策树的生成,同时分裂同一层的节点,采用多线程优化,不容易过拟合,但有些节点分裂增益非常小,没必要进行分割,这就带来了一些不必要的计算;LightGBM采样leaf-wise策略进行树的生成,每次都选择在当前叶子节点中增益最大的节点进行分裂,如此迭代,但是这样容易产生深度很深的树,产生过拟合,所以增加了最大深度的限制,来保证高效的同时防止过拟合。

4.API

读取数据

dtrain = xgb.DMatrix(‘demo/data/agaricus.txt.train’)
dtest = xgb.DMatrix(‘demo/data/agaricus.txt.test’)

通过 map 指定参数

param = {‘max_depth’:2, ‘eta’:1, ‘silent’:1, ‘objective’:‘binary:logistic’ }
num_round = 2
bst = xgb.train(param, dtrain, num_round)

预测

preds = bst.predict(dtest)

要加载 numpy 的数组到 DMatrix 对象中, 代码如下:

import numpy as np
import xgboost as xgb
data = np.random.rand(5,10) # 5 entities, each contains 10 features
label = np.random.randint(2, size=5) # binary target
dtrain = xgb.DMatrix( data, label=label)

->data

array([[4.58112586e-01, 5.15109055e-01, 9.49322368e-01, 4.12068451e-01,
        9.07828945e-01, 6.01836350e-01, 2.67689084e-02, 8.71999699e-01,
        9.70469774e-01, 4.08043402e-01],
       [3.84152246e-01, 3.33657143e-01, 5.09202802e-01, 7.49937855e-01,
        6.76731623e-01, 5.98826160e-01, 8.87044516e-01, 2.42738478e-01,
        5.54069014e-01, 7.31676395e-01],
       [4.31604612e-04, 2.37646980e-01, 7.08828313e-01, 2.97212746e-01,
        7.08635495e-01, 5.25163997e-01, 3.93572198e-01, 9.49710807e-01,
        7.81015022e-01, 2.29557159e-01],
       [7.72886296e-01, 2.38108229e-01, 1.25507593e-01, 2.79567575e-01,
        2.82561160e-02, 7.04470072e-01, 2.61917976e-01, 5.98723606e-01,
        6.72975320e-01, 7.21076548e-01],
       [2.88186647e-01, 6.24797266e-01, 5.15669053e-01, 8.68095215e-01,
        4.43562171e-01, 5.07861559e-01, 6.53741982e-01, 9.29474058e-01,
        7.91150281e-02, 1.52469552e-01]])

-> label

array([1, 1, 1, 0, 0])

-> dtrain


  • 稀疏矩阵的Dmartix的数据导入
import scipy
csr = scipy.sparse.csr_matrix((dat, (row, col)))
dtrain = xgb.DMatrix(csr)
  • 使用自带的libsvm数据格式
dtrain = xgb.DMatrix(‘train.svm.txt’)
dtrain.save_binary(“train.buffer”)
  • 自定义缺失值
dtrain = xgb.DMatrix(data, label=label, missing = -999.0)
  • 必要时设置权重
w = np.random.rand(5, 1)
dtrain = xgb.DMatrix(data, label=label, missing = -999.0, weight=w)
  • 通过字典的形式设置参数
param = {'bst:max_depth':2, 'bst:eta':1, 'silent':1, 'objective':'binary:logistic' }
param['nthread'] = 4
param['eval_metric'] = 'auc'
  • 其他评价指标
param[‘eval_metric’] = [‘auc’, ‘ams@0’]
#alternativly:
#plst = param.items()
#plst += [(‘eval_metric’, ‘ams@0’)]
  • 指定测试集合
evallist  = [(dtest,‘eval’), (dtrain,‘train’)]
  • 训练
num_round = 10
bst = xgb.train( plst, dtrain, num_round, evallist )
  • 保存模型
bst.save_model(‘0001.model’)

#转存模型
bst.dump_model(‘dump.raw.txt’)
#转储模型和特征映射
bst.dump_model(‘dump.raw.txt’,‘featmap.txt’)
  • 加载模型
bst = xgb.Booster({‘nthread’:4}) #init model
bst.load_model(“model.bin”) # load data
  • 提前停止

如果您有一个验证集, 你可以使用提前停止找到最佳数量的 boosting rounds(梯度次数). 提前停止至少需要一个 evals集合. 如果有多个, 它将使用最后一个.
train(…, evals=evals, early_stopping_rounds=10)
该模型将开始训练, 直到验证得分停止提高为止. 验证错误需要至少每个 early_stopping_rounds减少以继续训练.

如果提前停止,模型将有三个额外的字段: bst.best_score, bst.best_iteration 和 bst.best_ntree_limit.请注意 train() 将从上一次迭代中返回一个模型, 而不是最好的一个.
这与两个度量标准一起使用以达到最小化(RMSE, 对数损失等)最大化(MAP, NDCG, AUC). 请注意, 如果您指定多个评估指标, 则 param [‘eval_metric’] 中的最后一个用于提前停止.

  • 预测
#7 个样本, 每一个包含 10 个特征
data = np.random.rand(7, 10)
dtest = xgb.DMatrix(data)
ypred = bst.predict(xgmat)

如果在训练过程中提前停止, 可以用 bst.best_ntree_limit

从最佳迭代中获得预测结果:
ypred = bst.predict(xgmat,ntree_limit=bst.best_ntree_limit)
当你观察到训练精度高,但是测试精度低时,你可能遇到了过拟合的问题。
通常有两种方法可以控制 xgboost 中的过拟合。
第一个方法是直接控制模型的复杂度
这包括max_depth, min_child_weight 和 gamma
第二种方法是增加随机性,使训练对噪声强健
这包括 subsample, colsample_bytree
你也可以减小步长 eta, 但是当你这么做的时候需要记得增加 num_round

  • 处理不平衡的数据集

对于广告点击日志等常见情况,数据集是极不平衡的。 这可能会影响 xgboost 模型的训练,有两种方法可以改善它。
如果你只关心预测的排名顺序(AUC)
通过 scale_pos_weight 来平衡positivenegative 权重。

  • 使用 AUC 进行评估

如果你关心预测正确的概率
在这种情况下,您无法重新平衡数据集
在这种情况下,将参数max_delta_step 设置为有限数字(比如说1)将有助于收敛

原文链接:https://blog.csdn.net/weixin_40083227/article/details/103610953

你可能感兴趣的:(机器学习算法——XGBoost)