LightGBM调参

article/2025/10/20 9:43:08

GBDT模型的另一个进化版本:LightGBM。LigthGBM是boosting集合模型中的新进成员,由微软提供,它和XGBoost一样是对GBDT的高效实现,原理上它和GBDT及XGBoost类似,都采用损失函数的负梯度作为当前决策树的残差近似值,去拟合新的决策树。

LightGBM在很多方面会比XGBoost表现的更为优秀。它有以下优势:

  • 更快的训练效率
  • 低内存使用
  • 更高的准确率
  • 支持并行化学习
  • 可处理大规模数据
  • 支持直接使用category特征

从下图实验数据可以看出, LightGBM比XGBoost快将近10倍,内存占用率大约为XGBoost的1/6,并且准确率也有提升。

好用归好用,关于这个东西的调参一直让我很伤脑筋,首先是它的参数好多,源码里好像不全,好像一些参数的意义相同但是有好几个名字,等等等等,很怪。

源码中的一些参数

Parameters----------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.num_leaves : int, optional (default=31)Maximum tree leaves for base learners.max_depth : int, optional (default=-1)Maximum tree depth for base learners, <=0 means no limit.learning_rate : float, optional (default=0.1)Boosting learning rate.You can use ``callbacks`` parameter of ``fit`` method to shrink/adapt learning ratein training using ``reset_parameter`` callback.Note, that this will ignore the ``learning_rate`` argument in training.n_estimators : int, optional (default=100)Number of boosted trees to fit.subsample_for_bin : int, optional (default=200000)Number of samples for constructing bins.objective : string, callable or None, optional (default=None)Specify the learning task and the corresponding learning objective ora custom objective function to be used (see note below).Default: 'regression' for LGBMRegressor, 'binary' or 'multiclass' for LGBMClassifier, 'lambdarank' for LGBMRanker.class_weight : dict, 'balanced' or None, optional (default=None)Weights associated with classes in the form ``{class_label: weight}``.Use this parameter only for multi-class classification task;for binary classification task you may use ``is_unbalance`` or ``scale_pos_weight`` parameters.Note, that the usage of all these parameters will result in poor estimates of the individual class probabilities.You may want to consider performing probability calibration(https://scikit-learn.org/stable/modules/calibration.html) of your model.The 'balanced' mode uses the values of y to automatically adjust weightsinversely proportional to class frequencies in the input data as ``n_samples / (n_classes * np.bincount(y))``.If None, all classes are supposed to have weight one.Note, that these weights will be multiplied with ``sample_weight`` (passed through the ``fit`` method)if ``sample_weight`` is specified.min_split_gain : float, optional (default=0.)Minimum loss reduction required to make a further partition on a leaf node of the tree.min_child_weight : float, optional (default=1e-3)Minimum sum of instance weight (hessian) needed in a child (leaf).min_child_samples : int, optional (default=20)Minimum number of data needed in a child (leaf).subsample : float, optional (default=1.)Subsample ratio of the training instance.subsample_freq : int, optional (default=0)Frequence of subsample, <=0 means no enable.colsample_bytree : float, optional (default=1.)Subsample ratio of columns when constructing each tree.reg_alpha : float, optional (default=0.)L1 regularization term on weights.reg_lambda : float, optional (default=0.)L2 regularization term on weights.random_state : int or None, optional (default=None)Random number seed.If None, default seeds in C++ code will be used.n_jobs : int, optional (default=-1)Number of parallel threads.silent : bool, optional (default=True)Whether to print messages while running boosting.importance_type : string, optional (default='split')The type of feature importance to be filled into ``feature_importances_``.If 'split', result contains numbers of times the feature is used in a model.If 'gain', result contains total gains of splits which use the feature.**kwargsOther parameters for the model.Check http://lightgbm.readthedocs.io/en/latest/Parameters.html for more parameters... warning::\*\*kwargs is not supported in sklearn, it may cause unexpected issues.Attributes----------n_features_ : intThe number of features of fitted model.classes_ : array of shape = [n_classes]The class label array (only for classification problem).n_classes_ : intThe number of classes (only for classification problem).best_score_ : dict or NoneThe best score of fitted model.best_iteration_ : int or NoneThe best iteration of fitted model if ``early_stopping_rounds`` has been specified.objective_ : string or callableThe concrete objective used while fitting this model.booster_ : BoosterThe underlying Booster of this model.evals_result_ : dict or NoneThe evaluation results if ``early_stopping_rounds`` has been specified.feature_importances_ : array of shape = [n_features]The feature importances (the higher, the more important the feature).Note----A custom objective function can be provided for the ``objective`` parameter.In this case, it should have the signature``objective(y_true, y_pred) -> grad, hess`` or``objective(y_true, y_pred, group) -> grad, hess``:y_true : array-like of shape = [n_samples]The target values.y_pred : array-like of shape = [n_samples] or shape = [n_samples * n_classes] (for multi-class task)The predicted values.group : array-likeGroup/query data, used for ranking task.grad : array-like of shape = [n_samples] or shape = [n_samples * n_classes] (for multi-class task)The value of the first order derivative (gradient) for each sample point.hess : array-like of shape = [n_samples] or shape = [n_samples * n_classes] (for multi-class task)The value of the second order derivative (Hessian) for each sample point.For multi-class task, the y_pred is group by class_id first, then group by row_id.If you want to get i-th row y_pred in j-th class, the access way is y_pred[j * num_data + i]and you should group grad and hess in this way as well."""

里面的参数都是比较常见的,但是上网搜了很多调参的参数里面都没有,我意识到事情没有这么简单,我又搜集了好多网站,终于找到了一个我认为参数比较全的。(机器学习算法之LightGBM – 标点符)

LightGBM调参指导
针对 leaf-wise 树的参数优化:num_leaves:控制了叶节点的数目。它是控制树模型复杂度的主要参数。
如果是level-wise,则该参数为2^{depth},其中depth为树的深度。但是当叶子数量相同时,leaf-wise的树要远远深过level-wise树,非常容易导致过拟合。因此应该让num_leaves小于2^{depth}。在leaf-wise树中,并不存在depth的概念。因为不存在一个从leaves到depth的合理映射。
min_data_in_leaf:每个叶节点的最少样本数量。它是处理leaf-wise树的过拟合的重要参数。将它设为较大的值,可以避免生成一个过深的树。但是也可能导致欠拟合。
max_depth: 控制了树的最大深度。该参数可以显式的限制树的深度。
针对更快的训练速度:通过设置 bagging_fraction 和 bagging_freq 参数来使用 bagging 方法
通过设置 feature_fraction 参数来使用特征的子抽样
使用较小的 max_bin
使用 save_binary 在未来的学习过程对数据加载进行加速
获取更好的准确率:使用较大的 max_bin (学习速度可能变慢)
使用较小的 learning_rate 和较大的 num_iterations
使用较大的 num_leaves (可能导致过拟合)
使用更大的训练数据
尝试 dart
缓解过拟合:使用较小的 max_bin
使用较小的 num_leaves
使用 min_data_in_leaf 和 min_sum_hessian_in_leaf
通过设置 bagging_fraction 和 bagging_freq 来使用 bagging
通过设置 feature_fraction 来使用特征子抽样
使用更大的训练数据
使用 lambda_l1, lambda_l2 和 min_gain_to_split 来使用正则
尝试 max_depth 来避免生成过深的树
核心参数:config 或者config_file:一个字符串,给出了配置文件的路径。默认为空字符串。
task: 一个字符串,给出了要执行的任务。可以为:
‘train’ 或者 ‘training’:表示是训练任务。默认为’train’。
‘predict’ 或者 ‘prediction’或者’test’:表示是预测任务。
‘convert_model’: 表示是模型转换任务。将模型文件转换成if-else 格式。
application或者objective或者app:一个字符串,表示问题类型。可以为:
‘regression’或’regression_l2’或’mean_squared_error’或’mse’或’l2_root’或’root_mean_squred_error’或’rmse’:表示回归任务,但是使用L2损失函数。默认为’regression’
‘regression_l1’或者mae或者mean_absolute_error:表示回归任务,但是使用L1损失函数。
‘huber’: 表示回归任务,但是使用huber 损失函数。
‘fair’: 表示回归任务,但是使用fair 损失函数。
‘poisson’: 表示Poisson 回归任务。
‘quantile’: 表示quantile回归任务。
‘quantile_l2’:表示quantile回归任务,但是使用了L2 损失函数。
‘mape’ 或者’mean_absolute_precentage_error’: 表示回归任务,但是使用MAPE 损失函数
‘gamma’: 表示gamma 回归任务。
‘tweedie’: 表示tweedie 回归任务。
‘binary’: 表示二分类任务,使用对数损失函数作为目标函数。
‘multiclass’: 表示多分类任务,使用softmax 函数作为目标函数。必须设置num_class 参数
‘multiclassova’ 或者’multiclass_ova’ 或者’ova’ 或者’ovr’: 表示多分类任务,使用one-vs-all 的二分类目标函数。必须设置num_class 参数
‘xentropy’ 或者’cross_entropy’: 目标函数为交叉熵(同时具有可选择的线性权重)。要求标签是[0,1] 之间的数值。
‘xentlambda’ 或者’cross_entropy_lambda’: 替代了参数化的cross_entropy 。要求标签是[0,1]之间的数值。
‘lambdarank’:表示排序任务。在lambdarank 任务中,标签应该为整数类型,数值越大表示相关性越高。label_gain 参数可以用于设置整数标签的增益(权重)
boosting 或者’boost’ 或者 ‘boosting_type’: 一个字符串,给出了基学习器模型算法。可以为:
‘gbdt’: 表示传统的梯度提升决策树。默认值为’gbdt’
‘rf’: 表示随机森林。
‘dart’: 表示带dropout 的gbdt
goss:表示Gradient-based One-Side Sampling 的gbdt
data或者train或者train_data:一个字符串,给出了训练数据所在的文件的文件名。默认为空字符串。lightgbm将使用它来训练模型。
valid或者test或者valid_data或者test_data:一个字符串,表示验证集所在的文件的文件名。默认为空字符串。lightgbm将输出该数据集的度量。如果有多个验证集,则用逗号分隔。
num_iterations或者num_iteration或者num_tree或者num_trees或者num_round或者num_rounds或者num_boost_round 一个整数,给出了boosting的迭代次数。默认为 100。
对于python/R包,该参数是被忽略的。对于python,使用train()/cv()的输入参数num_boost_round来代替。
在内部,lightgbm对于multiclass 问题设置了num_class*num_iterations 棵树。
learning_rate或者shrinkage_rate: 个浮点数,给出了学习率。默认为1。在dart 中,它还会影响dropped trees 的归一化权重。
num_leaves或者num_leaf:一个整数,给出了一棵树上的叶子数。默认为 31
tree_learner或者tree:一个字符串,给出了tree learner,主要用于并行学习。 默认为’serial’。 可以为:
‘serial’: 单台机器的tree learner
‘feature’: 特征并行的tree learner
‘data’: 数据并行的tree learner
‘voting’: 投票并行的tree learner
num_threads 或者num_thread 或者nthread:一个整数, 给出了lightgbm 的线程数。默认为OpenMP_default。
为了更快的速度,应该将它设置为真正的CPU 内核数,而不是线程的数量(大多数CPU 使用超线程来使每个CPU内核生成2个线程)。
当数据集较小的时候,不要将它设置的过大
对于并行学习,不应该使用全部的CPU核心,因为这会使得网络性能不佳
device: 一个字符串,指定计算设备。默认为’cpu’。 可以为’gpu’,’cpu’。
建议使用较小的max_bin 来获得更快的计算速度
为了加快学习速度,GPU 默认使用32位浮点数来求和。你可以设置gpu_use_dp=True 来启动64位浮点数,但是它会使得训练速度降低。
学习控制参数:max_depth: 一个整数,限制了树模型的最大深度,默认值为-1。如果小于0,则表示没有限制。
min_data_in_leaf 或者 min_data_per_leaf 或者 min_data或者min_child_samples: 一个整数,表示一个叶子节点上包含的最少样本数量。默认值为 20
min_sum_hessian_in_leaf 或者 min_sum_hessian_per_leaf或者 min_sum_hessian 或者 min_hessian或者min_child_weight: 一个浮点数,表示一个叶子节点上的最小hessian 之和。(也就是叶节点样本权重之和的最小值) 默认为1e-3 。
feature_fraction或者sub_feature或者colsample_bytree:一个浮点数,取值范围为[0.0,1.0], 默认值为0。如果小于1.0,则lightgbm 会在每次迭代中随机选择部分特征。如0.8 表示:在每棵树训练之前选择80% 的特征来训练。
feature_fraction_seed: 一个整数,表示feature_fraction 的随机数种子,默认为2。
bagging_fraction 或者sub_row 或者 subsample:一个浮点数,取值范围为[0.0,1.0], 默认值为0。如果小于1.0,则lightgbm 会在每次迭代中随机选择部分样本来训练(非重复采样)。如0.8 表示:在每棵树训练之前选择80% 的样本(非重复采样)来训练。
bagging_freq 或者subsample_freq:一个整数,表示每bagging_freq 次执行bagging。如果该参数为0,表示禁用bagging。
bagging_seed 或者 bagging_fraction_seed:一个整数,表示bagging 的随机数种子,默认为 3 。
early_stopping_round 或者 early_stopping_rounds或者early_stopping:一个整数,默认为0。如果一个验证集的度量在early_stopping_round 循环中没有提升,则停止训练。如果为0则表示不开启早停。
lambda_l1 或者reg_alpha: 一个浮点数,表示L1正则化系数。默认为0
lambda_l2 或者reg_lambda: 一个浮点数,表示L2正则化系数。默认为0
min_split_gain 或者min_gain_to_split: 一个浮点数,表示执行切分的最小增益,默认为0
drop_rate: 一个浮点数,取值范围为[0.0,1.0],表示dropout 的比例,默认为1。 该参数仅在dart 中使用
skip_drop: 一个浮点数,取值范围为[0.0,1.0],表示跳过dropout 的概率,默认为5。 该参数仅在dart 中使用
max_drop: 一个整数,表示一次迭代中删除树的最大数量,默认为50。 如果小于等于0,则表示没有限制。 该参数仅在dart 中使用
uniform_drop:一个布尔值,表示是否想要均匀的删除树,默认值为False。 该参数仅在dart 中使用
xgboost_dart_mode: 一个布尔值,表示是否使用xgboost dart 模式,默认值为False。该参数仅在dart 中使用
drop_seed: 一个整数,表示dropout 的随机数种子,默认值为 4。 该参数仅在dart 中使用
top_rate: 一个浮点数,取值范围为[0.0,1.0],表示在goss 中,大梯度数据的保留比例,默认值为2。该参数仅在goss 中使用
other_rate: 一个浮点数,取值范围为[0.0,1.0],表示在goss 中,小梯度数据的保留比例,默认值为1。该参数仅在goss 中使用
min_data_per_group:一个整数,表示每个分类组的最小数据量,默认值为100。用于排序任务
max_cat_threshold: 一个整数,表示category 特征的取值集合的最大大小。默认为 32 。
cat_smooth: 一个浮点数,用于category 特征的概率平滑。默认值为 10。它可以降低噪声在category 特征中的影响,尤其是对于数据很少的类。
cat_l2: 一个浮点数,用于category 切分中的L2 正则化系数。默认为 10 。
top_k 或者 topk: 一个整数,用于投票并行中。默认为20 。将它设置为更大的值可以获得更精确的结果,但是会降低训练速度。
IO 参数:max_bin: 一个整数,表示最大的桶的数量。默认值为 255。lightgbm 会根据它来自动压缩内存。如max_bin=255 时,则lightgbm 将使用uint8 来表示特征的每一个值。
min_data_in_bin: 一个整数,表示每个桶的最小样本数。默认为3。该方法可以避免出现一个桶只有一个样本的情况。
data_random_seed: 一个整数,表示并行学习数据分隔中的随机数种子。默认为1它不包括特征并行。
output_model或者model_output或者model_out: 一个字符串,表示训练中输出的模型被保存的文件的文件名。默认txt 。
input_model或者model_input或者model_in: 一个字符串,表示输入模型的文件的文件名。默认空字符串。对于prediction任务,该模型将用于预测数据,对于train任务,训练将从该模型继续
output_result或者 predict_result或者prediction_result:一个字符串,给出了prediction 结果存放的文件名。默认为txt。
pre_partition 或者 is_pre_partition: 一个布尔值,指示数据是否已经被划分。默认值为False。 如果为true,则不同的机器使用不同的partition 来训练。它用于并行学习(不包括特征并行)
is_sparse或者 is_enable_sparse或者enable_sparse: 一个布尔值,表示是否开启稀疏优化,默认为True。如果为True则启用稀疏优化。
two_round 或者two_round_loading或者 use_two_round_loading: 一个布尔值,指示是否启动两次加载。默认值为False,表示只需要进行一次加载。默认情况下,lightgbm 会将数据文件映射到内存,然后从内存加载特征,这将提供更快的数据加载速度。但是当数据文件很大时,内存可能会被耗尽。如果数据文件太大,则将它设置为True
save_binary或者is_save_binary或者 is_save_binary_file: 一个布尔值,表示是否将数据集(包括验证集)保存到二进制文件中。默认值为False。如果为True,则可以加快数据的加载速度。
verbosity 或者verbose:一个整数,表示是否输出中间信息。默认值为1。如果小于0,则仅仅输出critical 信息;如果等于0,则还会输出error,warning 信息; 如果大于0,则还会输出info 信息。
header或者has_header:一个布尔值,表示输入数据是否有头部。默认为False。
label 或者label_column:一个字符串,表示标签列。默认为空字符串。你也可以指定一个整数,如label=0 表示第0列是标签列。你也可以为列名添加前缀,如label=prefix:label_name
weight 或者weight_column: 一个字符串,表示样本权重列。默认为空字符串。你也可以指定一个整数,如weight=0 表示第0列是权重列。注意:它是剔除了标签列之后的索引。假如标签列为0,权重列为1,则这里weight=0。你也可以为列名添加前缀,如weight=prefix:weight_name
query 或者query_column或者gourp 或者group_column: 一个字符串,query/group ID 列。默认为空字符串。你也可以指定一个整数,如query=0 表示第0列是query列。注意:它是剔除了标签列之后的索引。假如标签列为0,query列为1,则这里query=0。你也可以为列名添加前缀,如query=prefix:query_name
ignore_column 或者 ignore_feature或者blacklist: 一个字符串,表示训练中忽略的一些列,默认为空字符串。可以用数字做索引,如ignore_column=0,1,2 表示第0,1,2 列将被忽略。注意:它是剔除了标签列之后的索引。
你也可以为列名添加前缀,如ignore_column=prefix:ign_name1,ign_name2
categorical_feature 或者categorical_column或者cat_feature或者 cat_column:一个字符串,指定category 特征的列。默认为空字符串。可以用数字做索引,如categorical_feature=0,1,2 表示第0,1,2 列将作为category 特征。注意:它是剔除了标签列之后的索引。你也可以为列名添加前缀,如categorical_feature=prefix:cat_name1,cat_name2 在categorycal 特征中,负的取值被视作缺失值。
predict_raw_score 或者raw_score或者 is_predict_raw_score:一个布尔值,表示是否预测原始得分。默认为False。如果为True则仅预测原始得分。该参数只用于prediction 任务。
predict_leaf_index 或者 leaf_index或者 is_predict_leaf_index: 一个布尔值,表示是否预测每个样本在每棵树上的叶节点编号。默认为False。在预测时,每个样本都会被分配到每棵树的某个叶子节点上。该参数就是要输出这些叶子节点的编号。该参数只用于prediction 任务。
predict_contrib 或者 contrib或者 is_predict_contrib: 一个布尔值,表示是否输出每个特征对于每个样本的预测的贡献。默认为False。输出的结果形状为[nsamples,nfeatures+1], 之所以+1 是考虑到bais 的贡献。所有的贡献加起来就是该样本的预测结果。该参数只用于prediction 任务。
bin_construct_sample_cnt 或者 subsample_for_bin:一个整数,表示用来构建直方图的样本的数量。默认为200000。如果数据非常稀疏,则可以设置为一个更大的值,如果设置更大的值,则会提供更好的训练效果,但是会增加数据加载时间。
num_iteration_predict: 一个整数,表示在预测中使用多少棵子树。默认为-1。小于等于0表示使用模型的所有子树。该参数只用于prediction 任务。
pred_early_stop:一个布尔值,表示是否使用早停来加速预测。默认为False。如果为True,则可能影响精度。
pred_early_stop_freq: 一个整数,表示检查早停的频率。默认为10
pred_early_stop_margin: 一个浮点数,表示早停的边际阈值。默认为0
use_missing: 一个布尔值,表示是否使用缺失值功能。默认为True如果为False 则禁用缺失值功能。
zero_as_missing: 一个布尔值,表示是否将所有的零(包括在libsvm/sparse矩阵 中未显示的值)都视为缺失值。 默认为False。如果为False,则将nan 视作缺失值。如果为True,则np.nan 和 零都将视作缺失值。
init_score_file: 一个字符串,表示训练时的初始化分数文件的路径。默认为空字符串,表示train_data_file+”.init” (如果存在)
valid_init_score_file: 一个字符串,表示验证时的初始化分数文件的路径。默认为空字符串,表示valid_data_file+”.init” (如果存在)。如果有多个(对应于多个验证集),则可以用逗号, 来分隔。
目标函数的参数:sigmoid: 一个浮点数,用sigmoid 函数的参数,默认为0。它用于二分类任务和lambdarank 任务。
alpha: 一个浮点数,用于Huber 损失函数和Quantile regression ,默认值为0。它用于huber回归任务和Quantile 回归任务。
fair_c: 一个浮点数,用于Fair 损失函数,默认值为0 。它用于fair 回归任务。
gaussian_eta: 一个浮点数,用于控制高斯函数的宽度,默认值为0 。它用于regression_l1 回归任务和huber回归任务。
posson_max_delta_step: 一个浮点数,用于Poisson regression 的参数,默认值为7 。它用于poisson 回归任务。
scale_pos_weight: 一个浮点数,用于调整正样本的权重,默认值为0它用于二分类任务。
boost_from_average: 一个布尔值,指示是否将初始得分调整为平均值(它可以使得收敛速度更快)。默认为True。它用于回归任务。
is_unbalance或者unbalanced_set : 一个布尔值,指示训练数据是否均衡的。默认为True。它用于二分类任务。
max_position: 一个整数,指示将在这个NDCG 位置优化。默认为 20 。它用于lambdarank 任务。
label_gain: 一个浮点数序列,给出了每个标签的增益。默认值为0,1,3,7,15,….它用于lambdarank 任务。
num_class或者num_classes : 一个整数,指示了多分类任务中的类别数量。默认为 1它用于多分类任务。
reg_sqrt: 一个布尔值,默认为False。如果为True,则拟合的结果为:\sqrt{label}。同时预测的结果被自动转换为:{pred}^2。它用于回归任务。
度量参数:metric:一个字符串,指定了度量的指标,默认为:对于回归问题,使用l2 ;对于二分类问题,使用binary_logloss;对于lambdarank 问题,使用ndcg。如果有多个度量指标,则用逗号, 分隔。
‘l1’ 或者 mean_absolute_error或者 mae或者 regression_l1: 表示绝对值损失
‘l2’ 或者mean_squared_error或者 mse或者 regression_l2或者 regression:表示平方损失
‘l2_root’ 或者root_mean_squared_error或者 rmse:表示开方损失
‘quantile’: 表示Quantile 回归中的损失
‘mape’ 或者 ‘mean_absolute_percentage_error’ :表示MAPE 损失
‘huber’: 表示huber 损失
‘fair’: 表示fair 损失
‘poisson’: 表示poisson 回归的负对数似然
‘gamma’: 表示gamma 回归的负对数似然
‘gamma_deviance’: 表示gamma 回归的残差的方差
‘tweedie’: 表示Tweedie 回归的负对数似然
‘ndcg’: 表示NDCG
‘map’ 或者’mean_average_precision’: 表示平均的精度
‘auc’: 表示AUC
‘binary_logloss’或者’binary’: 表示二类分类中的对数损失函数
‘binary_error’: 表示二类分类中的分类错误率
‘multi_logloss’或者 ‘multiclass’或者 ‘softmax’或者 ‘multiclassova’或者 ‘multiclass_ova’,或者’ova’或者 ‘ovr’: 表示多类分类中的对数损失函数
‘multi_error’: 表示多分类中的分类错误率
‘xentropy’或者’cross_entropy’: 表示交叉熵
‘xentlambda’ 或者’cross_entropy_lambda’: 表示intensity 加权的交叉熵
‘kldiv’或者’kullback_leibler’: 表示KL 散度
metric_freq或者’output_freq’:一个正式,表示每隔多少次输出一次度量结果。默认为1。
train_metric 或者training_metric或者 is_training_metric: 一个布尔值,默认为False。如果为True,则在训练时就输出度量结果。
ndcg_at 或者 ndcg_eval_at 或者eval_at: 一个整数列表,指定了NDCG 评估点的位置。默认为1,2,3,4,5 。
参考链接:http://lightgbm.apachecn.org/#/docs/6
http://www.huaxiaozhuan.com/%E5%B7%A5%E5%85%B7/lightgbm/chapters/lightgbm_usage.html
https://lightgbm.readthedocs.io/en/latest/Parameters.html

调参示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

import lightgbm as lgb

X = df.iloc[:,:-1]

y = df.iloc[:,-1]

category_feature=[0,1,2,3,4,5,6,7,8,9,10,11,12,13]

cv_params = {

    'num_leaves': [13,14,15],

#     'max_depth': [-1,4,6,8],

#     'learning_rate': [0.07,0.08,0.09],

#     'n_estimators':[10,15,20],

#     'min_child_samples':[15,20,25],

#     'subsample':[0.4,0.5,0.6,0.7],

#     'colsample_bytree':[0.4,0.5,0.6,0.7],

#     'reg_alpha':[0,1,2,3,5,8],

#     'reg_lambda':[7,8,9,10],

#     'num_iterations':[30,40,50],

#     'min_data_in_leaf': [30, 50, 100, 300, 400],

#     'cat_smooth':[150,160,170,180,190]

}

# cv_params = {'learning_rate': [0.06,0.07,0.08,0.09]}

other_params = {

    'max_depth' : 4,

    'num_leaves': 15,

    'learning_rate': 0.07,

    'cat_smooth':180,

    'num_iterations':100,

    'colsample_bytree': 0.7,

    'subsample': 0.4,

    'reg_alpha':3,

    'reg_lambda':9,

}

model_lgb = lgb.LGBMRegressor(**other_params)

optimized_lgb = GridSearchCV(estimator=model_lgb, param_grid=cv_params, scoring='r2', cv=5, verbose=1, n_jobs=2)

optimized_lgb.fit(X, y, categorical_feature=category_feature)

print('参数的最佳取值:{0}'.format(optimized_lgb.best_params_))

print('最佳模型得分:{0}'.format(optimized_lgb.best_score_))

print(optimized_lgb.cv_results_['mean_test_score'])

print(optimized_lgb.cv_results_['params'])

sklearn接口形式的LightGBM示例

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

import lightgbm as lgb

from sklearn.metrics import mean_squared_error

from sklearn.model_selection import GridSearchCV

from sklearn.datasets import load_iris

from sklearn.model_selection import train_test_split

# 加载数据

iris = load_iris()

data = iris.data

target = iris.target

X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2)

