XGBoost算法-代码实现和网格调参

news2024/9/24 19:15:51

目录

导包

特征工程

基本模型

超参数优化


导包

import pandas as pd
import numpy as np
import xgboost as xgb
import pickle
import sys
import matplotlib.pyplot as plt
from sklearn.metrics import make_scorer
from sklearn.metrics import mean_absolute_error
from sklearn.preprocessing import LabelEncoder, LabelBinarizer
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold, train_test_split

from xgboost import XGBRegressor

import warnings

warnings.filterwarnings('ignore')
%matplotlib inline

%config InlineBackend.figure_format = 'retina'

特征工程

# 测试集特征
train = pd.read_csv('allstate-claims-severity/train.csv')
train['log_loss'] = np.log(train['loss'])
features = [x for x in train.columns if x not in ['id','loss','log_loss']]
cat_features =[x for x in train.select_dtypes(include = ['object']) if x not in ['id','loss','log_loss']]
num_features =[x for x in train.select_dtypes(exclude = ['object']) if x not in ['id','loss','log_loss']]
print('训练集-离散特征Categorical: {} features'.format(len(cat_features)))
print('训练集-连续值特征Numerical:{} features'.format(len(num_features)))

# 得到训练集x和y
train_x = train[features]
train_y = train['log_loss']

# 离散特征单独处理成pandas的category类型
for c in range(len(cat_features)):
    train_x[cat_features[c]] = train_x[cat_features[c]].astype('category').cat.codes
print('Xtrain:',train_x.shape) # Xtrain: (188318, 130)
print('ytrain:',train_y.shape) # ytrain: (188318,)

# 截止到这个位置,训练集已经可用
train_x
train_y

基本模型

import pandas as pd
import numpy as np
import xgboost as xgb
import matplotlib.pyplot as plt
from sklearn.metrics import mean_absolute_error
import warnings

warnings.filterwarnings('ignore')  # 忽略警告信息,以便输出更清晰

# 自定义评估函数,用于计算平均绝对误差(MAE)
def xg_eval_mae(yhat, dtrain):
    y = dtrain.get_label()
    # 对预测值和真实值进行指数变换,然后计算MAE
    return 'mae', mean_absolute_error(np.exp(y), np.exp(yhat))

# 定义XGBoost回归模型类
class XGBoostRegressor(object):
    def __init__(self, **kwargs):
        # 初始化模型参数,包括用户自定义参数和默认参数
        self.params = kwargs
        self.params.update({
            'verbosity': 0,  # 设置日志等级
            'objective': 'reg:squarederror',  # 设置目标函数为平方误差
            'seed': 0,  # 设置随机种子
            'num_boost_round': 100  # 设置boosting round的数量
        })
        self.bst = None  # 初始化模型对象为None

    def fit(self, x_train, y_train):
        # 训练模型
        dtrain = xgb.DMatrix(x_train, label=y_train)
        try:
            self.bst = xgb.train(
                params=self.params,  # 模型参数
                dtrain=dtrain,  # 训练数据
                num_boost_round=self.params['num_boost_round'],  # boosting round数量
                feval=xg_eval_mae,  # 自定义评估函数
                maximize=False  # 评估函数的最大化标志
            )
        except Exception as e:
            print("Error during training:", e)
            self.bst = None

    def predict(self, x_pred):
        # 预测函数
        if self.bst is None:
            raise ValueError("Model not trained. Call 'fit' before 'predict'.")
        dpred = xgb.DMatrix(x_pred)
        return self.bst.predict(dpred)

    def kfold(self, x_train, y_train, nfold=5):
        # 交叉验证函数
        dtrain = xgb.DMatrix(x_train, label=y_train)
        cv_results = xgb.cv(
            params=self.params,  # 模型参数
            dtrain=dtrain,  # 训练数据
            num_boost_round=self.params['num_boost_round'],  # boosting round数量
            nfold=nfold,  # 交叉验证的折数
            feval=xg_eval_mae,  # 自定义评估函数
            maximize=False,  # 评估函数的最大化标志
            early_stopping_rounds=10,  # 提前停止的轮数
            metrics={'mae'}  # 评估指标
        )
        return pd.DataFrame(cv_results)

    def plot_feature_importances(self):
        # 绘制特征重要性
        if self.bst is None:
            raise ValueError("Model not trained. Call 'fit' before plotting feature importances.")
        feat_imp = pd.Series(self.bst.get_score(importance_type='weight')).sort_values(ascending=False)
        feat_imp.plot(kind='bar', title='Feature Importances')
        plt.ylabel('Feature Importance Score')
        plt.show()

    def get_params(self, deep=True):
        # 获取模型参数
        return self.params

    def set_params(self, **params):
        # 设置模型参数
        self.params.update(params)
        return self

    def save_model(self, filepath):
        # 保存模型到本地文件
        if self.bst is not None:
            self.bst.save_model(filepath)
        else:
            raise ValueError("Model not trained. Call 'fit' before saving the model.")

