ML之lightgbm.sklearn:LGBMClassifier函数的简介、具体案例、调参技巧之详细攻略

举报
一个处女座的程序猿 发表于 2021/03/28 01:58:41 2021/03/28
【摘要】 ML之lightgbm.sklearn:LGBMClassifier函数的简介、具体案例、调参技巧之详细攻略         目录 LGBMClassifier函数的简介、具体案例、调参技巧 LGBMClassifier函数的调参技巧 1、lightGBM适合较大数据集的样本 2、建议使用更小的learning_rat...

ML之lightgbm.sklearn:LGBMClassifier函数的简介、具体案例、调参技巧之详细攻略

 

 

 

 

目录

LGBMClassifier函数的简介、具体案例、调参技巧

LGBMClassifier函数的调参技巧

1、lightGBM适合较大数据集的样本

2、建议使用更小的learning_rate和更大的num_iteration

3、样本不平衡调参技巧

4、调参时,可将参数字典分为两大类

LGBMClassifier函数简介

1、所有弱学习器的参数

2、具体函数解释


 

 

 

LGBMClassifier函数的简介、具体案例、调参技巧

LGBMClassifier函数的调参技巧

1、lightGBM适合较大数据集的样本

而对于较小的数据集(<10000条记录),lightGBM可能不是最佳选择。所以,如果进行调优lightgbm参数,这可能没有帮助。

 

2、建议使用更小的learning_rate和更大的num_iteration

此外,如果您想要更高的num_iteration,那么您应该使用early_stopping_rounds,以便在无法学习任何有用的内容时停止训练。

 

3、样本不平衡调参技巧

lightgbm中,可以设置两个参数is_unbalance和scale_pos_weight。
is_unbalace:当其为True时,算法将尝试自动平衡占主导地位的标签的权重(使用列集中的pos/neg分数)
scale_pos_weight:默认1,即假设正负标签都是相等的。在不平衡数据集的情况下,建议使用以下公式:
sample_pos_weight = number of negative samples / number of positive samples

 

4、调参时,可将参数字典分为两大类

https://sites.google.com/view/lauraepp/parameters

调优参数

search_params = {'learning_rate': 0.4,

                 'max_depth': 15,

                 'num_leaves': 20,

                 'feature_fraction': 0.8,

                 'subsample': 0.2}

固定参数

fixed_params={'objective': 'binary',

              'metric': 'auc',

              'is_unbalance':True,

              'boosting':'gbdt',

              'num_boost_round':300,

              'early_stopping_rounds':30}

 

 

LGBMClassifier函数简介

LightGBM原论文https://papers.nips.cc/paper/6907-lightgbm-a-highly-efficient-gradient-boosting-decision-tree

1、所有弱学习器的参数

参数及其默认

参数解释及调参技巧

boosting_type='gbdt'

提升树的类型,常用的梯度提升方法包括gbdt、dart、goss、rf。可以尝试运行不同类型的渐变增强提升方法。

(1)、gbdt:这是传统的梯度提升决策树,也是基于XGBoost和pGBRT等优秀库背后的算法。gbdt精度高、效率高、稳定性好,目前已得到广泛的应用。但是,它的主要缺点是,在每个树节点中找到最佳分割点非常耗时,而且会消耗内存。下边其它的提升方法试图解决这个问题。

(2)、dart:即Dropouts meet Multiple Additive Regression Trees,dart利用dropout技巧(源自深度神经网络)解决过拟合的Regression Trees,改进模型正则化。gbdt存在过度专门化(over-specialization)的问题,这意味着在以后的迭代中添加的树往往只会影响对少数实例的预测,而对其余实例的贡献则可以忽略不计。添加dropout会使树在以后的迭代中更加难以专门化那些少数的示例,从而提高性能。

它的原理是随机丢弃生成的决策树,然后再从剩下的决策树集中迭代优化提升树。它的特点是

  • 训练慢:因为随机dropout不使用用于保存预测结果的buffer,所以训练会更慢。
  • 随机导致不稳定:因为随机,早停可能不够稳定。

dart与gbdt的不同点:计算下一棵树要拟合的梯度的时,仅仅随机从已经生成的树中选取一部分。

注意dart添加一棵树时需要先归一化。

(3)、goss :基于梯度的单边采样,该方法命名为lightgbm的最重要原因就是其使用了基于Goss方法。goss的基本思想是首先对训练集数据根据梯度排序,预设一个比例划分梯度大小,保留在所有样本中梯度大的数据样本;再设置一个采样比例,从梯度小的样本中按比例抽取样本。为了弥补对样本分布造成的影响,goss算法在计算信息增益时,会对较小梯度的数据集乘以一个系数,用来放大。这样,在计算信息增益时,算法可以更加关注“未被充分训练”的样本数据。         goss通过对较小的样本数据集估算增益,大大的减少了计算量。而且通过证明,goss算法不会过多的降低训练的精度。

