机器学习:lightGBM算法

  lightGBM是基于GBDT的一个算法。因为传统的GBDT在每一次迭代时需要多次遍历整个训练数据,所以GBDT的训练会受内存等的限制。尤其在处理工业级海量数据的数据时,GBDT不能满足其需求。而lightGBM支持高效率的并行训练,并且具有更快的迭代速度,更低的内存消耗、更好的准确率,支持分布式可以快速处理海量数据。lightGBM的优缺点主要如下:

1.优点

  XGBoost也是GBDT框架下的一个算法。相对于XGBoost, lightGBM的优点主要集中在内存和速度两个方面。

  • lightGBM采用基于直方图的决策树算法,该算法将遍历样本转化为遍历直方图。既降低了内存使用率又可以利用直方图做差的方式降低计算复杂度;而XGBoost采用的是基于预排序的决策树算法,不仅需要额外的空间保存特征排序结果,而且需要遍历每一个分割点计算分裂增益,计算代价大。
  • ligthGBM算法在训练过程中采用单边梯度算法(GOSS)过滤掉梯度小的样本,减少了大量的计算。GOSS先将要进行分裂的特征的所有绝对值大小进行降序排序,选取绝对值最大的 a × 100 % a\times 100\% a×100%个数据,然后在剩下的较小梯度数据中随机选择 b × 100 % b\times 100\% b×100%个数据。接着将这 b × 100 % b\times 100\% b×100%个数据乘以一个常数 1 − a b \frac{1-a}{b} b1a,这样算法既可以更关注训练不足的样本,又不用担心会改变原数据集的分布。
  • lightGBM采用了leaf-wise算法的增长策略构建树,减少了很多不必要的计算。XGBoost采用按层(level-wise)生长策略,该策略遍历一次数据可以同时分裂同一层的叶子,虽然这样方便进行多线程优化,控制模型复杂度并且不容易过拟合,但这种策略不加区分低对待同一层的叶子,非常低效。而lightGBM采用的leaf-wise算法每次只对当前分裂增益最大的叶子结点进行分裂。这种方法很容易长出比较深的树从而导致过拟合,所以一般会在树的最大深度上加一个限制。
  • lightGBM采用优化后的特征并行、数据并行方法加速计算,当数据量非常大的时候还可以采用投票并行的策略。
  • lightGBM对缓存进行了优化,增加了缓存命中率。
  • lightGBM算法在训练过程可以将两两互斥或冲突率低的特征捆绑成一个特征进行处理,减少了特征数量,降低了内存消耗(使用图着色原理选择要捆绑在一起的特征)。
  • lightGBM可以直接处理类别型特征。
2.缺点
  • 可能会长比深的决策树,产生过拟合。
  • lightGBM是基于偏差的算法,所以会对异常值比较敏感。
  • 在寻找最优解的时候,没有将最优解是全部特征的综合这一理念考虑进去。
3.案例

  这里使用lightGBM的sklearn接口。下面以LGBMClassifier()为例,介绍其中的主要参数。
在这里插入图片描述

  • boosting_type:‘gbdt’(传统的GBDT模型)、‘dart’、‘goss’、‘rf’(随机森林)
    dart: Dropouts meet Multiple Additive Regression Trees. 在每棵树的迭代过程中不再单单去拟合前一棵树的残差,而是从前面已有的树中采样一部分树,组合成一个新的树,然后去拟合这部分的残差,从而使后面的树贡献变大一些。
    goss:Gradient-based One-Side Sampling,单边梯度采样。目的是丢弃一些对计算增益没有帮助的样本留下有帮助的,降低计算复杂度。
  • num_leaves:基学习器的最大叶子节点数。
  • max_depth: 基学习器的最大树深度。若 ≤ 0 \leq 0 0则意味着对树深度不加限制。
  • learning_rate: 学习率。
  • n_estimators:学习器的个数。
  • subsample_for_bin: 构成bins的样本数。
    lightGBM中使用基于直方图算法的决策树算法。对每个特征进行直方图统计,然后根据直方图的离散值,遍历寻找最优的分割点。
  • objective: ‘binary’、‘multiclass’
  • class_weight: 该参数主要用于多分类任务中;在二分类任务中,可以使用is_unbalance或者scale_pos_weight。
  • colsample_bytree:构造每棵树时特征的抽样比率。
  • reg_alpha: L1正则化项。
  • reg_lambda: L2正则化项。
  • silent: 是否打印每次的运行结果。

LGBMClassifier()的fit()方法中也有几个重要参数需要说明。具体如下:
在这里插入图片描述

  • eval_metric:评价指标。分类任务默认使用’logloss‘。lightGBM中常用的评价指标有:
    机器学习:lightGBM算法_第1张图片
  • categorical_feature: 类别特征。lightGBM是目前唯一能直接处理类别特征的算法。在lightGBM中类别特征不需要在用one-hot进行转换了。
import pandas as pd
from lightgbm import LGBMClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score,accuracy_score
from sklearn.impute import SimpleImputer
from sklearn.model_selection import GridSearchCV

data=pd.read_csv('Titanic.train.csv')

#删除无用字段
data=data.drop(['PassengerId','Name','Ticket','Cabin'],axis=1)

#对Age字段的缺失值用均值进行填充。也可以使用模型预测缺失值。
imputer=SimpleImputer(strategy='mean')
data['Age']=imputer.fit_transform(data[['Age']])

#把object型转换category型(lightGBM不接受object型)
for col in data.columns:
    if data[col].dtype=='object':
        data[col]=data[col].astype('category')

x=data.drop(['Survived'],axis=1)
y=data['Survived']

x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=0)

params={'max_depth':[2,3,4],
        'learning_rate':[0.05,0.1,0.15,0.2,1],
        'n_estimators':[30,50,80,100]}

estimator=LGBMClassifier(objective='binary',reg_alpha=0.1,
                                reg_lambda=0.2)
gbm=GridSearchCV(estimator,params)
gbm.fit(x_train,y_train,early_stopping_rounds=10,
        categorical_feature=['Sex','Embarked'],
        eval_metric=['auc','binary'],
        eval_set=[(x_train,y_train)],
        eval_names='train',
        verbose=10)

model=gbm.best_estimator_
y_pred=model.predict(x_test)
roc_auc=roc_auc_score(y_test,model.predict_proba(x_test)[:,1])
accuracy=accuracy_score(y_test,y_pred)
print("lightGBM模型的准确率为{:.3f},AUC={:.3f}".format(accuracy,roc_auc))

其运行结果如下:

lightGBM模型的准确率为0.849,AUC=0.904

参考资料
  1. https://zhuanlan.zhihu.com/p/99069186
  2. https://lightgbm.readthedocs.io/en/latest/index.html

你可能感兴趣的:(机器学习)