# 特征工程
train = pd.read_csv('allstate-claims-severity/train.csv')
train['log_loss'] = np.log(train['loss'])  # 对target进行对数变换
features = [x for x in train.columns if x not in ['id', 'loss', 'log_loss']]  # 选择特征列
cat_features = [x for x in train.select_dtypes(include=['object']) if x not in ['id', 'loss', 'log_loss']]  # 选择类别特征
num_features = [x for x in train.select_dtypes(exclude=['object']) if x not in ['id', 'loss', 'log_loss']]  # 选择数值特征
print('训练集-离散特征Categorical: {} features'.format(len(cat_features)))
print('训练集-连续值特征Numerical: {} features'.format(len(num_features)))
train_x = train[features]
train_y = train['log_loss']

# 检查loss列是否为非负
if any(train['loss'] < 0):
    raise ValueError("Column 'loss' must be non-negative for log transformation.")

# 离散特征单独处理成pandas的category类型
for c in range(len(cat_features)):
    train_x[cat_features[c]] = train_x[cat_features[c]].astype('category').cat.codes

# 模型训练
bst = XGBoostRegressor(eta=0.1,
                       colsample_bytree=0.5,
                       subsample=0.5,
                       max_depth=5,
                       min_child_weight=3,
                       num_boost_round=100)
kfold_results = bst.kfold(train_x, train_y, nfold=5)

# 绘制MAE结果
kfold_results.mean(axis=1).plot(title='K-Fold MAE')
plt.xlabel('Boosting Round')
plt.ylabel('MAE')
plt.show()

# 再次训练模型
bst.fit(train_x, train_y)

# 保存模型到本地
model_filename = 'xgboost_model.json'
bst.save_model(model_filename)

test = pd.read_csv('allstate-claims-severity/test.csv')
test_x = test[features]

# 将类别数据的类别用数字替换
for c in range(len(cat_features)):
    test_x[cat_features[c]] = test_x[cat_features[c]].astype('category').cat.codes

# 预测命令:
test_y = bst.predict(test_x)

# 保存预测结果
test['predicted_loss'] = np.exp(test_y)
test[['id', 'predicted_loss']].to_csv('submission.csv', index=False)

bst.get_params()

在XGBoost中,这些超参数控制着模型的训练过程和行为。下面是每个超参数的含义:

  1. eta (学习率):
    • 控制每一步迭代中权重调整的幅度。较小的值意味着模型需要更多的迭代次数来训练,但可能会获得更好的性能和泛化能力。
  1. colsample_bytree (每棵树的特征采样比率):
    • 每棵树在训练时用到的特征数量的比例。值在0到1之间,用于随机特征选择,以增加模型的多样性并防止过拟合。
  1. subsample (训练样本的采样比率):
    • 训练每棵树时使用的样本比例。值在0到1之间,同样用于增加模型的多样性和防止过拟合。
  1. max_depth (树的最大深度):
    • 树的最大深度。树越深,模型越复杂,可能会有更好的性能,但也更容易过拟合。
  1. min_child_weight (子节点最小权重):
    • 决定最小数据权重和,需要在叶子节点上观察到进一步分裂。增加这个值可以防止模型学习到过于复杂的模式。
  1. num_boost_round (提升轮数):
    • 总共要执行的提升(boosting)轮数。更多的轮数可能会提高模型的性能,但也可能增加过拟合的风险。
  1. verbosity (日志等级):
    • 控制XGBoost打印的输出信息的详细程度。等级越高,打印的信息越少。
  1. objective (目标函数):
    • 指定学习任务和相应的学习目标或预测类型。在这个例子中,'reg:squarederror' 表示回归任务,使用平方误差作为损失函数。
  1. seed (随机种子):
    • 控制随机数生成器的种子。用于结果的可重复性。

这些超参数的合理设置对于模型的性能至关重要。通常,需要通过交叉验证等方法来调整这些参数,以找到最佳的模型配置。

