Scikit-Learn 和 Caret 中的梯度提升分类器

Joshua Noble

Data Scientist

梯度提升分类器

梯度提升是数据科学中一种强大且广泛使用的机器学习算法,用于分类任务。它与装袋方法一起,是集成学习方法家族的一部分,通过组合多个更简单模型的预测来提高整体性能。梯度提升回归使用梯度提升来更好地基于线性回归生成输出数据。本教程中将介绍一种梯度提升分类器,它使用梯度提升来更好地将输入数据分类为属于两个或多个不同的类别。 

梯度提升是 Adaboost 算法的更新,它使用决策树桩而非决策树。这些决策树桩类似于随机森林中的树,但它们只有一个节点和两片叶子。梯度提升算法按顺序构建模型,每个步骤都试图纠正上一次迭代的错误。训练过程通常从创建一个弱学习器(例如用于训练数据的浅层决策树)开始。经过初始训练后,梯度提升法会计算实际值和预测值之间的误差(通常称为残差),然后训练一个新的估计器来预测此误差。将该新树添加到集成中,以更新预测,从而创建一个强大的学习器。梯度提升会重复此过程,直到改进停止或达到固定的迭代次数。提升方法本身类似于梯度下降 ,但通过引入新模型来“下降”梯度。

提升方法有几个优点:它在表格数据上表现良好,并且可以处理数值和分类数据。即使使用默认参数也能良好工作,并且对数据集中的异常值具有稳健性。然而,它的训练速度可能很慢,而且通常对训练过程中设置的超参数非常敏感。在处理大型数据集时,保持较小的树数量可以加快训练过程。此步骤通常是通过最大深度参数完成的。如果调整不当,梯度提升方法也容易造成过拟合。为防止过拟合,您可以配置训练过程中的学习率。对于分类器或梯度提升回归器,此过程大致相同,并用于流行的 xgboost,它通过添加正则化在梯度提升的基础上构建。

在本教程中,您将学习如何使用两种不同的编程语言和梯度提升库,通过流行的 Palmer Penguins 数据集对企鹅进行分类。

您可以从 Github 下载本教程的笔记本。

第 1 步 创建 R 笔记本

虽然您可以选择多种工具,本教程将引导您如何设置 IBM 帐户以使用 Jupyter Notebook。

使用您的 IBM Cloud 帐户登录 watsonx.ai

创建 watsonx.ai 项目

您可以从项目内部获取项目 ID。点击管理选项卡。然后,从常规页面的详细信息部分复制项目 ID。您需要此 ID 来完成本教程。

创建一个 Jupyter Notebook

创建笔记本时,请务必选择“Runtime 24.1 on R 4.3 S (4 vCPU 16 GB RAM)”。此步骤将打开 Jupyter Notebook 环境,您可以在其中复制本教程中的代码。或者,您可以将此笔记本下载到本地系统并将其作为资产上传到您的 watsonx.ai 项目。要查看更多 Granite 教程,请访问 IBM Granite 社区。您可以在 GitHub 上找到 Jupyter Notebook。

第 2 步 配置库和数据

在 R 中,caret 库是一个功能强大的工具,可用于通用数据准备和模型拟合。您将使用它来准备数据并训练模型本身

install.packages('gbm')
install.packages('caret')
install.packages('palmerpenguins')

library(gbm)
library(caret)  
library(palmerpenguins)

head(penguins) # head() returns the top 6 rows of the dataframe
summary(penguins) # prints a statistical summary of the data columns

使用 caret 包的 createDataPartition 函数将原始数据集分割为训练集和测试集,按 70% 训练和 30% 测试划分。


dim(penguins)

# get rid of any NA

penguins <- na.omit(penguins)
parts = caret::createDataPartition(penguins$species, p = 0.7, list = F)

train = penguins[parts, ]
test = penguins[-parts, ]

现在准备进行训练与测试。

第 3 步 训练和测试

Caret 库中的训练方法使用 R 公式,其因变量(通常也称为目标变量)位于波浪符“~”的左侧。独立变量(通常也称为特征变量)位于“~”的右侧。例如:

height ~ age

此步骤根据年龄预测身高。要训练 caret,您需要传入公式、训练数据及所用方法。Caret 库提供了许多不同类型训练的方法,因此将方法设置为“gbm”就是指定使用梯度提升。下一个参数用于配置训练过程。“repeatedcv”方法对训练集数据点的子样本执行 X 折交叉验证。此处,您可以通过为每个交叉验证使用一组不同的折叠集来指定 5 折交叉验证的 3 次重复。

model_gbm <- caret::train("species ~ .",
                          data = train,
                          method = "gbm", # gbm for gradient boosting machine
                          trControl = trainControl(method = "repeatedcv", 
                                                   number = 5, 
                                                   repeats = 3, 
                                                   verboseIter = FALSE),
                          verbose = 0)

现在您可以使用预测模型对测试数据进行预测:

pred_test = caret::confusionMatrix(
  data = predict(model_gbm, test),
  reference = test$species
)

print(pred_test)

此步骤输出:

Confusion Matrix and Statistics
           Reference
Prediction  Adelie Chinstrap Gentoo
  Adelie        42         0      0
  Chinstrap      0        20      0
  Gentoo         1         0     35

Overall Statistics
                                          
               Accuracy : 0.9898          
                 95% CI : (0.9445, 0.9997)
    No Information Rate : 0.4388          
    P-Value [Acc > NIR] : < 2.2e-16       
                  Kappa : 0.984           

 Mcnemar's Test P-Value : NA              

Statistics by Class:
                     Class: Adelie Class: Chinstrap Class: Gentoo