标准的gbdt是可靠的,但在大型数据集上速度不够快。因此goss提出了一种基于梯度的采样方法来避免搜索整个搜索空间。其实,对于每个数据实例,当梯度很小时,这意味着不用担心数据是经过良好训练的,而当梯度很大时,应该重新训练。数据实例有大的和小的渐变。因此,goss以一个大的梯度保存所有数据,并对一个小梯度的数据进行随机抽样(这就是为什么它被称为单边抽样)。这使得搜索空间更小,goss的收敛速度更快。

(4)、rf :随机森林。切记,如果将增强设置为rf,那么lightgbm算法表现为随机森林而不是增强树。根据文档可知,要使用rf,必须使用bagging_fraction和feature_fraction小于1。

objective ='binary'

目标,"regression"、"binary"

metric='binary_logloss'

模型度量标准,"rmse"、"auc"、'binary_logloss'

learning_rate=0.1

学习率

n_estimators=10

拟合的树的棵树,可以理解为训练的轮数。

弱学习器的个数,其中gbdt原理是利用通过梯度不断拟合新的弱学习器,直到达到设定的弱学习器的数量。

max_depth=-1

最大树的深度。每个弱学习器也就是决策树的最大深度。

其中,-1表示不限制。

num_leavel=32

树的最大叶子数,控制模型复杂性的最重要参数之一。对比在xgboost中,一般为2^(max_depth)

因LightGBM使用的是leaf-wise的算法,因此在调节树的复杂程度时,使用的是num_leaves而不是max_depth。它们之间大致换算关系:num_leaves = 2^(max_depth)。即它的值的设置应该小于2^(max_depth),否则会进行警告,可能会导致过拟合。

bagging_freq=15

控制过拟合。

bagging_fraction= 0.8

子样例,来控制过拟合。

可以指定每个树构建迭代使用的行数百分比。这意味着将随机选择一些行来匹配每个学习者(树)。这不仅提高了泛化能力,也提高了训练速度。

feature_fraction=0.8

子特征处理列采样,来控制过拟合。

它将在每次迭代(树)上随机选择特征子集。例如,如果将其设置为0.8,它将在训练每棵树之前选择60%的特性。它常用来加速训练和处理过拟合。

subsample=1.0

训练样本采样率,行

colsample_bytree=1.0 

训练特征采样率,列

subsample_freq=1

子样本频率

reg_alpha=0.5

L1正则化系数

reg_lambda=0.5

L2正则化系数

min_split_gain=0.0

最小分割增益

min_child_weight=0.001 

分支结点的最小权重

min_child_samples=20

 

random_state=None

随机种子数

n_jobs=-1

并行运行多线程核心数

silent=True

训练过程是否打印日志信息

verbose=-1

 

 

2、具体函数解释

class LGBMClassifier Found at: lightgbm.sklearn

 