{'eta': 0.1,
 'colsample_bytree': 0.5,
 'subsample': 0.5,
 'max_depth': 5,
 'min_child_weight': 3,
 'num_boost_round': 100,
 'verbosity': 0,
 'objective': 'reg:squarederror',
 'seed': 0}

超参数优化

利用GridSearchCV算法,找出最合适的num_boost_round和学习率eta超参数

import pandas as pd
import numpy as np
import xgboost as xgb
import matplotlib.pyplot as plt
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.metrics import mean_absolute_error
import warnings

warnings.filterwarnings('ignore')  # 忽略警告信息,以便输出更清晰

# 读取数据并进行预处理
train = pd.read_csv('allstate-claims-severity/train.csv')
train['log_loss'] = np.log(train['loss'])  # 对target进行对数变换
features = [x for x in train.columns
            if x not in ['id', 'loss', 'log_loss']]  # 选择特征列
cat_features = [
    x for x in train.select_dtypes(include=['object'])
    if x not in ['id', 'loss', 'log_loss']
]  # 选择类别特征
for c in cat_features:
    train[c] = train[c].astype('category').cat.codes  # 将类别特征转换为数值

train_x = train[features]
train_y = train['log_loss']

# 划分训练集和验证集
x_train, x_val, y_train, y_val = train_test_split(train_x,
                                                  train_y,
                                                  test_size=0.2,
                                                  random_state=0)

# 设置XGBoost模型和参数网格
xgb_reg = xgb.XGBRegressor(colsample_bytree=0.5,
                           subsample=0.5,
                           max_depth=5,
                           min_child_weight=3,
                           objective='reg:squarederror',
                           seed=0)

# 设置GridSearchCV
param_grid = {
    'n_estimators': [100, 200, 300, 400, 500],  # 尝试不同的num_boost_round值
    'eta': [0.01, 0.05, 0.1, 0.2]  # 尝试不同的学习率
}
grid_search = GridSearchCV(estimator=xgb_reg,
                           param_grid=param_grid,
                           scoring='neg_mean_absolute_error',
                           cv=3,
                           verbose=1)
grid_search.fit(x_train, y_train)

# 打印最佳参数和得分
print("Best parameters:", grid_search.best_params_)
print("Best MAE:", -grid_search.best_score_)

# 打印每个参数组合及其得分
results = grid_search.cv_results_
for mean_score, params in zip(results['mean_test_score'], results['params']):
    print(np.sqrt(-mean_score), params)  # 打印MAE而不是负MAE

# 使用最佳参数再次训练模型
best_params = grid_search.best_params_
best_xgb_reg = xgb.XGBRegressor(n_estimators=best_params['n_estimators'],
                                eta=best_params['eta'],
                                colsample_bytree=0.5,
                                subsample=0.5,
                                max_depth=5,
                                min_child_weight=3,
                                objective='reg:squarederror',
                                seed=0)
best_xgb_reg.fit(x_train, y_train)

# 预测验证集
predictions = best_xgb_reg.predict(x_val)
mae = mean_absolute_error(y_val, predictions)
print("Validation MAE:", mae)

# 绘制验证集的MAE结果
plt.figure()
plt.plot(predictions, label='Predictions')
plt.plot(y_val.values, label='True Values')
plt.legend()
plt.title('XGBoost Predictions vs True Values')
plt.xlabel('Sample Index')
plt.ylabel('Log Loss')
plt.show()

这段执行结果提供了通过GridSearchCV进行的模型超参数优化和验证的细节。以下是对这些输出的解释:

  1. 交叉验证过程:
    • "Fitting 3 folds for each of 2 candidates, totalling 6 fits" 表示GridSearchCV使用了3折交叉验证来评估两个不同的参数组合(在这个例子中是n_estimators的值)。总共进行了6次拟合(3折 x 2参数值)。
  1. 最佳参数和得分:
    • "Best parameters: {'n_estimators': 200}" 表示在测试的参数组合中,当n_estimators(即提升树的数量)设置为200时,模型的性能最佳。
    • "Best MAE: 0.4214897722016709" 显示了使用最佳参数时的平均绝对误差(MAE)。这是在交叉验证过程中得到的最优结果。
  1. 每个参数组合的得分:
    • "0.6529385343493455 {'n_estimators': 100}" 和 "0.6492224366129615 {'n_estimators': 200}" 显示了每个参数组合的平均测试分数。这里显示的分数是负MAE,因为GridSearchCV默认是寻找最小化的目标,所以使用负数表示。正值0.6529385343493455和0.6492224366129615实际上是MAE值,其中较小的值(对应n_estimators为200)表示更好的性能。
  1. 验证集上的MAE:
    • "Validation MAE: 0.41929878566038986" 表示在独立的验证集上,使用最佳参数(n_estimators=200)训练的模型的平均绝对误差。这个值用于最终评估模型在未知数据上的性能。

