集成学习_LightGBM

作者: Nefelibatas | 来源:发表于2022-02-15 09:38 被阅读0次

2017年经微软推出,XGBoost的升级版 Light => 在大规模数据集上运行效率更高 GBM => Gradient Boosting Machine

Motivation

常用的机器学习算法,例如神经网络等算法,都可以以mini-batch的方式训练,训练数据的大小不会受到内存限制

GBDT在每一次迭代的时候,都需要遍历整个训练数据多次。如果把整个训练数据装进内存则会限制训练数据的大小;

如果不装进内存,反复地读写训练数据又会消耗非常大的时间。对于工业级海量的数据,普通的GBDT算法是不能满足其需求的

LightGBM的提出是为了解决GBDT在海量数据遇到的问题,让GBDT可以更好更快地用于工业场景

LightGBM与XGBoost比较

模型精度:两个模型相当

训练速度:LightGBM训练速度更快 => 1/10

内存消耗:LightGBM占用内存更小 => 1/6

特征缺失值:两个模型都可以自动处理特征缺失值

分类特征:XGBoost不支持类别特征,需要对其进行OneHot编码,而LightGBM支持分类特征

XGBoost模型的复杂度

  • 模型复杂度 = 树的棵数 X 每棵树的叶子数量 X 每片叶子生成复杂度

  • 每片叶子生成复杂度 = 特征数量 X 候选分裂点数量 X 样本的数量

  • 针对XGBoost的优化:

    • Histogram算法,直方图算法 => 减少候选分裂点数量

    • GOSS算法,基于梯度的单边采样算法 => 减少样本的数量

    • EFB算法,互斥特征捆绑算法 => 减少特征的数量

LightGBM = XGBoost + Histogram + GOSS + EFB

XGBoost的预排序(pre-sorted)算法

  • 将样本按照特征取值排序,然后从全部特征取值中找到最优的分裂点位

  • 预排序算法的候选分裂点数量=样本特征不同取值个数减1

eg: i列中x_i、g_i、h_i分别对应原函数、一阶导、二阶导

i 1 2 3 4 5 6 7 8
x_i 0.1 2.1 2.5 3.0 3.0 4.0 4.5 5.0
g_i 0.01 0.03 0.06 0.05 0.04 0.7 0.6 0.07
h_i 0.2 0.04 0.05 0.02 0.08 0.02 0.03 0.03
image-20220212190514632.png

LightGBM的Histogram算法

  • 替代XGBoost的预排序算法

  • 思想是先连续的浮点特征值离散化成k个整数,同时构造一个宽度为k的直方图,即将连续特征值离散化到k个bins上(比如k=255)

  • 当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点

  • XGBoost需要遍历所有离散化的值,LightGBM只要遍历k个直方图的值

  • 候选分裂点数量 = k-1

image-20220212190708701.png

GOSS算法

  • Gradient-based One-Side Sampling,基于梯度的单边采样算法

  • 思想是通过样本采样,减少目标函数增益Gain的计算复杂度

  • 单边采样,只对梯度绝对值较小的样本按照一定

  • 比例进行采样,而保留了梯度绝对值较大的样本 因为目标函数增益主要来自于梯度绝对值较大的样本 => GOSS算法在性能和精度之间进行了很好的trade off

image-20220212205120521.png

EFB算法

Exclusive Feature Bundling,互斥特征绑定算法

思想是特征中包含大量稀疏特征的时候,减少构建直方图的特征数量,从而降低计算复杂度

数据集中通常会有大量的稀疏特征(大部分为0,少量为非0)我们认为这些稀疏特征是互斥的,

即不会同时取非零值

EFB算法可以通过对某些特征的取值重新编码,将多个这样互斥的特征绑定为一个新的特征

类别特征可以转换成onehot编码,这些多个特征的onehot编码是互斥的,可以使用EFB将他们绑定为一个特征

在LightGBM中,可以直接将每个类别取值和一个bin关联,从而自动地处理它们,也就无需预处理成onehot编码

LightGBM工具

