目录
2.1、以Scikit-learn API 风格 的 LGBMRegressor 为例
0、资料
0.1、知识脑图
脑图链接:决策树家族脑图
0.2、决策树PDF资料
决策树PDF资料链接:决策树PDF资料
一、知识结构
1.1、理解GBDT 与 梯度下降的原理
梯度提升(Gradient Boosting)算法 、深入理解XGBoost
理解过程:泰勒公式 ===> 梯度下降&牛顿法 ====> GBDT ====> Xgboost =====> lighgbm
二、lightgbm 中sklearn API风格代码案例
2.1、以Scikit-learn API 风格 的 LGBMRegressor 为例
2.1.1、Lightgbm 参数解释
# Scikit-learn API
class lightgbm.LGBMRegressor(boosting_type='gbdt', num_leaves=31, max_depth=-1,
learning_rate=0.1, n_estimators=10, max_bin=255, subsample_for_bin=200000, objective=None,
min_split_gain=0.0, min_child_weight=0.001, min_child_samples=20, subsample=1.0,
subsample_freq=1, colsample_bytree=1.0, reg_alpha=0.0, reg_lambda=0.0, random_state=None,
n_jobs=-1, silent=True, **kwargs)
boosting_type (string__, optional (default="gbdt")) – ‘gbdt’, traditional Gradient Boosting Decision Tree. ‘dart’, Dropouts meet Multiple Additive Regression Trees. ‘goss’, Gradient-based One-Side Sampling. ‘rf’, Random Forest.
默认的就挺好
1. 参数介绍
num_leaves (int__, optional (default=31)) – Maximum tree leaves for base learners.
每个基学习器的最大叶子节点。LightGBM 使用的是 leaf-wise 的算法,因此在调节树的复杂程度时使用的是 num_leaves,它的值的设置应该小于 2^(max_depth)
max_depth (int__, optional (default=-1)) – Maximum tree depth for base learners, -1 means no limit.
每个基学习器的最大深度。当模型过拟合,首先降低max_depth
learning_rate (float__, optional (default=0.1)) – Boosting learning rate.
梯度下降的步长。常用 0.1, 0.001, 0.003
n_estimators (int__, optional (default=10)) – Number of boosted trees to fit.
基学习器的数量
max_bin (int__, optional (default=255)) – Number of bucketed bins for feature values.
存储feature的bin的最大数量,对应的是直方图的组数k
subsample_for_bin (int__, optional (default=50000)) – Number of samples for constructing bins.
用来构建直方图的数据的样本数量
objective (string__, callable or None__, optional (default=None)) – Specify the learning task and the corresponding learning objective or a custom objective function to be used (see note below). default: ‘regression’ for LGBMRegressor, ‘binary’ or ‘multiclass’ for LGBMClassifier, ‘lambdarank’ for LGBMRanker.
min_split_gain(= min_gain_to_split) (float__, optional (default=0.)) – Minimum loss reduction required to make a further partition on a leaf node of the tree.
最小切分的信息增益值
min_child_weight(= min_sum_hessian_in_leaf) (float__, optional (default=1e-3)) – Minimum sum of instance weight(hessian) needed in a child(leaf).
决定最小叶子节点样本权重和(hessian)的最小阈值,若是基学习器切分后得到的叶节点中样本权重和低于该阈值则不会进一步切分,在线性模型中该阈值就对应每个节点的最小样本数。当它的值较大时,可以避免模型学习到局部的特殊样本,防止模型过拟合。但如果这个值过高,又会导致欠拟合
min_child_samples(= min_data_in_leaf) (int__, optional (default=20)) – Minimum number of data need in a child(leaf).
一个叶子节点中最小的数据量,调大可以防止过拟合
subsample (= bagging_fraction)(float__, optional (default=1.)) – Subsample ratio of the training instance.
这个参数控制对于每棵树,在非重复采样的情况下随机采样的比例。减小这个参数的值算法会更加保守,避免过拟合,加快运算速度。但是这个值设置的过小,它可能会导致欠拟合
subsample_freq(= bagging_freq) (int__, optional (default=1)) – Frequence of subsample, <=0 means no enable.
bagging 的频率, 0 意味着禁用 bagging. k 意味着每 k 次迭代执行bagging
colsample_bytree(= feature_fraction) (float__, optional (default=1.)) – Subsample ratio of columns when constructing each tree.
用来控制每棵随机采样的列数的占比(每一列是一个特征)。 调小可以防止过拟合,加快运算速度。典型值:0.5-1范围: (0,1]。一般设置成0.8左右。
reg_alpha(= lambda_l1)(float__, optional (default=0.)) – L1 regularization term on weights.
L1 正则化项的权重系数,越大模型越保守。防止过拟合,提高泛化能力
reg_lambda(= lambda_l2) (float__, optional (default=0.)) – L2 regularization term on weights.
L2 正则化项的权重系数,越大模型越保守。防止过拟合,提高泛化能力
random_state (int or None__, optional (default=None)) – Random number seed. Will use default seeds in c++ code if set to None.
计算机不能产生绝对的随机数,只能产生伪随机数。伪就是有规律的意思。如果每次使用一样的 随机种子,生成的随机数列就是一样的了
n_jobs (int__, optional (default=-1)) – Number of parallel threads.
多线程,表示可以在机器的多个核上并行的构造树以及计算预测值。不过受限于通信成本,可能效率并不会说分为k个线程就得到k倍的提升,不过整体而言相对需要构造大量的树或者构建一棵复杂的树而言还是高效的
silent (bool__, optional (default=True)) – Whether to print messages while running boosting.
在运行过程中是否打印流程
2.1.2、Lightgbm代码
from lightgbm import LGBMClassifier
from sklearn.datasets import load_iris
from lightgbm import plot_importance
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score,f1_score,precision_score,recall_score
# 加载鸢尾花数据集
iris_obj = load_iris()
x,y = iris_obj.data,iris_obj.target
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=1440)
# lightgbm模型
model = LGBMClassifier(boosting_type='gbdt', # 默认使用"树模型"作为子学习器,默认即可
num_leaves=31, # 子学习器最大的叶子节点的个数
max_depth=15, # 子学习器树模型的深度,默认不对树模型的深度进行限制
learning_rate=0.05, # 子学习器的学习率(较小的学习率需要有更大的子学习器的数量来弥补)
n_estimators=1000, # 子学习器的数目
subsample_for_bin=200000, # 用来构建直方图的数据的样本数量
objective='multiclass', # 默认 'regression' for LGBMRegressor, 'binary' or 'multiclass' for LGBMClassifier, 'lambdarank' for LGBMRanker
class_weight=None, # 默认即可,用于对于训练时样本集每个类别不均衡时类别样本的权重
min_split_gain=1e-4, # 损失函数至少减小多少值才进行树分裂
min_child_weight=2, # 所有子树节点之和需要小于该值
min_child_samples=20, # 叶子节点的最小的样本数,可以防止过拟合
subsample=1., # 这个参数控制对于每棵树,在非重复采样的情况下随机采样的比例。减小这个参数的值算法会更加保守,避免过拟合,加快运算速度。但是这个值设置的过小,它可能会导致欠拟合
subsample_freq=0, # bagging 的频率, 0 意味着禁用 bagging. k 意味着每 k 次迭代执行bagging
colsample_bytree=1., # 特征抽样选取的比例
reg_alpha=1., # l1 正则的权重系数,越大模型越保守
reg_lambda=5., # l2 正则的权重系数,越大模型越保守
random_state=1440, # 随机数种子
n_jobs=-1, # 线程进程数
silent=True, # 是否在运行过程中打印流程
importance_type='split')
# 训练
model.fit(x_train, # array, DataFrame 类型
y_train, # array, Series 类型
eval_set=[(x_train, y_train), (x_test, y_test)], # 用于评估的数据集,例如:[(X_train, y_train), (X_test, y_test)]
eval_metric=None, # 评估函数,字符串类型,例如:'l2', 'logloss'
early_stopping_rounds=100, # 连续多少次迭代后模型的效果没有提升停止训练
verbose=100 # 设置为正整数表示间隔多少次迭代输出一次信息
)
# 模型进行预测
y_train_pre = model.predict(x_train)
y_pre = model.predict(x_test)
y_pre_prob = model.predict_proba(x_test)
print(y_pre)
print(y_pre_prob)
# 分值
test_acc = accuracy_score(y_true=y_test,y_pred=y_pre)
print(test_acc)
train_acc = accuracy_score(y_true=y_train,y_pred=y_train_pre)
print(train_acc)
# 特征重要性
plot_importance(model)
plt.show()
2.1.3、Lightgbm调参策略
2.官方参数优化建议:针对 Leaf-wise (最佳优先) 树的参数优化
2.1 num_leaves. 这是控制树模型复杂度的主要参数. 理论上, 借鉴 depth-wise 树, 我们可以设置 num_leaves = 2^(max_depth) 但是, 这种简单的转化在实际应用中表现不佳. 这是因为, 当叶子数目相同时, leaf-wise 树要比 depth-wise 树深得多, 这就有可能导致过拟合. 因此, 当我们试着调整 num_leaves 的取值时, 应该让其小于 2^(max_depth). 举个例子, 当 max_depth=6 时(这里译者认为例子中, 树的最大深度应为7), depth-wise 树可以达到较高的准确率.但是如果设置 num_leaves 为 127 时, 有可能会导致过拟合, 而将其设置为 70 或 80 时可能会得到比 depth-wise 树更高的准确率. 其实, depth 的概念在 leaf-wise 树中并没有多大作用, 因为并不存在一个从 leaves 到 depth 的合理映射.
2.2 min_child_samples(min_data_in_leaf). 这是处理 leaf-wise 树的过拟合问题中一个非常重要的参数. 它的值取决于训练数据的样本个树和 num_leaves. 将其设置的较大可以避免生成一个过深的树, 但有可能导致欠拟合. 实际应用中, 对于大数据集, 设置其为几百或几千就足够了.
2.3 max_depth. 你也可以利用 max_depth 来显式地限制树的深度
3. 针对更快的训练速度:
3.1 通过设置 subsample(bagging_fraction) 和 subsample_freq(= bagging_freq) 参数来使用 bagging 方法进行采样提升训练速度(减小了数据集)
3.2 通过设置 colsample_bytree(= feature_fraction)参数来使用特征的子抽样
使用较小的 max_bin,较少的直方图数目
3.3 使用 save_binary 将数据集被保存为二进制文件,下次加载数据时速度会变快
通过并行训练来提速
4.针对更好的准确率:
4.1 使用较大的直方图数目 max_bin,这样会牺牲训练速度
4.2 使用较小的学习率 learning_rate,这样会增加迭代次数
4.3 使用较大的 num_leaves,可能导致过拟合
4.4 使用更大的训练数据
4.5 尝试 dart 模型(Dropouts meet Multiple Additive Regression Trees)
5.处理过拟合:
5.1 设置较少的直方图数目 max_bin
5.2 设置较小的叶节点数 num_leaves
5.3 使用 min_child_samples(min_data_in_leaf) 和 min_child_weight(= min_sum_hessian_in_leaf)
5.4 通过设置 subsample(bagging_fraction) 和 subsample_freq(= bagging_freq)来使用 bagging
5.5 通过设置 colsample_bytree(feature_fraction) 来使用特征子抽样
使用更大的训练数据
5.6 使用 reg_alpha(lambda_l1), reg_lambda(lambda_l2) 和 min_split_gain(min_gain_to_split) 来使用正则
5.7 尝试 max_depth 来避免生成过深的树