# 创建模型,训练模型

gbm = lgb.LGBMRegressor(objective='regression', num_leaves=31, learning_rate=0.05, n_estimators=20)

gbm.fit(X_train, y_train, eval_set=[(X_test, y_test)], eval_metric='l1', early_stopping_rounds=5)

# 测试机预测

y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration_)

# 模型评估

print('The rmse of prediction is:', mean_squared_error(y_test, y_pred) ** 0.5)

# feature importances

print('Feature importances:', list(gbm.feature_importances_))

# 网格搜索,参数优化

estimator = lgb.LGBMRegressor(num_leaves=31)

param_grid = {

    'learning_rate': [0.01, 0.1, 1],

    'n_estimators': [20, 40]

}

gbm = GridSearchCV(estimator, param_grid)

gbm.fit(X_train, y_train)

print('Best parameters found by grid search are:', gbm.best_params_)

原生形式使用lightgbm

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

import lightgbm as lgb

from sklearn.metrics import mean_squared_error

from sklearn.datasets import load_iris

from sklearn.model_selection import train_test_split

iris = load_iris()

data = iris.data

target = iris.target

X_train, X_test, y_train, y_test = train_test_split(data, target, test_size=0.2)

# 创建成lgb特征的数据集格式

lgb_train = lgb.Dataset(X_train, y_train)

lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)

# 将参数写成字典下形式

params = {

    'task': 'train',

    'boosting_type': 'gbdt',  # 设置提升类型

    'objective': 'regression',  # 目标函数

    'metric': {'l2', 'auc'},  # 评估函数

    'num_leaves': 31,  # 叶子节点数

    'learning_rate': 0.05,  # 学习速率

    'feature_fraction': 0.9,  # 建树的特征选择比例

    'bagging_fraction': 0.8,  # 建树的样本采样比例

    'bagging_freq': 5,  # k 意味着每 k 次迭代执行bagging

    'verbose': 1  # <0 显示致命的, =0 显示错误 (警告), >0 显示信息

}

# 训练 cv and train

gbm = lgb.train(params, lgb_train, num_boost_round=20, valid_sets=lgb_eval, early_stopping_rounds=5)

# 保存模型到文件

gbm.save_model('model.txt')

# 预测数据集

y_pred = gbm.predict(X_test, num_iteration=gbm.best_iteration)

# 评估模型

print('The rmse of prediction is:', mean_squared_error(y_test, y_pred) ** 0.5)

参数速查

xgblgbxgb.sklearnlgb.sklearn
booster=’gbtree’boosting=’gbdt’booster=’gbtree’boosting_type=’gbdt’
objective=’binary:logistic’application=’binary’objective=’binary:logistic’objective=’binary’
max_depth=7num_leaves=2**7max_depth=7num_leaves=2**7
eta=0.1learning_rate=0.1learning_rate=0.1learning_rate=0.1
num_boost_round=10num_boost_round=10n_estimators=10n_estimators=10
gamma=0min_split_gain=0.0gamma=0min_split_gain=0.0
min_child_weight=5min_child_weight=5min_child_weight=5min_child_weight=5
subsample=1bagging_fraction=1subsample=1.0subsample=1.0
colsample_bytree=1.0feature_fraction=1colsample_bytree=1.0colsample_bytree=1.0
alpha=0lambda_l1=0reg_alpha=0.0reg_alpha=0.0
lambda=1lambda_l2=0reg_lambda=1reg_lambda=0.0
scale_pos_weight=1scale_pos_weight=1scale_pos_weight=1scale_pos_weight=1
seedbagging_seed feature_fraction_seedrandom_state=888random_state=888
nthreadnum_threadsn_jobs=4n_jobs=4
evalsvalid_setseval_seteval_set
eval_metricmetriceval_metriceval_metric
early_stopping_roundsearly_stopping_roundsearly_stopping_roundsearly_stopping_rounds
verbose_evalverbose_evalverboseverbose