参数

  • boosting_type,训练方式,gbdt

  • objective,目标函数,可以是binary,regression

  • metric,评估指标,可以选择auc, mae,mse,binary_logloss,multi_logloss

  • max_depth,树的最大深度,当模型过拟合时,可以降低 max_depth

  • min_data_in_leaf,叶子节点最小记录数,默认20

  • lambda,正则化项,范围为0~1

  • min_gain_to_split,描述分裂的最小 gain,控制树的有用的分裂

  • max_cat_group,在 group 边界上找到分割点,当类别数量很多时,找分割点很容易过拟合时

  • num_boost_round,迭代次数,通常 100+

  • num_leaves,默认 31

  • device,指定cpu 或者 gpu

  • max_bin,表示 feature 将存入的 bin 的最大数量

  • categorical_feature,如果 categorical_features = 0,1,2, 则列 0,1,2是 categorical 变量 //与xgb的不同

  • ignore_column,与 categorical_features 类似,只不过不是将特定的列视为categorical,而是完全忽略

Bagging参数
  • bagging_fraction+bagging_freq(需要同时设置)

  • bagging_fraction,每次迭代时用的数据比例,用于加快训练速度和减小过拟合

  • bagging_freq:bagging的次数。默认为0,表示禁用bagging,非零值表示执行k次bagging,可以设置为3-5

  • feature_fraction,设置在每次迭代中使用特征的比例,例如为0.8时,意味着在每次迭代中随机选择80%的参数来建树

  • early_stopping_round,如果一次验证数据的一个度量在最近的round中没有提高,模型将停止训练

模型参数配置

param = {'boosting_type':'gbdt',
                         'objective' : 'binary', #任务类型
                         'metric' : 'auc', #评估指标
                         'learning_rate' : 0.01, #学习率
                         'max_depth' : 15, #树的最大深度
                         'feature_fraction':0.8, #设置在每次迭代中使用特征的比例
                         'bagging_fraction': 0.9, #样本采样比例
                         'bagging_freq': 8, #bagging的次数
                         'lambda_l1': 0.6, #L1正则
                         'lambda_l2': 0, #L2正则
       }

模型训练,得出预测结果

X_train, X_valid, y_train, y_valid = train_test_split(train.drop('Attrition',axis=1), train['Attrition'], test_size=0.2, random_state=42)
trn_data = lgb.Dataset(X_train, label=y_train)
val_data = lgb.Dataset(X_valid, label=y_valid)
model = lgb.train(param,train_data,valid_sets=[train_data,valid_data],num_boost_round = 10000 ,early_stopping_rounds=200,verbose_eval=25, categorical_feature=attr)
predict=model.predict(test)
test['Attrition']=predict
# 转化为二分类输出
test['Attrition']=test['Attrition'].map(lambda x:1 if x>=0.5 else 0)
test[['Attrition']].to_csv('submit_lgb.csv')

参数对比

xgb lgb XGBClassifier(xgb.sklearn) LGBMClassifier(lgb.sklearn)
booster='gbtree' boosting='gbdt' booster='gbtree' boosting_type='gbdt'
objective='binary:logistic' application='binary' objective='binary:logistic' objective='binary'
max_depth=7 num_leaves=2**7 max_depth=7 num_leaves=2**7
eta=0.1 learning_rate=0.1 learning_rate=0.1 learning_rate=0.1
num_boost_round=10 num_boost_round=10 n_estimators=10 n_estimators=10
gamma=0 min_split_gain=0.0 gamma=0 min_split_gain=0.0
min_child_weight=5 min_child_weight=5 min_child_weight=5 min_child_weight=5
subsample=1 bagging_fraction=1 subsample=1.0 subsample=1.0
colsample_bytree=1.0 feature_fraction=1 colsample_bytree=1.0 colsample_bytree=1.0
alpha=0 lambda_l1=0 reg_alpha=0.0 reg_alpha=0.0
lambda=1 lambda_l2=0 reg_lambda=1 reg_lambda=0.0
scale_pos_weight=1 scale_pos_weight=1 scale_pos_weight=1 scale_pos_weight=1
seed bagging_seed
feature_fraction_seed random_state=888 random_state=888
nthread num_threads n_jobs=4 n_jobs=4
evals valid_sets eval_set eval_set
eval_metric metric eval_metric eval_metric
early_stopping_rounds early_stopping_rounds early_stopping_rounds early_stopping_rounds
verbose_eval verbose_eval verbose verbose

