所有文章 > AI驱动 > R语言实现XGBoost以及绘制ROC曲线和混淆矩阵

R语言实现XGBoost以及绘制ROC曲线和混淆矩阵

XGBoost(eXtreme Gradient Boosting)是一种基于梯度提升树(Gradient Boosting Tree)的机器学习算法,适用于分类和回归问题。

XGBoost的特点和优势

  • 高性能: XGBoost通过多线程处理和优化算法,以及针对大规模数据集的特殊处理,实现了快速高效的训练和预测。这使得它在处理大规模数据和高维特征时表现优异。
  • 可扩展性: XGBoost可以处理数十万个特征的数据集,并且能够在分布式环境下进行并行计算,使其适用于大规模的实际应用。
  • 正则化: XGBoost支持L1和L2正则化项,有助于控制模型的复杂性,避免过拟合,并提高模型的泛化能力。
  • 树剪枝: XGBoost采用“深度优先生长”的方法构建决策树,并在构建过程中进行剪枝,从而避免了过拟合问题,并减少了内存消耗。
  • 缺失值处理: XGBoost能够自动处理缺失值,无需对缺失值进行填充。
  • 特征重要性评估: XGBoost提供了评估特征重要性的功能,可以帮助用户识别哪些特征对于模型的预测能力更为重要。

下面讲一下如何在R中实现XGBoost

R语言实现XGBoost

测试数据和代码

链接:https://pan.baidu.com/s/1v1zAfE95lIgaObak0trt4Q 提取码:o0r3

# 导入必要的包,没有安装的可以先安装一下
library(dplyr) #数据处理使用
library(data.table) #数据读取使用
library(xgboost) #模型使用
library(Matrix) #模型数据处理使用
library(caret) # 调参和计算模型评价参数使用
library(pROC) #绘图使用
library(ggplot2) #绘图使用
library(ggpubr) #绘图使用
library(ggprism) #绘图使用
# 读取数据
data <- fread("./XGBoost.txt",data.table = F) # 替换为你的数据文件名或路径

数据长这个样子,一共35727行,214列。每一行代表一个样本,第一列是样本标签malignantnormal,后面213列是213个特征。我们想根据213个特征,使用RF训练出一个能够对样本进行精准分类的模型

构建XGBoost模型

# 将分类转换成0和1
data <- data %>% mutate(type = ifelse(type == "normal",1,0))
# 分割数据为训练集和测试集
set.seed(123) # 设置随机种子,保证结果可复现
split <- sample.split(data$type, SplitRatio = 0.8) # 将数据按照指定比例分割
train_data <- subset(data, split == TRUE) # 训练集
test_data <- subset(data, split == FALSE) # 测试集

# 定义训练集特征和目标变量
X_train <- train_data[, -1]
y_train <- train_data[, 1]

# 将特征和目标变量转换为DMatrix格式
dtrain <- xgb.DMatrix(data = as.matrix(X_train), label = y_train)
# 设置XGBoost参数
params <- list(objective = "binary:logistic", eval_metric = "logloss", eta = 0.1, max_depth = 3)
# 设置迭代轮数(树的数量)
nrounds <- 100
# 训练XGBoost模型
xgb_model <- xgboost(params = params, data = dtrain, nrounds = nrounds)

# 在训练集上进行预测
train_predictions <- predict(xgb_model, newdata = dtrain)
train_predictions <- ifelse(train_predictions > 0.5,1,0)

# 计算准确率
accuracy <- mean(train_predictions == y_train)
print(paste("训练集准确率:", accuracy))

# 在测试集上进行预测
X_test <- test_data[, -1]
y_test <- as.factor(test_data[, 1])

dtest <- xgb.DMatrix(data = as.matrix(X_test))
test_predictions <- predict(xgb_model, newdata = dtest)
test_predictions <- ifelse(test_predictions > 0.5,1,0)

# 计算准确率
accuracy <- mean(test_predictions == y_test)
print(paste("测试集准确率:", accuracy))

从accuracy来看,初始模型在训练集和测试集中表现的都挺好的。

使用caret包进行调参

caret包中,XGBoost模型有七个参数可以进行调节。

  • nrounds:迭代轮数,即树的数量。它决定了模型的复杂度和训练时间,通常需要根据数据集大小和模型性能进行调整。
  • max_depth:每棵树的最大深度。它控制树的复杂度,较大的值可能会导致过拟合,较小的值可能会导致欠拟合。
  • eta:学习率(也称为步长),控制每个树对最终预测结果的贡献程度。较小的学习率可以使模型更加稳定,但需要更多的迭代次数才能达到最优结果。
  • gamma:树分裂所需的最小损失减少值。它控制了树的生长过程中分裂节点的限制条件,较大的值可以防止过拟合。
  • colsample_bytree:每棵树的特征子采样比例。它决定了每棵树使用的特征的比例,较小的值可以增加模型的多样性,防止过拟合。
  • min_child_weight:叶子节点的最小样本权重和。它控制了树的生长过程中分裂节点的限制条件,较大的值可以防止过拟合。
  • subsample:样本子采样比例。它控制每棵树使用的样本比例,较小的值可以防止过拟合。
##参数调整
# 将数据集转换为trainControl对象
ctrl <- trainControl(
method = "cv", # 交叉验证
number = 5, # 5折交叉验证
verboseIter = FALSE)

# 设置参数网格
param_grid <- expand.grid(
nrounds = c(100, 200), # 迭代轮数(nrounds)
max_depth = c(3, 6), # 最大树深度(max_depth)
eta = c(0.1), # 学习率(eta)
gamma = c(0, 0.1), # 树分裂所需的最小损失减少值
colsample_bytree = c(0.8), # 特征子采样比例(colsample_bytree)
min_child_weight = c(1, 3), # 叶子节点的最小权重和(min_child_weight)
subsample = c(0.8)) # 和样本子采样比例(subsample)

# 使用train()函数进行参数调优
xgb_model <- train(
x = X_train,
y = y_train,
method = "xgbTree",
trControl = ctrl,
tuneGrid = param_grid)

# 输出最佳参数配置
print(xgb_model$bestTune)

使用最佳参数训练模型

# 设置最佳XGBoost参数
params <- list(objective = "binary:logistic", eval_metric = "logloss",
eta = 0.1, max_depth = 3, gamma = 0.1,
colsample_bytree = 0.8,
min_child_weight = 1,
subsample = 0.8)

# 训练模型
xgb_model_final <- xgb.train(params = params, data = dtrain, nrounds = 200)

# 在训练集上进行预测
train_predictions <- predict(xgb_model_final, newdata = dtrain)
train_predictions <- ifelse(train_predictions > 0.5,1,0)
# 计算准确率
accuracy <- mean(train_predictions == y_train)
print(paste("训练集准确率:", accuracy))

# 在测试集上进行预测
X_test <- test_data[, -1]
y_test <- as.factor(test_data[, 1])
dtest <- xgb.DMatrix(data = as.matrix(X_test))
test_predictions <- predict(xgb_model_final, newdata = dtest)
test_predictions <- ifelse(test_predictions > 0.5,1,0)

# 计算准确率
accuracy <- mean(test_predictions == y_test)
print(paste("测试集准确率:", accuracy))

调参之后的模型比初始模型表现提升了一些。

本文章转载微信公众号@Bio小菜鸟