参考链接:https://bacterous.github.io/2018/09/13/LightGBM%E4%BD%BF%E7%94%A8/

更多参考

  • 项目地址:GitHub - microsoft/LightGBM: A fast, distributed, high performance gradient boosting (GBT, GBDT, GBRT, GBM or MART) framework based on decision tree algorithms, used for ranking, classification and many other machine learning tasks.
  • 中文文档:http://lightgbm.apachecn.org/
  • 参考链接:关于sklearn中的决策树是否应该用one-hot编码? - 知乎

在模型fit数据的时候可以操作下面这些参数:(下面这些参数的具体含义上面基本都有)

Parameters----------X : array-like or sparse matrix of shape = [n_samples, n_features]Input feature matrix.y : array-like of shape = [n_samples]The target values (class labels in classification, real numbers in regression).sample_weight : array-like of shape = [n_samples] or None, optional (default=None)Weights of training data.init_score : array-like of shape = [n_samples] or None, optional (default=None)Init score of training data.group : array-like or None, optional (default=None)Group data of training data.eval_set : list or None, optional (default=None)A list of (X, y) tuple pairs to use as validation sets.eval_names : list of strings or None, optional (default=None)Names of eval_set.eval_sample_weight : list of arrays or None, optional (default=None)Weights of eval data.eval_class_weight : list or None, optional (default=None)Class weights of eval data.eval_init_score : list of arrays or None, optional (default=None)Init score of eval data.eval_group : list of arrays or None, optional (default=None)Group data of eval data.eval_metric : string, list of strings, callable or None, optional (default=None)If string, it should be a built-in evaluation metric to use.If callable, it should be a custom evaluation metric, see note below for more details.In either case, the ``metric`` from the model parameters will be evaluated and used as well.Default: 'l2' for LGBMRegressor, 'logloss' for LGBMClassifier, 'ndcg' for LGBMRanker.early_stopping_rounds : int or None, optional (default=None)Activates early stopping. The model will train until the validation score stops improving.Validation score needs to improve at least every ``early_stopping_rounds`` round(s)to continue training.Requires at least one validation data and one metric.If there's more than one, will check all of them. But the training data is ignored anyway.To check only the first metric, set the ``first_metric_only`` parameter to ``True``in additional parameters ``**kwargs`` of the model constructor.verbose : bool or int, optional (default=True)Requires at least one evaluation data.If True, the eval metric on the eval set is printed at each boosting stage.If int, the eval metric on the eval set is printed at every ``verbose`` boosting stage.The last boosting stage or the boosting stage found by using ``early_stopping_rounds`` is also printed... rubric:: ExampleWith ``verbose`` = 4 and at least one item in ``eval_set``,an evaluation metric is printed every 4 (instead of 1) boosting stages.feature_name : list of strings or 'auto', optional (default='auto')Feature names.If 'auto' and data is pandas DataFrame, data columns names are used.categorical_feature : list of strings or int, or 'auto', optional (default='auto')Categorical features.If list of int, interpreted as indices.If list of strings, interpreted as feature names (need to specify ``feature_name`` as well).If 'auto' and data is pandas DataFrame, pandas unordered categorical columns are used.All values in categorical features should be less than int32 max value (2147483647).Large values could be memory consuming. Consider using consecutive integers starting from zero.All negative values in categorical features will be treated as missing values.The output cannot be monotonically constrained with respect to a categorical feature.callbacks : list of callback functions or None, optional (default=None)List of callback functions that are applied at each iteration.See Callbacks in Python API for more information.