理解关键点:

  • 较小的MAE值 表示模型预测与实际值之间的误差较小,即模型的预测性能较好。
  • 交叉验证 是一种重要的技术,用于评估不同参数设置下模型的稳健性和泛化能力。
  • GridSearchCV 提供了一个系统的方法来尝试多种参数组合,找到最优的模型配置。

在实际应用中,这些信息帮助我们理解模型在不同配置下的表现,并选择最佳的模型参数进行最终的模型部署和预测。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2121729.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

什么是话费充值api接口?话费充值API接口如何对接?

话费充值 API 接口对接相关信息 对接方式 通过技术人员对接&#xff1a;会专门将自己的小程序或者 app 对接到充值平台&#xff0c;通过接口提交号码和金额进行充值&#xff0c;提交一笔订单充值一笔。 对接优势 高效完善&#xff1a;能够使得整个话费充值的流程便捷&#…

电信AEP平台WEB在线开发经验总结

目录 一、服务器环境搭建 二、Web应用服务器安装 三、tomcat的SSL证书部署 四、电信AEP平台WEB在线开发域名管理 五、效果展示 一、服务器环境搭建 首先得购买服务器&#xff0c;比如华为云、腾讯云的轻量应用服务器都可以。然后购买域名并进行ICP备案&#xff0c;最后对…

数据结构——顺序表中基本操作的实现

前言 该部分知识参考于《数据结构&#xff08;C语言版 第2版&#xff09;》24~28页 &#x1f308;每一个清晨&#xff0c;都是世界对你说的最温柔的早安&#xff1a;ૢ(≧▽≦)و✨ 注意 这里的ElemType是以Book类型的数据作为举例&#xff0c;如果需要更改可以自行改变&…

基于SpringBoot的古城墙景区管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的古城墙景区管理系…

【C++题解】1275. 输出杨辉三角的前N行

欢迎关注本专栏《C从零基础到信奥赛入门级&#xff08;CSP-J&#xff09;》 问题&#xff1a;1275. 输出杨辉三角的前N行 类型&#xff1a;二维数组 题目描述&#xff1a; 输出杨辉三角的前 N 行( N<10 )。 输入&#xff1a; 输入只有一行&#xff0c;包括 1 个整数 N …

【Unity】【游戏开发】unity中快速导入VRM模型并应用动画

【背景】 之前介绍了不少通过Blender为中介,Match Rig应用Mixamo动画后导入Unity的方法。不过由于texture等的问题,这种方法有时显得效率太低,还需要自己改写材质的nodes,避免导入Unity后出现不适应。所以本篇寻求更高效的下载和导入VRM模型,Mixamo动画到Unity的方法。 …

2024 年 8 月区块链游戏研报:用户增长与加密货币市场波动并存

作者&#xff1a;Stella L (stellafootprint.network) 数据来源&#xff1a;Footprint Analytics Games Research 页面 8 月&#xff0c;加密货币市场面临严峻挑战&#xff0c;比特币和以太币的价值都大幅下跌。比特币下跌了 9.3%&#xff0c;而以太坊的跌幅更为严重&#x…

Resnet图像识别入门——池化层

前面的文章[Resnet图像识别入门——激活函数]介绍了3中常见的激活函数&#xff0c;以及激活函数在神经网络中的作用。 在CNN网络中&#xff0c;除了激活函数之外&#xff0c;还有一种算法也是很常见的&#xff0c;那就是池化层。在Resnet50中&#xff0c;就存在一个最大池化层…

VSCode GDB调试控制台只能查看变量不能执行调试命令的解决方案-var-create: unable to create variable object

背景 在使用VSCode进行GDB调试时&#xff0c;想使用x命令看一下某地址处的数值。然而&#xff0c;却给了报错而不显示&#xff1a; -var-create: unable to create variable object 这是啥原因呢&#xff1f; 解决方案 其实&#xff0c;在刚刚开始调试程序时&#xff0c;就以…

大数据Flink(一百一十四):PyFlink的作业开发入门案例