class LGBMClassifier(LGBMModel, _LGBMClassifierBase):

    """LightGBM classifier."""

    def fit(self, X, y,

        sample_weight=None, init_score=None,

        eval_set=None, eval_names=None, eval_sample_weight=None,

        eval_class_weight=None, eval_init_score=None, eval_metric=None,

        early_stopping_rounds=None, verbose=True,

        feature_name='auto', categorical_feature='auto', callbacks=None):

        """Docstring is inherited from the LGBMModel."""

        _LGBMAssertAllFinite(y)

        _LGBMCheckClassificationTargets(y)

        self._le = _LGBMLabelEncoder().fit(y)

        _y = self._le.transform(y)

        self._classes = self._le.classes_

        self._n_classes = len(self._classes)

        if self._n_classes > 2:

        # Switch to using a multiclass objective in the underlying LGBM

         instance

            ova_aliases = "multiclassova", "multiclass_ova", "ova", "ovr"

            if self._objective not in ova_aliases and not callable(self.

             _objective):

                self._objective = "multiclass"

            if eval_metric in ('logloss', 'binary_logloss'):

                eval_metric = "multi_logloss"

            elif eval_metric in ('error', 'binary_error'):

                eval_metric = "multi_error"

        elif eval_metric in ('logloss', 'multi_logloss'):

            eval_metric = 'binary_logloss'

        elif eval_metric in ('error', 'multi_error'):

            eval_metric = 'binary_error'

        if eval_set is not None:

            if isinstance(eval_set, tuple):

                eval_set = [eval_set]

            for i, (valid_x, valid_y) in enumerate(eval_set):

                if valid_x is X and valid_y is y:

                    eval_set[i] = valid_x, _y

                else:

                    eval_set[i] = valid_x, self._le.transform(valid_y)

        

        super(LGBMClassifier, self).fit(X, _y, sample_weight=sample_weight,

         init_score=init_score, eval_set=eval_set, eval_names=eval_names,

         eval_sample_weight=eval_sample_weight,

         eval_class_weight=eval_class_weight, eval_init_score=eval_init_score,

         eval_metric=eval_metric,

         early_stopping_rounds=early_stopping_rounds, verbose=verbose,

         feature_name=feature_name, categorical_feature=categorical_feature,

         callbacks=callbacks)

        return self

    

    fit.__doc__ = LGBMModel.fit.__doc__

    def predict(self, X, raw_score=False, num_iteration=None,

        pred_leaf=False, pred_contrib=False, **kwargs):

        """Docstring is inherited from the LGBMModel."""

        result = self.predict_proba(X, raw_score, num_iteration,

            pred_leaf, pred_contrib, **kwargs)

        if raw_score or pred_leaf or pred_contrib:

            return result

        else:

            class_index = np.argmax(result, axis=1)

            return self._le.inverse_transform(class_index)

    

    predict.__doc__ = LGBMModel.predict.__doc__

    def predict_proba(self, X, raw_score=False, num_iteration=None,

        pred_leaf=False, pred_contrib=False, **kwargs):

        """Return the predicted probability for each class for each sample. 返回每个类和每个样本的预测概率。

 

        Parameters

        ----------

        X : array-like or sparse matrix of shape = [n_samples, n_features] Input features matrix.

        raw_score : bool, optional (default=False). Whether to predict raw scores.

        num_iteration : int or None, optional (default=None). Limit number of iterations in the prediction. If None, if the best iteration exists, it is used; otherwise, all trees are used.  If <= 0, all trees are used (no limits).

        pred_leaf : bool, optional (default=False). Whether to predict leaf index.

        pred_contrib : bool, optional (default=False). Whether to predict feature contributions.

            Note

            ----

            If you want to get more explanation for your model's predictions using SHAP values like SHAP interaction values, you can install shap package (https://github.com/slundberg/shap).

 

        **kwargs

            Other parameters for the prediction.

        Returns

        -------

        predicted_probability : array-like of shape = [n_samples, n_classes]. The predicted probability for each class for each sample.

        X_leaves : array-like of shape = [n_samples, n_trees * n_classes]. If ``pred_leaf=True``, the predicted leaf every tree for each sample.

        X_SHAP_values : array-like of shape = [n_samples, (n_features + 1) *n_classes]. If ``pred_contrib=True``, the each feature contributions for each sample.

        """

        result = super(LGBMClassifier, self).predict(X, raw_score, num_iteration, pred_leaf, pred_contrib, **kwargs). if self._n_classes > 2 or pred_leaf or pred_contrib:

            return result

        else:

            return np.vstack((1. - result, result)).transpose()

参数

----------

X: 类数组形状或稀疏矩阵= [n_samples, n_features]输入特征矩阵。

raw_score : bool,可选(默认=False)。是否预测原始分数。

num_iteration:  int或None,可选(默认=None)。预测中的极限迭代次数。如果没有,如果存在最好的迭代,就使用它;否则,使用所有树。如果<= 0,则使用所有树(没有限制)。

pred_leaf:  bool,可选(默认=False)。是否预测叶指数。

pred_contrib:  bool,可选(默认=False)。是否预测特性贡献。

请注意

----

如果您想使用SHAP值(如SHAP交互值)对模型的预测进行更多的解释,您可以安装SHAP包(https://github.com/slundberg/shap)。

 

* * kwargs

用于预测的其他参数。

返回

-------

predicted_probability : 类数组形状= [n_samples, n_classes]。每个类,每个样本的预测概率。

X_leaves: 类数组的形状= [n_samples, n_trees * n_classes]。如果' ' pred_leaf=True ' ',则为每个样本的每棵树预测的叶。

X_SHAP_values: 类数组形状= [n_samples, (n_features + 1) *n_classes]。如果' ' pred_contrib=True ' ',则每个特性为每个示例贡献。

 

"""

        result = super(LGBMClassifier, self).predict(X, raw_score, num_iteration, pred_leaf, pred_contrib, **kwargs). if self._n_classes > 2 or pred_leaf or pred_contrib:

            return result

        else:

            return np.vstack((1. - result, result)).transpose()

       @property

    def classes_(self):

        """Get the class label array."""

        if self._classes is None:

            raise LGBMNotFittedError('No classes found. Need to call fit

             beforehand.')

        return self._classes

    

    @property

    def n_classes_(self):

        """Get the number of classes."""

        if self._n_classes is None:

            raise LGBMNotFittedError('No classes found. Need to call fit

             beforehand.')

        return self._n_classes

 

 

 

 

 

 

 

 

 

 

 

 

文章来源: yunyaniu.blog.csdn.net,作者:一个处女座的程序猿,版权归原作者所有,如需转载,请联系作者。

原文链接:yunyaniu.blog.csdn.net/article/details/109252743

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。