调参开始

部分参考博客:LightGBM调参笔记_浅笑古今的博客-CSDN博客

第一步:学习率和迭代次数


我们先把学习率先定一个较高的值,这里取 learning_rate = 0.1,其次确定估计器boosting/boost/boosting_type的类型,不过默认都会选gbdt。

迭代的次数,也可以说是残差树的数目,参数名为n_estimators/num_iterations/num_round/num_boost_round。我们可以先将该参数设成一个较大的数,然后在cv结果中查看最优的迭代次数,具体如代码。

在这之前,我们必须给其他重要的参数一个初始值。初始值的意义不大,只是为了方便确定其他参数。下面先给定一下初始值:

以下参数根据具体项目要求定:(如果是回归,那么objective中的binary需要修改为regression)

'boosting_type'/'boosting': 'gbdt'
'objective': 'binary'
'metric': 'auc'

以下是我选择的初始值:

'max_depth': 5     # 由于数据集不是很大,所以选择了一个适中的值,其实4-10都无所谓。
'num_leaves': 30   # 由于lightGBM是leaves_wise生长,官方说法是要小于2^max_depth
'subsample'/'bagging_fraction':0.8           # 数据采样
'colsample_bytree'/'feature_fraction': 0.8   # 特征采样

下面用cv确定迭代次数

import pandas as pd
import lightgbm as lgb
from sklearn.datasets import load_breast_cancer
from sklearn.cross_validation import train_test_splitcanceData=load_breast_cancer()
X=canceData.data
y=canceData.target
X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=0,test_size=0.2)
params = {    'boosting_type': 'gbdt','objective': 'binary','metric': 'auc','nthread':4,'learning_rate':0.1,'num_leaves':30, 'max_depth': 5,   'subsample': 0.8, 'colsample_bytree': 0.8, }data_train = lgb.Dataset(X_train, y_train)
cv_results = lgb.cv(params, data_train, num_boost_round=1000, nfold=5, stratified=False, shuffle=True, metrics='auc',early_stopping_rounds=50,seed=0)
print('best n_estimators:', len(cv_results['auc-mean']))
print('best cv score:', pd.Series(cv_results['auc-mean']).max())
输出结果如下:('best n_estimators:', 188)
('best cv score:', 0.99134716298085424)我们根据以上结果,取n_estimators=188。

第二步:确定max_depth和num_leaves

这是提高精确度的最重要的参数。

max_depth :设置树深度,深度越大可能过拟合

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

我们也可以同时调节这两个参数,对于这两个参数调优,我们先粗调,再细调:

这里我们引入sklearn里的GridSearchCV()函数进行搜索。

params_test1={'max_depth': range(3,8,1), 'num_leaves':range(5, 100, 5)}gsearch1 = GridSearchCV(estimator = lgb.LGBMClassifier(boosting_type='gbdt',objective='binary',metrics='auc',learning_rate=0.1, n_estimators=188, max_depth=6, bagging_fraction = 0.8,feature_fraction = 0.8), param_grid = params_test1, scoring='roc_auc',cv=5,n_jobs=-1)
gsearch1.fit(X_train,y_train)
gsearch1.grid_scores_, gsearch1.best_params_, gsearch1.best_score_

 结果如下:

([mean: 0.99248, std: 0.01033, params: {'num_leaves': 5, 'max_depth': 3},mean: 0.99227, std: 0.01013, params: {'num_leaves': 10, 'max_depth': 3},mean: 0.99227, std: 0.01013, params: {'num_leaves': 15, 'max_depth': 3},······mean: 0.99331, std: 0.00775, params: {'num_leaves': 85, 'max_depth': 7},mean: 0.99331, std: 0.00775, params: {'num_leaves': 90, 'max_depth': 7},mean: 0.99331, std: 0.00775, params: {'num_leaves': 95, 'max_depth': 7}],{'max_depth': 4, 'num_leaves': 10},0.9943573667711598)

如果metrics='rmse'(很多比赛都要求均方误差),这里必须说一下,sklearn模型评估里的scoring参数都是采用的higher return values are better than lower return values(较高的返回值优于较低的返回值)。但是,我采用的metric策略采用的是均方误差(rmse),越低越好,所以sklearn就提供了neg_mean_squared_erro参数,也就是返回metric的负数,所以就均方差来说,也就变成负数越大越好了。

如果用rmse:

所以,可以看到,最优解的分数为-1.860,转化为均方差为np.sqrt(-(-1.860)) = 1.3639。

第三步:确定min_data_in_leaf和max_bin in

说到这里,就该降低过拟合了。

min_data_in_leaf 是一个很重要的参数, 也叫min_child_samples,它的值取决于训练数据的样本个树和num_leaves. 将其设置的较大可以避免生成一个过深的树, 但有可能导致欠拟合。

min_sum_hessian_in_leaf:也叫min_child_weight,使一个结点分裂的最小海森值之和,真拗口(Minimum sum of hessians in one leaf to allow a split. Higher values potentially decrease overfitting)

我们采用跟上面相同的方法进行:

params_test2={'max_bin': range(5,256,10), 'min_data_in_leaf':range(1,102,10)}gsearch2 = GridSearchCV(estimator = lgb.LGBMClassifier(boosting_type='gbdt',objective='binary',metrics='auc',learning_rate=0.1, n_estimators=188, max_depth=4, num_leaves=10,bagging_fraction = 0.8,feature_fraction = 0.8), param_grid = params_test2, scoring='roc_auc',cv=5,n_jobs=-1)
gsearch2.fit(X_train,y_train)
gsearch2.grid_scores_, gsearch2.best_params_, gsearch2.best_score_
([mean: 0.98715, std: 0.01044, params: {'min_data_in_leaf': 1, 'max_bin': 5},mean: 0.98809, std: 0.01095, params: {'min_data_in_leaf': 11, 'max_bin': 5},mean: 0.98809, std: 0.00952, params: {'min_data_in_leaf': 21, 'max_bin': 5},
······mean: 0.99363, std: 0.00812, params: {'min_data_in_leaf': 81, 'max_bin': 255},mean: 0.99133, std: 0.00788, params: {'min_data_in_leaf': 91, 'max_bin': 255},mean: 0.98882, std: 0.01223, params: {'min_data_in_leaf': 101, 'max_bin': 255}],{'max_bin': 15, 'min_data_in_leaf': 51},0.9952978056426331)

第四步:确定feature_fraction、bagging_fraction、bagging_freq

这两个参数都是为了降低过拟合的。

feature_fraction参数来进行特征的子抽样。这个参数可以用来防止过拟合及提高训练速度。

bagging_fraction+bagging_freq参数必须同时设置,bagging_fraction相当于subsample样本采样,可以使bagging更快的运行,同时也可以降拟合。bagging_freq默认0,表示bagging的频率,0意味着没有使用bagging,k意味着每k轮迭代进行一次bagging。