调参经验

LGBMClassifier经验参数
clf = lgb.LGBMClassifier(
            num_leaves=2**5-1, reg_alpha=0.25, reg_lambda=0.25, objective='binary',
            max_depth=-1, learning_rate=0.005, min_child_samples=3, random_state=2021,
            n_estimators=2000, subsample=1, colsample_bytree=1,
        )
'''
num_leavel=2**5-1 # 树的最大叶子数,对比XGBoost一般为2^(max_depth)
reg_alpha,L1正则化系数
reg_lambda,L2正则化系数
max_depth,最大树的深度

n_estimators,树的个数,相当于训练的轮数
subsample,训练样本采样率(行采样)
colsample_bytree,训练特征采样率(列采样)
'''
XGBoost VS LightGBM

XGBoost效果相对LightGBM可能会好一些

xgb = xgb.XGBClassifier(
            max_depth=6, learning_rate=0.05, n_estimators=2000, 
            objective='binary:logistic', tree_method='gpu_hist', 
            subsample=0.8, colsample_bytree=0.8, 
            min_child_samples=3, eval_metric='auc', reg_lambda=0.5
        )
'''
max_depth,树的最大深度
learning_rate, 学习率
reg_lambda,L2正则化系数
n_estimators,树的个数,相当于训练的轮数
objective,目标函数, binary:logistic 用于二分类任务
tree_method, 使用功能的树的构建方法,hist代表使用直方图优化的近似贪婪算法
subsample,训练样本采样率(行采样)
colsample_bytree,训练特征采样率(列采样)

subsample, colsample_bytree是个值得调参的参数,
典型的取值为0.5-1(取0.7效果可能更好)


模型参数调参:
n_estimatores:总共迭代的次数,即决策树的个数
early_stopping_rounds:
    含义:在验证集上,连续n次迭代,分数没有提高,就终止训练
    调参:防止overfitting
max_depth
    含义:树的深度,默认值为6,典型值3-10
    调参:值越大,越容易过拟合;值越小,越容易欠拟合
min_child_weight
    含义:默认值为1
    调参:值越大,越容易欠拟合;值越小,越容易过拟合(值较大时,避免模型学习到局部的特殊样本)

subsample
    含义:训练每棵树时,使用的数据占全部训练集的比例。默认值为1,典型值为0.5-1
    调参:防止overfitting
colsample_bytree
    含义:训练每棵树时,使用的特征占全部特征的比例。默认值为1,典型值为0.5-1
    调参:防止overfitting

learning_rate
    含义:学习率,控制每次迭代更新权重时的步长,默认0.3
    调参:值越小,训练越慢, 典型值为0.001-0.05
    
objective 目标函数
    回归任务:reg:linear (默认),reg:logistic 
    二分类:
        binary:logistic   概率 ,binary:logitraw   类别
 多分类
        multi:softmax  num_class=n   返回类别
        multi:softprob   num_class=n  返回概率
        
eval_metric
    回归任务(默认rmse):rmse--均方根误差,mae--平均绝对误差
    分类任务(默认error)
        auc--roc曲线下面积
        error--错误率(二分类)
        merror--错误率(多分类)
        logloss--负对数似然函数(二分类)
        mlogloss--负对数似然函数(多分类)
gamma,惩罚项系数,指定节点分裂所需的最小损失函数下降值
alpha,L1正则化系数,默认为1
lambda,L2正则化系数,默认为1

'''

相关文章

网友评论

    本文标题:集成学习_LightGBM

    本文链接:https://www.haomeiwen.com/subject/budflrtx.html