Sensitivity                 0.9767           1.0000        1.0000
Specificity                 1.0000           1.0000        0.9841
Pos Pred Value              1.0000           1.0000        0.9722
Neg Pred Value              0.9821           1.0000        1.0000
Prevalence                  0.4388           0.2041        0.3571
Detection Rate              0.4286           0.2041        0.3571
Detection Prevalence        0.4286           0.2041        0.3673
Balanced Accuracy           0.9884           1.0000        0.9921

由于交叉验证的折间特性,每个类别的敏感性和特异性可能与此处观测值略有差异,但准确率保持一致。即使仅占训练数据集 20% 的 Chinstrap 企鹅类别,模型准确率也相当理想。

第 4 步 创建 Python 笔记本

现在您将学习如何在 Python 中创建梯度提升模型。在先前创建的同一项目中,创建一个 Jupyter Notebook。

请确保在 IBM Watson Studio 中使用 Python 3.11 创建 Jupyter Notebook。创建笔记本时,请务必选择“Runtime 24.1 on Python 3.11 XXS (1 vCPU 4 GB RAM)”。您现在已准备好使用 Python 创建梯度提升分类器。

第 5 步 配置库和数据

本步骤安装用于训练和测试梯度提升分类器的库。训练本身通过 scikit-learn 完成的,数据来自 palmerpenguins 库。

!pip install seaborn pandas scikit-learn palmerpenguins

现在将库安装到笔记本环境:

import pandas as pd
import seaborn as sns
from sklearn.compose import ColumnTransformer
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import classification_report
from sklearn.model_selection import cross_val_score, train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from palmerpenguins import load_penguins

与 R 代码一样,企鹅数据集中有一些 NA 需要删除。此代码段加载数据集,删除所有 NA 行,然后将数据拆分为特征和目标。

# Load the penguins
penguins = load_penguins() #initialize the dataset
penguins = penguins.dropna()
X = penguins.drop("species", axis=1)
y = penguins["species"]

现在将数据集分为训练和测试两部分,其中 70% 的数据用于训练,30% 的数据用于测试。

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

接下来,您将收集两个列名列表,一个用于 X 的分类特征,另一个用于 X 的数字特征,例如float64 或 int64。然后,使用 scikit-learn 中的 columnTransformer 对不同的列类型应用不同的预处理。对分类特征应用 OneHotEncoder,将其转换为二元向量。对数值特征应用 StandardScaler 将其标准化为均值 f0、方差 1。


# Define categorical and numerical features
categorical_features = X.select_dtypes(
   include=["object"]
).columns.tolist()

numerical_features = X.select_dtypes(
   include=["float64", "int64"]
).columns.tolist()

preprocessor = ColumnTransformer(
   transformers=[
       ("cat", OneHotEncoder(), categorical_features),
       ("num", StandardScaler(), numerical_features),
   ]
)

第 6 步 训练和测试

完成特征集和预处理器创建后,可构建训练模型的管道了。该管道先对输入数据执行预处理,然后传递给梯度提升算法构建分类器。对于更大型或更复杂的数据集,您可能还需要配置其他训练参数。例如,max_features 可以设置寻找最佳分割时要考虑的特征数量,而 max_depth 可以限制树中的节点数量。此代码片段设置条件参数,用于衡量训练拆分的质量。在这种情况下,我们使用 [Jerry Friedman] (https://jerryfriedman.su.domains/ftp/trebst.pdf)(位于 IBM 外部)改进的均方误差。

pipeline = Pipeline([
       ("preprocessor", preprocessor),
       ("classifier", GradientBoostingClassifier(random_state=42, 
         criterion='friedman_mse', max_features=2)),
   ])

接下来执行交叉验证以评估机器学习管道在训练数据上的表现。调用所创建管道的拟合方法对模型进行训练。损失函数默认使用均方误差(或 MSE)。

# Perform 5-fold cross-validation
cv_scores = cross_val_score(pipeline, X_train, y_train, cv=5)

# Fit the model on the training data
pipeline.fit(X_train, y_train)

现在模型已训练,对测试集进行预测并检验性能:


# Predict on the test set
y_pred = pipeline.predict(X_test)

# Generate classification report
report = classification_report(y_test, y_pred)

输出结果:

print(f"Mean Cross-Validation Accuracy: {cv_scores.mean():.4f}")
print("\nClassification Report:")
print(report)

本步骤输出以下结果:

Mean Cross-Validation Accuracy: 0.9775
Classification Report:
              precision    recall  f1-score   support
      Adelie       1.00      1.00      1.00        31
   Chinstrap       1.00      1.00      1.00        18
      Gentoo       1.00      1.00      1.00        18
    accuracy                           1.00        67
   macro avg       1.00      1.00      1.00        67
weighted avg       1.00      1.00      1.00        67

这些结果与本教程第一部分 R 方法报告的准确率高度接近。

相关解决方案
IBM watsonx.ai

使用面向 AI 构建器的新一代企业级开发平台 IBM watsonx.ai,可以训练、验证、调整和部署生成式 AI、基础模型和机器学习功能。使用一小部分数据,即可在很短的时间内构建 AI 应用程序。

了解 watsonx.ai
人工智能 (AI) 解决方案

借助 IBM 业界领先的人工智能专业知识和解决方案组合,让人工智能在您的业务中发挥作用。

深入了解 AI 解决方案
AI 咨询与服务

通过增加 AI 重塑关键工作流程和运营,最大限度提升体验、实时决策和商业价值。

深入了解人工智能服务
采取后续步骤

一站式访问跨越 AI 开发生命周期的功能。利用用户友好型界面、工作流并访问行业标准 API 和 SDK,生成功能强大的 AI 解决方案。

深入了解 watsonx.ai 预约实时演示