不同的参数,同样的方法。

 params_test3={'feature_fraction': [0.6,0.7,0.8,0.9,1.0],'bagging_fraction': [0.6,0.7,0.8,0.9,1.0],'bagging_freq': range(0,81,10)
}gsearch3 = GridSearchCV(estimator = lgb.LGBMClassifier(boosting_type='gbdt',objective='binary',metrics='auc',learning_rate=0.1, n_estimators=188, max_depth=4, num_leaves=10,max_bin=15,min_data_in_leaf=51), param_grid = params_test3, scoring='roc_auc',cv=5,n_jobs=-1)
gsearch3.fit(X_train,y_train)
gsearch3.grid_scores_, gsearch3.best_params_, gsearch3.best_score_
([mean: 0.99467, std: 0.00710, params: {'bagging_freq': 0, 'bagging_fraction': 0.6, 'feature_fraction': 0.6},mean: 0.99415, std: 0.00804, params: {'bagging_freq': 0, 'bagging_fraction': 0.6, 'feature_fraction': 0.7},mean: 0.99530, std: 0.00722, params: {'bagging_freq': 0, 'bagging_fraction': 0.6, 'feature_fraction': 0.8},
······mean: 0.99530, std: 0.00722, params: {'bagging_freq': 80, 'bagging_fraction': 1.0, 'feature_fraction': 0.8},mean: 0.99383, std: 0.00731, params: {'bagging_freq': 80, 'bagging_fraction': 1.0, 'feature_fraction': 0.9},mean: 0.99383, std: 0.00766, params: {'bagging_freq': 80, 'bagging_fraction': 1.0, 'feature_fraction': 1.0}],{'bagging_fraction': 0.6, 'bagging_freq': 0, 'feature_fraction': 0.8},0.9952978056426331)

第五步:确定lambda_l1和lambda_l2

正则化参数lambda_l1(reg_alpha), lambda_l2(reg_lambda),毫无疑问,是降低过拟合的,两者分别对应l1正则化和l2正则化。我们也来尝试一下使用这两个参数。
params_test4={'lambda_l1': [1e-5,1e-3,1e-1,0.0,0.1,0.3,0.5,0.7,0.9,1.0],'lambda_l2': [1e-5,1e-3,1e-1,0.0,0.1,0.3,0.5,0.7,0.9,1.0]
}gsearch4 = GridSearchCV(estimator = lgb.LGBMClassifier(boosting_type='gbdt',objective='binary',metrics='auc',learning_rate=0.1, n_estimators=188, max_depth=4, num_leaves=10,max_bin=15,min_data_in_leaf=51,bagging_fraction=0.6,bagging_freq= 0, feature_fraction= 0.8), param_grid = params_test4, scoring='roc_auc',cv=5,n_jobs=-1)
gsearch4.fit(X_train,y_train)
gsearch4.grid_scores_, gsearch4.best_params_, gsearch4.best_score_
([mean: 0.99530, std: 0.00722, params: {'lambda_l1': 1e-05, 'lambda_l2': 1e-05},mean: 0.99415, std: 0.00804, params: {'lambda_l1': 1e-05, 'lambda_l2': 0.001},mean: 0.99331, std: 0.00826, params: {'lambda_l1': 1e-05, 'lambda_l2': 0.1},
·····mean: 0.99049, std: 0.01047, params: {'lambda_l1': 1.0, 'lambda_l2': 0.7},mean: 0.99049, std: 0.01013, params: {'lambda_l1': 1.0, 'lambda_l2': 0.9},mean: 0.99070, std: 0.01071, params: {'lambda_l1': 1.0, 'lambda_l2': 1.0}],{'lambda_l1': 1e-05, 'lambda_l2': 1e-05},0.9952978056426331)

第六步:确定 min_split_gain 

params_test5={'min_split_gain':[0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]}gsearch5 = GridSearchCV(estimator = lgb.LGBMClassifier(boosting_type='gbdt',objective='binary',metrics='auc',learning_rate=0.1, n_estimators=188, max_depth=4, num_leaves=10,max_bin=15,min_data_in_leaf=51,bagging_fraction=0.6,bagging_freq= 0, feature_fraction= 0.8,
lambda_l1=1e-05,lambda_l2=1e-05), param_grid = params_test5, scoring='roc_auc',cv=5,n_jobs=-1)
gsearch5.fit(X_train,y_train)
gsearch5.grid_scores_, gsearch5.best_params_, gsearch5.best_score_
([mean: 0.99530, std: 0.00722, params: {'min_split_gain': 0.0},mean: 0.99415, std: 0.00810, params: {'min_split_gain': 0.1},mean: 0.99394, std: 0.00898, params: {'min_split_gain': 0.2},mean: 0.99373, std: 0.00918, params: {'min_split_gain': 0.3},mean: 0.99404, std: 0.00845, params: {'min_split_gain': 0.4},mean: 0.99300, std: 0.00958, params: {'min_split_gain': 0.5},mean: 0.99258, std: 0.00960, params: {'min_split_gain': 0.6},mean: 0.99227, std: 0.01071, params: {'min_split_gain': 0.7},mean: 0.99342, std: 0.00872, params: {'min_split_gain': 0.8},mean: 0.99206, std: 0.01062, params: {'min_split_gain': 0.9},mean: 0.99206, std: 0.01064, params: {'min_split_gain': 1.0}],{'min_split_gain': 0.0},0.9952978056426331)

第七步:降低学习率,增加迭代次数,验证模型

model=lgb.LGBMClassifier(boosting_type='gbdt',objective='binary',metrics='auc',learning_rate=0.01, n_estimators=1000, max_depth=4, num_leaves=10,max_bin=15,min_data_in_leaf=51,bagging_fraction=0.6,bagging_freq= 0, feature_fraction= 0.8,
lambda_l1=1e-05,lambda_l2=1e-05,min_split_gain=0)
model.fit(X_train,y_train)
y_pre=model.predict(X_test)
print("acc:",metrics.accuracy_score(y_test,y_pre))
print("auc:",metrics.roc_auc_score(y_test,y_pre))

结果如下:

('acc:', 0.97368421052631582)
('auc:', 0.9744363289933311)

而使用默认参数时,模型表现如下:

model=lgb.LGBMClassifier()
model.fit(X_train,y_train)
y_pre=model.predict(X_test)
print("acc:",metrics.accuracy_score(y_test,y_pre))
print("auc:",metrics.roc_auc_score(y_test,y_pre))
('acc:', 0.96491228070175439)
('auc:', 0.96379803112099083)

我们可以看出在准确率和AUC得分都有所提高。

3.LightGBM的cv函数调参

这种方式比较省事儿,写好代码自动寻优,但需要有调参经验,如何设置较好的参数范围有一定的技术含量,这里直接给出代码。

