【xgboost】贝叶斯自动调参代码

2023-11-08

工作中,很多场景下会用到xgboost模型,如风控、催收、营销、推荐等待。在用xgboost模型进行模型训练的时候,也经常用贝叶斯自动调参来搜索最优的参数。

现在把相关的代码贴出来,供大家参考。

目前是支持了xgboost和lightgbm模型,如果需要支持其他模型,感兴趣的朋友可以自己添加一下。

一、安装包

pip install bayesian-optimization

二、代码示例

GBDTModel类

我写了一个GBDTModel类,用来封装贝叶斯自动调参、模型训练、模型评估、模型保存、参数保存等代码,具体如下:

# -*-coding:utf-8 -*-
import os
import json
import pickle
import numpy as np
import xgboost as xgb
import lightgbm as lgb
from bayes_opt import BayesianOptimization
from sklearn.metrics import mean_absolute_error, roc_auc_score, accuracy_score, confusion_matrix


class GBDTModel(object):
    def __init__(self, output_dir, n_thread=10, n_jobs=10, random_state=7):
        self.best_model = None
        self.best_param = None
        self.output_dir = output_dir
        os.makedirs(output_dir, exist_ok=True)

        self.n_thread = n_thread
        self.n_jobs = n_jobs
        self.random_state = random_state

        self.clf_dict = {
            'lgb': lgb.LGBMClassifier,
            'xgb': xgb.XGBClassifier
        }
        self.params_dict = {
            'lgb': {
                'learning_rate': (0.03, 0.2),
                'n_estimators': (100, 1000),
                'num_leaves': (20, 100),
                'max_depth': (2, 5),
                'max_bin': (30, 255),
                'min_data_in_bin': (30, 256),
                'min_data_in_leaf': (30, 500),
                'min_split_gain': (0.1, 10),
                'min_child_weight': (0.1, 100),
                'min_child_samples': (30, 256),
                'colsample_bytree': (0.6, 1.0),
                'reg_alpha': (0.3, 10),
                'reg_lambda': (0.3, 10),
                'subsample': (0.6, 1.0),
                'subsample_for_bin': (200000, 400000),
                'scale_pos_weight': (1.0, 1.5),
            },
            'xgb': {
                'learning_rate': (0.01, 0.3),
                'n_estimators': (100, 800),
                'max_depth': (2, 5),
                'reg_alpha': (0.00001, 5),
                'reg_lambda': (0.00001, 5),
                'min_child_weight': (1, 100),
                'subsample': (0.6, 1.0),
                'colsample_bytree': (0.6, 1.0),
                'colsample_bynode': (0.6, 1.0),
                'colsample_bylevel': (0.6, 1.0),
                'gamma': (0.0, 0.3),
                'scale_pos_weight': (1.0, 1.5)
            }
        }
        self.int_params = [
            'max_depth', 'n_estimators', 'num_leaves', 'max_bin', 'scale_pos_weight',
            'min_child_samples', 'min_data_in_bin', 'min_data_in_leaf', 'subsample_for_bin']

    def save_model(self, model_name="model.pkl"):
        file = os.path.join(self.output_dir, model_name)
        with open(file, 'wb') as f:
            pickle.dump(self.best_model, f)

    def read_model(self, model_name="model.pkl"):
        file = os.path.join(self.output_dir, model_name)
        with open(file, 'rb') as f:
            self.best_model = pickle.load(f)

    def save_best_param(self, file_name="params.json"):
        file = os.path.join(self.output_dir, file_name)
        with open(file, mode="w", encoding="utf-8") as fw:
            json.dump(self.best_param, fw, indent=4, ensure_ascii=False)

    def read_best_param(self, file_name="params.json"):
        file = os.path.join(self.output_dir, file_name)
        with open(file=file, mode="r", encoding="utf-8") as fr:
            self.best_param = json.load(fr)

    def bayes_optimization(self, train_x, train_y, test_x, test_y, oot_x, oot_y,
                           clf_name='lgb', target='acc', scale_pos_use=True, **bayes_args):
        res_list = []
        n_thread = self.n_thread
        n_jobs = self.n_jobs
        random_state = self.random_state
        int_params = self.int_params

        if scale_pos_use is True:
            scale_pos_weight = round(np.sum(train_y == 0) / np.sum(train_y == 1), 1)
            if 'scale_pos_weight' in self.params_dict[clf_name].keys():
                self.params_dict[clf_name]['scale_pos_weight'] = \
                    tuple([x * scale_pos_weight for x in list(self.params_dict[clf_name]['scale_pos_weight'])])
            else:
                self.params_dict[clf_name]['scale_pos_weight'] = scale_pos_weight
        else:
            self.params_dict[clf_name]['scale_pos_weight'] = 1

        print("[bayes_optimization] scale_pos_weight: {}".format(
            self.params_dict[clf_name]['scale_pos_weight']), flush=True)

        def _eval(**clf_args):
            for param in int_params:
                if clf_args.get(param):
                    clf_args[param] = int(round(clf_args[param]))

            print("[eval] args: {}".format(clf_args))

            if clf_name == 'lgb':
                model = lgb.LGBMClassifier(**clf_args,
                                           n_jobs=n_jobs,
                                           random_state=random_state)
            else:
                model = xgb.XGBClassifier(**clf_args,
                                          nthread=n_thread,
                                          n_jobs=n_jobs,
                                          random_state=random_state)

            model.fit(train_x, train_y)

            train_prob = model.predict_proba(train_x)[:, 1]
            test_prob = model.predict_proba(test_x)[:, 1]
            oot_prob = model.predict_proba(oot_x)[:, 1]

            train_acc = round(accuracy_score(train_y, train_prob > 0.5), 5)
            train_auc = round(roc_auc_score(train_y, train_prob), 5)

            test_acc = round(accuracy_score(test_y, test_prob > 0.5), 5)
            test_auc = round(roc_auc_score(test_y, test_prob), 5)

            oot_acc = round(accuracy_score(oot_y, oot_prob > 0.5), 5)
            oot_auc = round(roc_auc_score(oot_y, oot_prob), 5)

            res_list.append({
                'train_acc': train_acc, 'train_auc': train_auc,
                'test_acc': test_acc, 'test_auc': test_auc,
                'oot_acc': oot_acc, 'oot_auc': oot_auc
            })

            if target == 'auc':
                target_value = test_auc
            else:
                target_value = test_acc

            print('[train_acc] {}, [train_auc] {}, [test_acc] {}, [test_auc] {}, [oot_acc] {}, [oot_auc] {}'.format(
                train_acc, train_auc, test_acc, test_auc, oot_acc, oot_auc), flush=True)

            return target_value

        print("[bayes_optimization] {}".format(self.params_dict[clf_name]), flush=True)
        clf_bo = BayesianOptimization(f=_eval, pbounds=self.params_dict[clf_name])
        clf_bo.maximize(**bayes_args)

        self.best_param = clf_bo.max['params']

        for param in int_params:
            if self.params_dict[clf_name].get(param):
                self.best_param[param] = int(round(self.best_param[param]))

        self.best_param['nthread'] = n_thread
        self.best_param['n_jobs'] = n_jobs
        self.best_param['random_state'] = random_state

        res_bo = []
        for id, bo in enumerate(clf_bo.res):
            for param in int_params:
                if bo['params'].get(param):
                    bo['params'][param] = int(round(bo['params'][param]))
            res_bo.append([bo.update(res_list[id])])

        return clf_bo, self.best_param, res_bo

    def eval(self, x, y):
        # 使用模型对测试集数据进行预测
        predictions = self.best_model.predict_proba(x)[:, 1]
        print("[MAE] {}".format(mean_absolute_error(y_true=y, y_pred=predictions)), flush=True)
        print("[ACC] {}".format(accuracy_score(y_true=y, y_pred=predictions > 0.5), flush=True))
        print("[AUC] {}".format(roc_auc_score(y_true=y, y_score=predictions)), flush=True)
        print("[confusion_matrix] \n{} ".format(confusion_matrix(y_true=y, y_pred=predictions > 0.5)), flush=True)

        return predictions

    def train(self, clf_name, x, y):
        print("[train] best_param: {}".format(self.best_param), flush=True)
        if clf_name == 'lgb':
            print("[train] use model: LGBMClassifier", flush=True)
            self.best_model = lgb.LGBMClassifier(**self.best_param)
        else:
            print("[train] use model: XGBClassifier", flush=True)
            self.best_model = xgb.XGBClassifier(**self.best_param)

        self.best_model.fit(x, y)
        print("[train] best_model: {}".format(self.best_model), flush=True)

        self.save_model()

