lightgbm实战-二分类问题(贝叶斯优化下调参方法)

# use bayes_opt
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score,KFold
from bayes_opt import BayesianOptimization
import numpy as np
# 产生随机分类数据集,10个特征, 2个类别
x, y = make_classification(n_samples=1000,n_features=10,n_classes=2)


# 尝试一下用未调参的随机森林模型进行交叉验证
rf = RandomForestClassifier()
# 这里会输出5个值,取得均值
cv_score = cross_val_score(rf, x, y, scoring="f1", cv=5).mean()
cv_score

# 定义一个函数,输入一些超参数,这些超参数就是需要进行调整的参数
def rf_cv(n_estimators, min_samples_split, max_features, max_depth):
    cv_score = cross_val_score(
        RandomForestClassifier(n_estimators=int(n_estimators),
                            min_samples_split=int(min_samples_split),
                            max_features=float(max_features), 
                            max_depth=int(max_depth),
                              random_state=2),
    x, y, scoring="f1", cv=5).mean()
    # 必须返回一个值,如果像误差的话(回归算法)这里是需要加上一个负号的
    return cv_score
rf_bo = BayesianOptimization(
        rf_cv,
        {'n_estimators': (10, 250),
        'min_samples_split': (2, 25),
        'max_features': (0.1, 0.999),
        'max_depth': (5, 15)}
    )
# 输出不同迭代参数组合下的得分
rf_bo.maximize()
# 输出最高得分下的参数组合
rf_bo.max

在这里插入图片描述
在这里插入图片描述

# 带入最佳参数进行计算
rf = RandomForestClassifier(random_state=2,max_depth=12,max_features=0.2694,min_samples_split=6,n_estimators=103)
np.mean(cross_val_score(rf, x, y, cv=4, scoring='f1'))

使用lightgbm尝试一波

# 设置几个参数
def lgb_cv(colsample_bytree, min_child_samples, num_leaves, subsample, max_depth):
    model = lgb.LGBMClassifier(boosting_type='gbdt',objective='binary',
           colsample_bytree=float(colsample_bytree), learning_rate=0.01,
           min_child_samples=int(min_child_samples), min_child_weight=0.001, 
           n_estimators=800, n_jobs=-1, num_leaves=int(num_leaves),
           random_state=None, reg_alpha=0.0, reg_lambda=0.0,max_depth=int(max_depth),
           subsample=float(subsample))
    cv_score = cross_val_score(model, x, y, scoring="f1", cv=5).mean()
    return cv_score
# 使用贝叶斯优化
lgb_bo = BayesianOptimization(
        lgb_cv,
        {'colsample_bytree': (0.7,1),
        'min_child_samples': (2, 25),
        'num_leaves': (5, 250),
        'subsample': (0.7, 1),
        'max_depth':(2,10)}
    )
lgb_bo.maximize()
lgb_bo.max
# 将优化好的参数带入进行使用
model = lgb.LGBMClassifier(boosting_type='gbdt',objective='binary',
           colsample_bytree=0.7111, learning_rate=0.01,
           min_child_samples=9, min_child_weight=0.001, 
           n_estimators=800, n_jobs=-1, num_leaves=188,
           random_state=None, reg_alpha=0.0, reg_lambda=0.0,max_depth=2,
           subsample=0.91)
cv_score = cross_val_score(model, x, y, scoring="f1", cv=5).mean()
cv_score
# 结果就不放出来了,也就是一个值,大家可以模仿一下,跑跑代码。

接下里是采用lightgbm的自带的train方法配合交叉验证

def LGB_CV(
          max_depth,
          num_leaves,
          min_data_in_leaf,
          feature_fraction,
          bagging_fraction,
          lambda_l1
         ):
    # 这里就不采用交叉验证的cv_score = cross_val_score(model, x, y, scoring="f1", cv=5)
    kf = KFold(n_splits=5,shuffle=True)
    # f是准备存储预测值的,交叉验证下,用五份数据作为验证集,最后将这五份数据放回f里
    f = np.zeros(x.shape[0])
    for index, (train_index, val_index) in enumerate(kf.split(x)):
        print("fold--{}".format(index))
        train_data = lgb.Dataset(x[train_index], label=y[train_index])
        val_data = lgb.Dataset(x[val_index], label=y[val_index])
    
        params = {'num_leaves': int(num_leaves),
                'min_data_in_leaf': int(min_data_in_leaf), 
                'objective':'binary',
                'max_depth': int(max_depth),
                'learning_rate': 0.01,
                "boosting": "gbdt",
                "feature_fraction": feature_fraction,
                "bagging_fraction": bagging_fraction ,
                "metric": 'auc',
                "lambda_l1": lambda_l1,
                }
        # 因为是交叉验证的算法,这里直接使用train,valid_sets就是要评估的数据集
        model = lgb.train(params, train_data, valid_sets=[train_data, val_data],num_boost_round=700, verbose_eval=500,early_stopping_rounds = 20)
        # 返回迭代中最好的数据,这里的predict里面的数据(不需要经过dataset)不需要再进行转化,如果是xgboost就需要,需要把x_test进行转化DMatrix(x_test),这里x_test不包含类别特征
        f[val_index] = model.predict(x[val_index], num_iteration=model.best_iteration)
        # predict里面的验证集不需要进行dataset,但是xgboost算法时需要dmatrix,并且只需要DMatrix(x_test),这里x_test不包含类别特征,很多地方这里都会出错,直接带着类别就去预测
        del model, train_index, val_index
    # 由于输出的是概率值,转化为0,1的整型值 
    f = np.array([1 if i>0.5 else 0 for i in oof])
    return metrics.f1_score(f, y)
    
