XGBoost - 使用超参数进行调整

在本章中,我们将讨论 XGBoost 模型超参数调整的关键问题。超参数是控制算法如何学习的特定数字或权重。正如我们在上一章中已经看到的,XGBoost 提供了广泛的超参数。通过修改 XGBoost 的超参数,我们可以最大限度地提高其效率。XGBoost 以其自动调整数千个可学习参数以在数据中寻找模式和规律的能力而闻名。

在每个节点选择的决策变量是基于树的模型(如 XGBoost)的可学习参数。设计决策数量的增加将导致超参数增大。这些是算法训练时使用的参数,并且保持不变。

基于树的模型中的超参数包括最大树深度、要生长的树的数量、构建每棵树时要考虑的变量数量、最小叶子样本数量以及用于构建树的观测分数。但本章的重点是最大化 XGBoost 超参数,此处介绍的技术适用于任何其他高级 ML 方法。

使用超参数调整 XGBoost

现在我们将看到如何在超参数的帮助下调整我们的 XGBoost 模型 −

1.导入库

首先,您需要按照以下代码导入所有必要的库 −

# 导入 pandas 用于处理数据
import pandas as pd

# 导入 numpy 用于科学计算
import numpy as np

# 导入 XGBoost 用于机器学习
import xgboost as xgb
from sklearn.metrics import accuracy_score

# 导入库用于调整超参数
from hyperopt import STATUS_OK, Trials, fmin, hp, tpe

2. 读取数据集

现在我们将读取我们的数据集。这里我们使用 Wholesale-customers-data.csv 数据集。

data = '/Python/Wholesale customers data.csv'

df = pd.read_csv(data)

3.声明特征向量和目标变量

现在我们需要声明特征向量和目标变量 −

X = df.drop('Channel', axis=1)

y = df['Channel']

现在让我们看一下特征向量 (X) 和目标变量 (y)。

X.head()
y.head()

输出

这是上述步骤的结果 −

0    2
1    2
2    2
3    1
4    2
Name: Channel, dtype: int64

我们可以看到 y 标签的值为 1 和 2。为了进一步分析,我们必须将其转换为 0 和 1。因此我们将按如下方式执行 -

# 将标签更改为二进制值

y[y == 2] = 0

y[y == 1] = 1

我们再次检查 y 标签 −

# 现在再次查看 y 标签

y.head()

这是上述部分的结果 −

0    0
1    0
2    0
3    1
4    0
Name: Channel, dtype: int64

所以你可以在这里看到我们的目标变量(y)被转换为 0 和 1。

4. 将数据拆分为单独的训练集和测试集

现在我们将把上述数据拆分为单独的训练集和测试集。按如下方式操作 −

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 0)

使用 HYPEROPT 进行贝叶斯优化

贝叶斯优化是寻找机器学习或深度学习算法的最佳参数的过程。优化是确定最低成本函数的过程,该函数可使模型在训练集和测试集上的整体性能更好。

在这种方法中,我们将使用各种参数范围训练模型,直到找到最佳拟合。超参数调整有助于找到最佳调整参数并返回最佳拟合模型,这是构建 ML 或 DL 算法时应遵循的最佳方法。

本章讨论了最精确和最成功的超参数调整方法之一,即使用 HYPEROPT 的贝叶斯优化。

什么是 HYPEROPT?

HYPEROPT 是一个高级 Python 包,它在超参数值空间中搜索以找到最小化损失函数的最佳选项。

贝叶斯优化方法使用 Hyperopt 来调整模型超参数。 Hyperopt 是一个用于调整模型超参数的 Python 库。

贝叶斯优化实现

优化过程有 4 个部分:初始化域空间、定义目标函数、优化算法和结果。因此,让我们在这里逐一讨论这些部分 −

1. 初始化域空间

域空间指的是我们要搜索的输入值。以下是您可以看到的代码 −

# 使用 Hyperopt 设置用于调整的超参数
space = {
    'max_depth': hp.quniform('max_depth', 3, 10, 1),
    'learning_rate': hp.uniform('learning_rate', 0.01, 0.2),
    'n_estimators': hp.quniform('n_estimators', 50, 300, 50),
    'subsample': hp.uniform('subsample', 0.5, 1),
    'colsample_bytree': hp.uniform('colsample_bytree', 0.5, 1),
    'gamma': hp.uniform('gamma', 0, 0.5),
    'lambda': hp.uniform('lambda', 0, 1),
    'alpha': hp.uniform('alpha', 0, 1)
}

2. 定义目标函数

目标函数是生成我们想要最小化的实值的任何函数。在这种情况下,我们专注于减少 ML 模型相对于其超参数的验证误差。如果准确度确实有价值,我们需要最大化它。然后代码应该返回度量的负值。

# 定义用于超参数调整的目标函数
def objective(space):
    clf=xgb.XGBClassifier(
                    n_estimators =space['n_estimators'], max_depth = int(space['max_depth']), gamma = space['gamma'],
                    reg_alpha = int(space['reg_alpha']),min_child_weight=int(space['min_child_weight']),
                    colsample_bytree=int(space['colsample_bytree']))
    
    evaluation = [( X_train, y_train), ( X_test, y_test)]
    
    clf.fit(X_train, y_train,
            eval_set=evaluation, eval_metric="auc",
            early_stopping_rounds=10,verbose=False)
    

    pred = clf.predict(X_test)
    accuracy = accuracy_score(y_test, pred>0.5)
    print ("SCORE:", accuracy)
    return {'loss': -accuracy, 'status': STATUS_OK }

3. 优化算法

这是构建替代目标函数并选择下一个要评估的值的过程。

# 运行 Hyperopt 以找到最佳超参数
trials = Trials()
best = fmin(
   fn=objective, 
   space=space, 
   algo=tpe.suggest, 
   max_evals=50, 
   trials=trials
)

4. 打印结果

结果是算法用于构建模型的分数或值对。

# 打印最佳超参数
print("Best Hyperparameters:", best)

输出

Best Hyperparameters: {'alpha': 0.221612523499914, 'colsample_bytree': 0.7560822278126258, 'gamma': 0.05019667254058424, 'lambda': 0.3047164013099425, 'learning_rate': 0.019578072539274467, 'max_depth': 9.0, 'n_estimators': 150.0, 'subsample': 0.7674996723810256}