import pandas as pd
import lightgbm as lgb
from sklearn import metrics
from sklearn.datasets import load_breast_cancer
from sklearn.cross_validation import train_test_splitcanceData=load_breast_cancer()
X=canceData.data
y=canceData.target
X_train,X_test,y_train,y_test=train_test_split(X,y,random_state=0,test_size=0.2)### 数据转换
print('数据转换')
lgb_train = lgb.Dataset(X_train, y_train, free_raw_data=False)
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train,free_raw_data=False)### 设置初始参数--不含交叉验证参数
print('设置参数')
params = {'boosting_type': 'gbdt','objective': 'binary','metric': 'auc','nthread':4,'learning_rate':0.1}### 交叉验证(调参)
print('交叉验证')
max_auc = float('0')
best_params = {}# 准确率
print("调参1:提高准确率")
for num_leaves in range(5,100,5):for max_depth in range(3,8,1):params['num_leaves'] = num_leavesparams['max_depth'] = max_depthcv_results = lgb.cv(params,lgb_train,seed=1,nfold=5,metrics=['auc'],early_stopping_rounds=10,verbose_eval=True)mean_auc = pd.Series(cv_results['auc-mean']).max()boost_rounds = pd.Series(cv_results['auc-mean']).idxmax()if mean_auc >= max_auc:max_auc = mean_aucbest_params['num_leaves'] = num_leavesbest_params['max_depth'] = max_depth
if 'num_leaves' and 'max_depth' in best_params.keys():          params['num_leaves'] = best_params['num_leaves']params['max_depth'] = best_params['max_depth']# 过拟合
print("调参2:降低过拟合")
for max_bin in range(5,256,10):for min_data_in_leaf in range(1,102,10):params['max_bin'] = max_binparams['min_data_in_leaf'] = min_data_in_leafcv_results = lgb.cv(params,lgb_train,seed=1,nfold=5,metrics=['auc'],early_stopping_rounds=10,verbose_eval=True)mean_auc = pd.Series(cv_results['auc-mean']).max()boost_rounds = pd.Series(cv_results['auc-mean']).idxmax()if mean_auc >= max_auc:max_auc = mean_aucbest_params['max_bin']= max_binbest_params['min_data_in_leaf'] = min_data_in_leaf
if 'max_bin' and 'min_data_in_leaf' in best_params.keys():params['min_data_in_leaf'] = best_params['min_data_in_leaf']params['max_bin'] = best_params['max_bin']print("调参3:降低过拟合")
for feature_fraction in [0.6,0.7,0.8,0.9,1.0]:for bagging_fraction in [0.6,0.7,0.8,0.9,1.0]:for bagging_freq in range(0,50,5):params['feature_fraction'] = feature_fractionparams['bagging_fraction'] = bagging_fractionparams['bagging_freq'] = bagging_freqcv_results = lgb.cv(params,lgb_train,seed=1,nfold=5,metrics=['auc'],early_stopping_rounds=10,verbose_eval=True)mean_auc = pd.Series(cv_results['auc-mean']).max()boost_rounds = pd.Series(cv_results['auc-mean']).idxmax()if mean_auc >= max_auc:max_auc=mean_aucbest_params['feature_fraction'] = feature_fractionbest_params['bagging_fraction'] = bagging_fractionbest_params['bagging_freq'] = bagging_freqif 'feature_fraction' and 'bagging_fraction' and 'bagging_freq' in best_params.keys():params['feature_fraction'] = best_params['feature_fraction']params['bagging_fraction'] = best_params['bagging_fraction']params['bagging_freq'] = best_params['bagging_freq']print("调参4:降低过拟合")
for lambda_l1 in [1e-5,1e-3,1e-1,0.0,0.1,0.3,0.5,0.7,0.9,1.0]:for lambda_l2 in [1e-5,1e-3,1e-1,0.0,0.1,0.4,0.6,0.7,0.9,1.0]:params['lambda_l1'] = lambda_l1params['lambda_l2'] = lambda_l2cv_results = lgb.cv(params,lgb_train,seed=1,nfold=5,metrics=['auc'],early_stopping_rounds=10,verbose_eval=True)mean_auc = pd.Series(cv_results['auc-mean']).max()boost_rounds = pd.Series(cv_results['auc-mean']).idxmax()if mean_auc >= max_auc:max_auc=mean_aucbest_params['lambda_l1'] = lambda_l1best_params['lambda_l2'] = lambda_l2
if 'lambda_l1' and 'lambda_l2' in best_params.keys():params['lambda_l1'] = best_params['lambda_l1']params['lambda_l2'] = best_params['lambda_l2']print("调参5:降低过拟合2")
for min_split_gain in [0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]:params['min_split_gain'] = min_split_gaincv_results = lgb.cv(params,lgb_train,seed=1,nfold=5,metrics=['auc'],early_stopping_rounds=10,verbose_eval=True)mean_auc = pd.Series(cv_results['auc-mean']).max()boost_rounds = pd.Series(cv_results['auc-mean']).idxmax()if mean_auc >= max_auc:max_auc=mean_aucbest_params['min_split_gain'] = min_split_gain
if 'min_split_gain' in best_params.keys():params['min_split_gain'] = best_params['min_split_gain']print(best_params)

结果如下:

{'bagging_fraction': 0.7,'bagging_freq': 30,'feature_fraction': 0.8,'lambda_l1': 0.1,'lambda_l2': 0.0,'max_bin': 255,'max_depth': 4,'min_data_in_leaf': 81,'min_split_gain': 0.1,'num_leaves': 10}

我们将训练得到的参数代入模型

model=lgb.LGBMClassifier(boosting_type='gbdt',objective='binary',metrics='auc',learning_rate=0.01, n_estimators=1000, max_depth=4, num_leaves=10,max_bin=255,min_data_in_leaf=81,bagging_fraction=0.7,bagging_freq= 30, feature_fraction= 0.8,
lambda_l1=0.1,lambda_l2=0,min_split_gain=0.1)
model.fit(X_train,y_train)
y_pre=model.predict(X_test)
print("acc:",metrics.accuracy_score(y_test,y_pre))
print("auc:",metrics.roc_auc_score(y_test,y_pre))

结果如下:

('acc:', 0.98245614035087714)
('auc:', 0.98189901556049541)

使用hyperopt对Lightgbm调参----自动调参

微软的lightgbm已经成为了数据挖掘竞赛的必用工具,运行速度快,准确率高等等各种优点。

调参也是竞赛中不可缺少的一步,常规的调参方法有网格搜索,贝叶斯调参等,或者就是部分大佬的手动直接调参,这种级别需要大量的经验累积,23333。

今天介绍一个调参包----hyperopt,可以对lgb进行自动调参,本次先介绍使用hyperopt对lightgbm进行自动调参,下次再更交叉验证~

关于Hyperopt

hyperopt:是python中的一个用于"分布式异步算法组态/超参数优化"的类库。使用它我们可以拜托繁杂的超参数优化过程,自动获取最佳的超参数。广泛意义上,可以将带有超参数的模型看作是一个必然的非凸函数,因此hyperopt几乎可以稳定的获取比手工更加合理的调参结果。尤其对于调参比较复杂的模型而言,其更是能以远快于人工调参的速度同样获得远远超过人工调参的最终性能。

使用iris数据集来进行演示:

导入数据

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import lightgbm as lgb
from sklearn.model_selection import train_test_split
#导入数据
data_iris=load_iris()
X,y=data_iris.data,data_iris.target
#划分数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=100)
train_data = lgb.Dataset(data=X_train,label=y_train)
test_data = lgb.Dataset(data=X_test,label=y_test)

迁移一:自动调参

定义参数空间

使用hyperopt自带的函数定义参数空间,但是因为其randint()方法产生的数组范围是从0开始的,所以我额外定义了一个数据转换方法,对原始参数空间进行一次转换。

from hyperopt import fmin, tpe, hp, partial# 自定义hyperopt的参数空间
space = {"max_depth": hp.randint("max_depth", 15),"num_trees": hp.randint("num_trees", 300),'learning_rate': hp.uniform('learning_rate', 1e-3, 5e-1),"bagging_fraction": hp.randint("bagging_fraction", 5),"num_leaves": hp.randint("num_leaves", 6),}def argsDict_tranform(argsDict, isPrint=False):argsDict["max_depth"] = argsDict["max_depth"] + 5argsDict['num_trees'] = argsDict['num_trees'] + 150argsDict["learning_rate"] = argsDict["learning_rate"] * 0.02 + 0.05argsDict["bagging_fraction"] = argsDict["bagging_fraction"] * 0.1 + 0.5argsDict["num_leaves"] = argsDict["num_leaves"] * 3 + 10if isPrint:print(argsDict)else:passreturn argsDict

创建模型工厂与分数获取器

lightgbm模型工厂用于生产我们需要的model,而分数获取器则是为了解耦。这样在实际的测试工作中可以更加方便地套用代码。