模型训练示例

在进行模型训练的时候,就直接调用封装的GBDTModel类里面的函数即可,具体如下:

  • 进行贝叶斯自动调参,并保存最优的参数。(数据均用pandas的DataFrame保存)
use_columns = ['col_1', 'col_2', 'col_3', 'col_4']
label_columns = ['label']

train_manager = GBDTModel(output_dir="./")

train_manager.bayes_optimization(
    train_x=train_df[use_columns], train_y=np.array(train_df[label_columns]),
    test_x=test_df[use_columns], test_y=test_df[label_columns],
    oot_x=val_df[use_columns], oot_y=val_df[label_columns],
    clf_name="xgb"
)

train_manager.save_best_param(file_name="params.json")
  • 读取最优的参数,训练模型与评估
train_manager.read_best_param(file_name="params.json")
train_manager.train(clf_name="xgb",
                    x=train_data[use_columns], y=train_data[label_columns])

train_manager.eval(x=test_data[use_columns], y=test_data[label_columns])
train_manager.eval(x=val_data[use_columns], y=val_data[label_columns])

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【xgboost】贝叶斯自动调参代码 的相关文章

随机推荐

  • R语言学习笔记(三)数据处理

    本文的示例数据框集 egData 如下 值标签 if FALSE 值标签 levels代表变量实际值 labels代表标签值 egData sex lt factor egData sex levels c 1 2 labels c mal
  • WSL2+Docker+IDEA一站式开发调试

    WSL2 Docker IDEA一站式开发调试 将就看吧 不知道为什么CSDN无法转储并展示jsdelivr的图片 但博客园正常展示 前言 我们知道 Docker是一个容器引擎 对于开发者来说 使用Dokcer容器部署各种开发需要的中间件
  • linux端口开放指定端口的两种方法

    开放端口的方法 方法一 命令行方式 1 开放端口命令 sbin iptables I INPUT p tcp dport 8080 j ACCEPT 2 保存 etc rc d init d iptables save 3 重启服务 etc
  • 正则表达式和三剑客

    正则表达式与三剑客 Linux正则表达式 由一类特殊字符及文本字符所编写的模式 其中有些字符不表示其字面意义 而是用于表示控制或通配符的功能 分两类 基本正则表达式 BRE 扩展正则表达式 ERE 基本正则表达式DRE集合 元字符 作用 只
  • ROS环境搭建步骤总结

    ROS环境搭建踩坑总结 Ubuntu 16 04安装ROS Kinetic ROS安装 进入到 ROS官网选择安装的版本和系统 配置Ubuntu的repositories 以允许 restricted universe 和 multiver
  • vue element el-select下拉选择不回显问题

    el select下拉选择无效 问题描述 在使用Vue开发使用element ui时 el select下拉框出现在点击选择的时候数据无法显示的问题
  • MMX及SSE优化--SSE篇

    上回讲到针对整数运算的MMX优化技术 然而真正大运算量的图形和声音处理大都用的是浮点运算 而且现在对浮点运算的要求也是越来越高 在这样一个条件下INTEL终于在Pentium III处理中增加针对浮点运算优化的SSE指令 所以所有用过SSE
  • 初学者适合什么副业?适合初学者做的8个副业

    有网友曾说过 安全感是主业给的 但财富是靠副业创造的 可见 找一份靠谱的副业是多么的重要 但是 想找一份靠谱的副业 特别难 尤其是以前没有了解过的 看到各种副业吹嘘 根本无法下手 今天 聪少就给大家分享几个适合新手的副业 帮助大家快速走上副
  • 基于SpringBoot的外卖点餐管理系统

    项目背景 随着科学技术的飞速发展 各行各业都在努力与现代先进技术接轨 通过科技手段提高自身的优势社会的发展和科学技术的进步 互联网技术越来越受欢迎 网络计算机的生活方式逐渐受到广大人民群众的喜爱 也逐渐进入了每个用户的使用 互联网具有便利性
  • 基于STM32CUBEMX,HAL库蓝牙通信

    蓝牙通信 实现手机与stm32连接 1 准备工作 蓝牙模块HC 05模块 安卓APP软件 HC 05蓝牙模块支持AT指令 要进入AT指令模式 需要先按住蓝牙模块上的按键 接通电源 当模块上的LED灯进入慢闪后再松开按键 此时已经进入AT指令
  • vue-cli3.0引入高德地图3d效果两种方法+实例+填坑

    前言 因为项目需要引入高德地图的3d效果 找了很多资料 在这里记录下方法和实例组件 注意 因为两个方法代码量都特别大 这里分2个页面详细说一下 方法一是链接出去专门说 最下面有更多资料 高德3d官网地址和别的资料地址 方法一 使用官方案例
  • 掌握Python的X篇_32_使用python编辑pdf文件_pdfrw

    本篇介绍利用python操作pdf文件 我们平时也会有合并和拆分pdf的需求 此时我们就可以使用本节内容 文章目录 1 pdfrw的安装 2 切分pdf文件 3 pdfrw官网及实现一版四面的实例 1 pdfrw的安装 pip instal
  • React中函数组件和类式组件

    React中函数组件和类式组件 定义组件有两个要求 组件名称必须以大写字母开头 组件的返回值只能有一个根元素 1 函数组件 函数组件也称无状态组件 顾名思义就是通过函数编写的形式去实现一个React组件 是React中定义组件最简单的方式
  • 字符串 - 二进制和文本字符串 - 探究

    1 应用场景 主要用于探究字符串中的二进制和文本字符串 以及它们的区别和应用场景 2 学习 操作 1 文档阅读 重要来自于与chatgpt的对话问答 以及其他技术文章 2 整理输出 2 1 是什么 二进制和文本字符串都是计算机中常用的数据类
  • 相机触发模式

    一 图像采集模式分类 相机的图像采集模式分为内触发模式与外触发模式 其中内触发模式包含连续采集 单帧采集两种形式 外触发模式包含软件触发 硬件外触发 本文以海康相机的软件平台作介绍 该软件去海康机器人官网下载 内触发模式与外触发模式可以通过
  • matlab 降维工具

    降维工具箱drtool 这个工具箱的 主页如下 现在的最新版本是2013 3 21更新 版本v0 8 1b http homepage tudelft nl 19j49 Matlab Toolbox for Dimensionality R
  • 系统服务器地云盘上,系统服务器地云盘上

    系统服务器地云盘上 内容精选 换一换 磁盘增强型弹性云服务器自带高存储带宽和IOPS的本地盘 具有高存储IOPS以及读写带宽的优势 同时 本地盘的价格更加低廉 在海量数据存储场景下 具备更高的性价比 磁盘增强型弹性云服务器具备如下特点 本地
  • 依赖注入之@Value原理(整体流程)

    Autowired等注解 Spring依赖注入之 Autowired Qualifier Primary Priority注解用法 Spring依赖注入之 Autowired Qualifier Primary Priority注解原理 上
  • win10 蓝牙耳机已连接但是耳机仍没有声音,音频仍是扬声器输出问题的出现条件及解决方案

    此问题可能分电脑分耳机类型出现 本人因耳机Fill CC2连接笔记本频繁出现此问题故以此文记录 问题出现原因 疑似 1 笔记本后台挂的程序应用过多 且笔记本开机通电时间过长 2 连接蓝牙耳机时笔记本扬声器正在发声 解决方法 27条消息 wi
  • 【xgboost】贝叶斯自动调参代码

    工作中 很多场景下会用到xgboost模型 如风控 催收 营销 推荐等待 在用xgboost模型进行模型训练的时候 也经常用贝叶斯自动调参来搜索最优的参数 现在把相关的代码贴出来 供大家参考 目前是支持了xgboost和lightgbm模型