# 最后进行调参
LGB_CV(
          max_depth=5,
          num_leaves=32,
          min_data_in_leaf=15,
          feature_fraction=0.8,
          bagging_fraction=0.8,
          lambda_l1=None
         )

# 采用贝叶斯优化算法
lgb_ba = BayesianOptimization(LGB_CV, {"max_depth":(2,12),
          "num_leaves":(5,130),
          "min_data_in_leaf":(5,30),
          "feature_fraction":(0.7,1),
          "bagging_fraction":(0.7,1),
          "lambda_l1":(0,6)})
lgb_ba.maximize()
lgb_ba.max["params"]

在这里插入图片描述

# 把设置好的参数带入
kf = KFold(n_splits=5,shuffle=True)
f = np.zeros(x.shape[0])
# 设置测试集数据
x_test = x[:200]
y_test = y[:200]
prediction = np.zeros(x_test.shape[0])
for index, (train_index, val_index) in enumerate(kf.split(x)):
    print("fold--{}".format(index))
    train_data = lgb.Dataset(x[train_index], label=y[train_index])
    val_data = lgb.Dataset(x[val_index], label=y[val_index])

    params = {'num_leaves': 44,
            'min_data_in_leaf': 19, 
            'objective':'binary',
            'max_depth': 11,
            'learning_rate': 0.01,
            "boosting": "gbdt",
            "feature_fraction": 0.81,
            "bagging_fraction": 0.84 ,
            "metric": 'auc',
            "lambda_l1": 1.8,
            }
    # 因为是交叉验证的算法,这里直接使用train,valid_sets就是要评估的数据集
    model = lgb.train(params, train_data, valid_sets=[train_data, val_data],num_boost_round=700, verbose_eval=500,early_stopping_rounds=20)
    f[val_index] = model.predict(x[val_index], num_iteration=model.best_iteration)
    # predict里面的数据不需要进行dataset
    prediction +=model.predict(x_test)num_iteration=model.best_iteration)/kf.n_splits
metrics.f1_score(np.array([1 if i>0.5 else 0 for i in prediction]), y_test)

在这里插入图片描述

题外话

这是kaggle上面的一种做法,也是非常高效的

  • 12
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
贝叶斯优化是一种用于自动调参方法,可以在给定的搜索空间内找到最优的超参数组合。LightGBM是一种基于梯度提升决策树(GBDT)的机器学习算法,它在处理大规模数据和高维特征时具有较快的训练速度和较低的内存消耗。现在,我将介绍如何使用贝叶斯优化来调整LightGBM模型的超参数。 首先,确定要调整的超参数。LightGBM有许多可调整的超参数,比如学习率(learning rate)、树的深度(max_depth)、叶子节点数(num_leaves)等等。你可以根据自己的需求选择需要调整的超参数。 然后,确定贝叶斯优化的目标函数。在这里,我们可以选择模型在验证集上的评估指标作为目标函数,比如准确率、AUC等等。目标函数应当与超参数相关,并且越大越好或者越小越好。 接下来,确定搜索空间。搜索空间包括每个超参数的取值范围。你可以选择在一定范围内均匀采样或者使用离散值进行采样。 然后,使用贝叶斯优化算法进行超参数搜索。常见的贝叶斯优化算法有高斯过程、树结构模型等。你可以使用现有的贝叶斯优化库,比如Hyperopt、Optuna等。 在每次迭代中,根据目标函数的反馈调整超参数的取值,并更新搜索空间。通过多次迭代,最终找到最优的超参数组合。 最后,使用找到的最优超参数重新训练LightGBM模型,并在测试集上评估模型的性能。 以上就是使用贝叶斯优化来调整LightGBM模型的步骤。希望对你有所帮助!
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值