from sklearn.metrics import mean_squared_errordef lightgbm_factory(argsDict):argsDict = argsDict_tranform(argsDict)params = {'nthread': -1,  # 进程数'max_depth': argsDict['max_depth'],  # 最大深度'num_trees': argsDict['num_trees'],  # 树的数量'eta': argsDict['learning_rate'],  # 学习率'bagging_fraction': argsDict['bagging_fraction'],  # bagging采样数'num_leaves': argsDict['num_leaves'],  # 终点节点最小样本占比的和'objective': 'regression','feature_fraction': 0.7,  # 样本列采样'lambda_l1': 0,  # L1 正则化'lambda_l2': 0,  # L2 正则化'bagging_seed': 100,  # 随机种子,light中默认为100}#rmseparams['metric'] = ['rmse']model_lgb = lgb.train(params, train_data, num_boost_round=300, valid_sets=[test_data],early_stopping_rounds=100)return get_tranformer_score(model_lgb)def get_tranformer_score(tranformer):model = tranformerprediction = model.predict(X_test, num_iteration=model.best_iteration)return mean_squared_error(y_test, prediction)

调用Hyperopt开始调参

之后我们调用hyperopt进行自动调参即可,同时通过返回值获取最佳模型的结果。

# 开始使用hyperopt进行自动调参
algo = partial(tpe.suggest, n_startup_jobs=1)
best = fmin(lightgbm_factory, space, algo=algo, max_evals=20, pass_expr_memo_ctrl=None)

结果:

Early stopping, best iteration is:
[125]   valid_0's rmse: 0.220095

展示结果

展示我们获取的最佳参数,以及该模型在训练集上的最终表现,如果想要使用交叉验证请参考其他教程。

RMSE = lightgbm_factory(best)
print('best :', best)
print('best param after transform :')
argsDict_tranform(best,isPrint=True)
print('rmse of the best lightgbm:', np.sqrt(RMSE))

结果:

Early stopping, best iteration is:
[135]   valid_0's rmse: 0.21918
best : {'bagging_fraction': 0.5, 'learning_rate': 0.050207534543127846, 'max_depth': 17, 'num_leaves': 25, 'num_trees': 250}
best param after transform :
{'bagging_fraction': 0.55, 'learning_rate': 0.05100415069086256, 'max_depth': 22, 'num_leaves': 85, 'num_trees': 400}
rmse of the best lightgbm: 0.219180276662925


原文链接:https://www.jianshu.com/p/017b7b1c505d
 


http://chatgpt.dhexx.cn/article/Y1B7UnCe.shtml

相关文章

XGBoost调参步骤及常见问题

XGBoost xgboost中的基学习器除了可以是CART&#xff08;gbtree&#xff09;也可以是线性分类器&#xff08;gblinear&#xff09; xgboost在目标函数中显示的加上了正则化项&#xff0c;基学习为CART时&#xff0c;正则化项与树的叶子节点的数量T和叶子节点的值有关。 正则项…

LightGBM原理介绍

简介 是GBDT模型的一个进化版本&#xff0c;其主要思想是利用弱分类器&#xff08;决策树&#xff09;迭代训练以得到最优模型&#xff0c;该模型具有训练效果好、不易过拟合等优点&#xff08;备注&#xff1a;容易出现过拟合的风险&#xff0c;需要限制树的最大深度来防止过…

lightbgm参数_参数调优LightGBM-商品分类-代码

1.直接调用LightGBM内嵌的cv寻找最佳的参数n_estimators(弱分类器数目) Otto商品分类数据 导入必要模型import lightgbm as lgbm import pandas as pd import numpy as np from sklearn.model_selection import GridSearchCV from sklearn.model_selection import StratifiedKF…

Xgboost回归四种调参方法及Python简单实现

前言 Xgboost对特征工程和数据处理比较友好&#xff0c;相比之下调参成为用好Xgboost重要的一环&#xff0c;本文分别从参数、调参方法、Python实现的维度进行梳理&#xff0c;作为调参思路的记录。 本文将关注以下几个问题&#xff1a; 1.Xgboost哪些参数需要调参&#xff…

Python机器学习10——梯度提升

本系列所有的代码和数据都可以从陈强老师的个人主页上下载&#xff1a;Python数据程序 参考书目&#xff1a;陈强.机器学习及Python应用. 北京&#xff1a;高等教育出版社, 2021. 本系列基本不讲数学原理&#xff0c;只从代码角度去让读者们利用最简洁的Python代码实现机器学…

【机器学习】集成学习代码练习

课程完整代码&#xff1a;https://github.com/fengdu78/WZU-machine-learning-course 代码修改并注释&#xff1a;黄海广&#xff0c;haiguang2000wzu.edu.cn import warnings warnings.filterwarnings("ignore") import pandas as pd from sklearn.model_selection …

Keras 1.0 与 2.0 中 Convolution1D 的区别(其实是tf1.0 2.0 区别)

1.0 Convolution1D: 一维卷积层 nb_filter: 卷积核的个数 filter_length: 每个卷积核的长度 init: 权重初始化函数名称 weights: 权重初始化 border_mode: valid, same or full 如果是‘valid ’ 进行有效的卷积&#xff0c;对边界数据不处理&#xff0c;‘same表示保留…

数据挖掘入门_Task04

线性回归模型 线性回归(Linear Regression)是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析。 可以直接使用sklearn建立线性模型&#xff1a; from sklearn.linear_model import LinearRegression model LinearRegression(n…

task4 建模调参

1 读取数据 import pandas as pd import numpy as np import warnings warnings.filterwarnings(ignore)note: 将整型变量的类型尽量压缩&#xff0c;逐步判断并转化为int8,int16,int32,int64 def reduce_mem_usage(df):""" iterate through all the columns …

深度学习与神经网络(七)——卷积神经网络之池化pooling 上采样upsample与降采样downsample(下采样)(subsample)(nn.MaxPool2d)

池化层pooling与采样 upsample与downsample upsample(interpolating)是上采样&#xff0c;是图片的放大 unpool是上采样的一种 downsample(subsample)是下采样&#xff0c;是图片的缩小 在卷积神经网络中使用的采样方式就是pooling&#xff0c;有点类似下采样&#xff0c;但不太…

有放回随机抽样:重要参数subsample

原理透析 确认了有多少棵树之后&#xff0c;我们来思考一个问题&#xff1a;建立了众多的树&#xff0c;怎么就能够保证模型整体的效果变强呢&#xff1f;集成的目的是为了模型在样本上能表现出更好的效果&#xff0c;所以对于所有的提升集成算法&#xff0c;每构建一个评估器&…

Subsample子采样(CloudCompare软件)

之前一直以为CC软件里面没有子采样这个功能&#xff0c;不过找了找之后发现还是有的&#xff0c;感觉这些小的功能挺有意思的&#xff0c;所以也就记录一下。 文章目录 一、Random采样二、space采样三、octree采样四、小结 一、Random采样 有时候我总是喜欢使用一些小的样本来…

Android Content Providers(三)——Contacts Provider

接着上篇Android Content Providers&#xff08;二&#xff09;——Contacts Provider继续&#xff0c;接下来要说明的是顶层的Contacts&#xff0c;Contacts是聚合联系人表&#xff0c;在之前讨论的RawContacts是原始联系人表&#xff0c;在Android通讯录的架构中&#xff0c;…

Android contacts 的详解

一、包结构分析 相关联的的projects 1、Contacts相关 联系人分为了Contacts和ContactsCommon&#xff0c;与sim卡联系人相关的是在Telephony中&#xff0c;数据库是在ContactsProvider&#xff0c;apk要push到/system/priv-app/Contacts下 2、Contacts的包结构 3、ContactsComm…

由ContactsProvider的升级引发的OTA首次开机卡白米问题分析

上午的宁静被一个OTA卡白米问题打破&#xff0c;接下来不断有人反馈不同机型都复现了OTA后卡白米&#xff0c;10.9号OTA升级到10.10号的版本&#xff0c;全机型问题&#xff0c;线刷没有问题&#xff0c;好吧&#xff0c;接下来就根据这些信息开始初步分析log吧&#xff01; 初…

Android Content Providers(二)——Contacts Provider

Contacts Provider是Android中一个强大并且灵活的组件&#xff0c;负责管理系统通讯录的数据&#xff0c;对外提供访问接口来对系统通讯录进行访问和操作。 以下是Contacts Provider的组织结构图&#xff1a; 可以看出Android的系统通讯录是三层架构&#xff0c;通过URI进行访…

API Guides Contacts Provider (二)

Data From Sync Adapters 用户直接输入联系人的数据到设备中&#xff0c;但是也可以通过sync adapters从服务器上获取联系人的数据。sync adapter 会自动同步设备和服务器上的数据。sync adapter运行在后台&#xff0c;由系统来控制。系统调用ContentResolver去管理数据。 在A…

Android 7.0后SettingProvider ContactsProvider TelephonyProvider MediaProvider数据库位置

在Android7.0之后&#xff0c;很多Provider数据库的位置都发生了改变&#xff0c;在这记录下&#xff0c;免得以后又忘记了&#xff0c;找起来费劲。 1、SettingsProvider 在之前SettingsProvider是是以settings.db的方法存在&#xff0c;在Android N之后SettingsProvider数据存…

利用Contacts Provider读取手机联系人信息

参考:https://developer.android.google.cn/guide/topics/providers/contacts-provider.html Contacts Provider组织结构 Contacts Provider组织结构由三部分构成,如下图所示: (联系人)Contact:代表联系人,包含了多种联系渠道。(原始联系人)RawContact:每个原始联…

API Guides Contacts Provider

Contacts Provider Contacts Provider是Android的一个强大组件&#xff0c;它管理联系人的核心数据。你在手机联系人看到联系人信息&#xff0c;来源于Contact Provider。当然&#xff0c;你可以在自己的应用用访问ContactProvider的数据&#xff0c;也可以同步手机和服务…