文章目录 PyFlink的作业开发入门案例 一、批处理的入门案例 1、示例 2、​​​​​​​​​​​​​​开发步骤 3、参考代码&#xff1a;基于DataStreamAPI编程 二、​​​​​​​​​​​​​​流处理的入门案例 1、​​​​​​​​​​​​​​示例 2、​​​​​…

2024年10款好用的文件加密软件!企业文件防泄密最佳选择

在数字化时代&#xff0c;数据安全已成为企业生存和发展的关键。随着企业数据量的不断增长&#xff0c;如何有效保护敏感信息免受未经授权的访问和泄露&#xff0c;成为企业面临的重要挑战。文件加密软件作为一种有效的数据保护工具&#xff0c;能够帮助企业确保数据的安全性和…

手机投屏到电脑怎么弄?

远程看看是一款免费的远程控制软件&#xff0c;它支持Windows、iOS和Android等多个系统&#xff0c;并且提供了文件传输、手机投屏、在线聊天等多种功能。我们可以使用远程看看软件进行手机投屏&#xff0c;从而帮助您的家人或朋友解决相应的手机问题。 1. 首先&#xff0c;将…

【运维方案】信息系统运维方案(Word完整版)

1 编制目的 2 系统运行维护 2.1 系统运维内容 2.2 日常运行维护方案 2.2.1 日常巡检 2.2.2 状态监控 2.2.3 系统优化 2.2.4 软件系统问题处理及升级 2.2.5 系统数据库管理维护 2.2.6 灾难恢复 2.3 应急运行维护方案 2.3.1 启动应急流程 2.3.2 成立应急小组 2.3.3 应急处理过程 …

如何给电脑设置静态IP地址:详细步骤与指南

在日常生活和工作中&#xff0c;我们经常需要使用电脑连接到网络。通常情况下&#xff0c;电脑会自动获取IP地址&#xff0c;但有时候&#xff0c;由于特定的网络需求或配置&#xff0c;我们可能需要手动为电脑设置静态IP地址。本文将详细介绍如何在Windows和Mac操作系统中为电…

操作系统 ---- 【2.3】进程控制

零、学习路线 一、什么是进程控制&#xff1f; 进程控制是进程管理中最基本的功能&#xff0c;主要包括创建新进程、终止已完成的进程、将因发生异常情况而无法继续运行的进程置于阻塞状态、负责进程运行中的状态转换等功能。如当一个正在执行的进程因等待某事件而暂时不能继续…

828华为云征文|docker部署overleaf搭建属于自己的论文编辑服务

1.介绍 1.1 什么是华为云Flexus X实例 最近华为云828 B2B企业节正在举办&#xff0c;Flexus X实例的促销也非常给力&#xff0c;大家可以去看看。特别是对算力性能有要求&#xff0c;同时对自建MySQL、Redis、Nginx性能有要求的小伙伴&#xff0c;千万不要错过。Flexus云服务器…

mysql datatime数据类型比实际多一秒问题

问题&#xff1a; 在项目上突然发现两个同一个Date时间存入数据库&#xff08;datetime类型&#xff09;和按照yyyy-MM-dd HH:mm:ss格式化时候有时候会相差一秒。 如下图&#xff1a; 格式为字符串为2024-09-10 14:18:41 存入数据库为2024-09-10 14:18:42 原因 SimpleDateF…

蚂蚁数科,独行的170天和未来新征程

文&#xff5c;白鸽 编&#xff5c;王一粟 9月5日&#xff0c;是赵闻飙上任蚂蚁数科公司首任CEO的第170天&#xff0c;也是蚂蚁数科独立运营的第170天。 在此期间&#xff0c;赵闻飙和蚂蚁数科都经历了角色上的转变。 “接手蚂蚁数科的170天里&#xff0c;我一直在思考一个…

如果美国衰退现货黄金市场怎样分析

近期美国的制造业PMI与劳动力市场超预期地下滑&#xff0c;这令市场对于美国经济“硬着陆”的预期有所增强。7月美国非农就业数据的大幅下降&#xff0c;触发了“萨姆规则”&#xff0c;该指标用于预测经济衰退的开始&#xff0c;而且自从1950年以来&#xff0c;每次都能成功识…

掌握LLM大模型基础!你的AI知识库升级秘籍在这里!

在这个已经被AI大模型包围的时代&#xff0c;不了解一点大模型的基础知识和相关概念&#xff0c;可能出去聊天都接不上话。刚好近期我也一直在用GPT和GitHub Copilot&#xff0c;也刚好对这些基础知识很感兴趣&#xff0c;于是学习了一下&#xff0c;做了如下的整理总结&#x…