【R语言】基于多模型的变量重要性图 (Variable Importance Plots)

变量重要性图 Variable Importance Plots

  • [1. 写在前面](#1. 写在前面)
  • 2.1数据导入
  • [2.2 模型训练](#2.2 模型训练)
  • [2.3 变量重要性](#2.3 变量重要性)
  • [2.4 变量重要性图](#2.4 变量重要性图)
  • [2.5 模型模拟验证](#2.5 模型模拟验证)
  • 3.基于caret包计算变量重要性

1. 写在前面

好久没有更新博客了,正好最近在帮老师做一个项目,里面涉及到了不同环境变量的重要性制图,所以在这里把我的理解进行分享,这应该是大家都可能遇到的问题。笔者水平有限,大家发现什么问题可以给我指出。

变量重要度图(Variable importance plots) 可以非常直观的展示各个变量在模型中的重要度,从而可以更好的理解和解释所建立的模型。

2.1数据导入

这里我随机生成了一个数据集,包含了10个x变量

r 复制代码
## 基于树模型的变量重要度图(Variable Importance Plots)-------------------------
library(vip) # 制作变量重要度图
library(rpart) # 决策树
library(randomForest) # 随机森林
library(xgboost) # 梯度提升决策树
library(mgcv)
library(caret)
library(ggplot2) # 作图

mydata <- gen_friedman( # 创建数据
  n_samples = 100, # 行数
  sigma = 1,       # 标准差
  seed = 123       # 让数据可以重复
)
nrow(mydata)
head(mydata)

数据集结构:

2.2 模型训练

这里包括了四个模型:决策树(Decision trees)、随机森林(Random forests)、梯度提升决策树(GBMs)、广义可加模型(GAM)

r 复制代码
# 1、拟合回归决策树模型-------------------------------------------
model_tree <- rpart(y ~ ., data = mydata)

# 2、拟合随机森林模型---------------------------------------------
model_rf <- randomForest(y ~ .,
                         data = mydata,
                         importance = TRUE)  # 计算变量的重要度   

# 3、拟合梯度提升决策树模型(GBMs)---------------------------------
model_gbm <- xgboost(
  data = data.matrix(subset(mydata, select = -y)), # 剔除y后将数据转化为矩阵格式
  label = mydata$y, # 指定因变量y
  nrounds = 100, # 提升迭代的最大次数
  max_depth = 5, # 树的最大深度为5,默认为6
  verbose = 0  # 不输出模型的运行信息
)

# 4、拟合广义可加模型 (GAM)----------------------------------------
# 自动创建公式字符串:将所有自变量包裹在平滑函数 s() 中
gam_formula <- as.formula(paste("y ~", paste0("s(", names(mydata)[-1], ")"
                                              , collapse = " + ")))
model_gam <- gam(gam_formula, data = mydata)
# # 拟合广义可加模型 (GAM)
# model_gam <- gam(y ~ s(x1) + s(x2) + s(x3) + s(x4) + s(x5)
#                  + s(x6) + s(x7) + s(x8) + s(x9) + s(x10),
#                  data = mydata)

2.3 变量重要性

使用vi()函数可以得到不同模型模拟的变量的重要性值

r 复制代码
# 决策树
vi(model_tree)
# 随机森林
vi(model_rf)
# GBMs
vi(model_gbm)
# 计算GAM模型的变量重要度
vi_gam <- vi(model_gam, method = "permute", target = "y", 
             metric = "rmse", pred_wrapper = predict)

简单列出其中一个模型的结果:

2.4 变量重要性图

这可能是大家最关心的地方

r 复制代码
# 制作变量重要度图
p1 <- vip(model_tree) + ggtitle("Single tree")
p2 <- vip(model_rf) + ggtitle("Random forest")
p3 <- vip(model_gbm) + ggtitle("Gradient boosting")
p4 <- vip(vi_gam) + ggtitle("GAM (Generalized Additive Model)")

# 将图片合并成1行3列
grid.arrange(p1, p2, p3, p4, nrow = 2)

结果展示:

可以看出,不同模型模拟的结果基本上是一致的。

2.5 模型模拟验证

这里用到了三个指标:R2、MAE和RMSE,具体公式如下,这里我没有使用Adjusted R2:

r 复制代码
## 模型模拟效果----------------------------------------------------------------
# 定义计算 R2的函数
calc_r2 <- function(actual, predicted) {
  ss_res <- sum((actual - predicted) ^ 2)
  ss_tot <- sum((actual - mean(actual)) ^ 2)
  1 - (ss_res / ss_tot)
}

# 定义计算 MAE 的函数
calc_mae <- function(actual, predicted) {
  mean(abs(actual - predicted))
}

# 定义计算 RMSE 的函数
calc_rmse <- function(actual, predicted) {
  sqrt(mean((actual - predicted) ^ 2))
}

# 获取实际值
actual_values <- mydata$y

# 计算每个模型的预测值
pred_tree <- predict(model_tree, mydata)
pred_rf <- predict(model_rf, mydata)
pred_gbm <- predict(model_gbm, data.matrix(subset(mydata, select = -y)))
pred_gam <- predict(model_gam, mydata)

# 计算 R2
r2_tree <- calc_r2(actual_values, pred_tree)
r2_rf <- calc_r2(actual_values, pred_rf)
r2_gbm <- calc_r2(actual_values, pred_gbm)
r2_gam <- calc_r2(actual_values, pred_gam)

# 计算 MAE
mae_tree <- calc_mae(actual_values, pred_tree)
mae_rf <- calc_mae(actual_values, pred_rf)
mae_gbm <- calc_mae(actual_values, pred_gbm)
mae_gam <- calc_mae(actual_values, pred_gam)

# 计算 RMSE
rmse_tree <- calc_rmse(actual_values, pred_tree)
rmse_rf <- calc_rmse(actual_values, pred_rf)
rmse_gbm <- calc_rmse(actual_values, pred_gbm)
rmse_gam <- calc_rmse(actual_values, pred_gam)

# 输出结果
cat(
  "Decision Tree:               R2 =", r2_tree,  "MAE =", mae_tree, "RMSE =", rmse_tree, "\n",
  "Random Forest:              R2 =", r2_rf,  "MAE =", mae_rf, "RMSE =", rmse_rf, "\n",
  "Gradient Boosting:          R2 =", r2_gbm,  "MAE =", mae_gbm, "RMSE =", rmse_gbm, "\n",
  "Generalized Additive Model: R2 =", r2_gam,  "MAE =", mae_gam, "RMSE =", rmse_gam, "\n"
)

结果展示:

3.基于caret包计算变量重要性

以上内容没有涉及到交叉验证,并且所有的模型评价指标都是手动计算的,现在我将使用caret包提供的函数进行计算。

caret(Classification and Regression Ensemble Training)包 是 R 语言中一个非常强大的工具,用于分类和回归模型的训练和评估。它提供了一个统一的接口 来实现不同的机器学习算法,并支持模型的调参、训练、预测和评估。
主要功能和特点

  • 统一的接口 : caret 提供了一个统一的接口来训练和评估各种机器学习模型,无论是分类模型还是回归模型。这样,你可以在不同的算法之间进行比较和选择。
  • 模型训练 : 使用 train() 函数可以训练模型,支持多种模型算法,如决策树、随机森林、支持向量机(SVM)、梯度提升、线性回归、广义可加模型(GAM)等。
  • 调参(Tuning): caret 允许你通过网格搜索(grid search)和随机搜索(random search)来调节模型的超参数,以找到最佳的参数组合。使用 train() 函数时,可以通过 tuneGrid 或 tuneLength 参数来指定需要调节的参数范围。
  • 交叉验证(Cross-Validation): 提供了多种交叉验证方法,如 k 折交叉验证(k-fold cross-validation)来评估模型的性能。你可以通过 trainControl() 函数设置交叉验证的参数。
  • 性能评估 : caret 可以计算模型的性能指标,如准确率(accuracy)、均方根误差(RMSE)、均方误差(MSE)、调整后的 R²(Adjusted R²)等。可以通过 postResample() 函数来提取模型的性能度量。
  • 数据预处理 : 支持数据预处理操作,如数据标准化(standardization)、归一化(normalization)、特征选择(feature selection)等。这些操作可以通过 preProcess() 函数实现。
  • 模型集成 : 支持多种模型集成方法,如堆叠(stacking)和集成(ensembling),以提高模型的预测性能。
r 复制代码
## caret ----------------------------------------------------------------------
# Set up 10-fold cross-validation
train_control <- trainControl(method = "cv", number = 10)

# glm with 10-fold cross-validation
model_glm_cv <- train(
  y ~ .,
  data = mydata,
  method = "glm",
  trControl = train_control,
  metric = "RMSE"
)

# GAM with 10-fold cross-validation
model_gam_cv <- train(
  y ~ .,
  data = mydata,
  method = "gamSpline",
  trControl = train_control,
  metric = "RMSE"
)

# Random Forest with 10-fold cross-validation
model_rf_cv <- train(
  y ~ .,
  data = mydata,
  method = "rf",
  trControl = train_control,
  metric = "RMSE"
)

# Gradient Boosting with 10-fold cross-validation
model_gbm_cv <- train(
  y ~ .,
  data = mydata,
  method = "xgbTree",
  trControl = train_control,
  metric = "RMSE"
)

# 计算并绘制变量重要性
vip(model_glm_cv)
vip(model_gam_cv)
vip(model_rf_cv)
vip(model_gbm_cv)

# make Variable Importance Plots
p11 <- vip(model_glm_cv) + ggtitle("Generalized linear Model")
p21 <- vip(model_gam_cv) + ggtitle("Random forest")
p31 <- vip(model_rf_cv) + ggtitle("Gradient boosting")
p41 <- vip(model_gbm_cv) + ggtitle("Generalized Additive Model")

grid.arrange(p11, p21, p31, p41, nrow = 2)

# Extract the results
results_glm <- model_glm_cv$results
results_rf <- model_rf_cv$results
results_gbm <- model_gbm_cv$results
results_gam <- model_gam_cv$results

# Print results
cat(
  "Generalized linear Model (GLM):   R2 =", max(results_glm$Rsquared), "MAE =", min(results_tree$MAE), "RMSE =", min(results_tree$RMSE), "\n",
  "Random Forest (RF):              R2 =", max(results_rf$Rsquared), "MAE =", min(results_rf$MAE), "RMSE =", min(results_rf$RMSE), "\n",
  "Gradient Boosting (GBM):         R2 =", max(results_gbm$Rsquared), "MAE =", min(results_gbm$MAE), "RMSE =", min(results_gbm$RMSE), "\n",
  "Generalized Additive Model(GAM): R2 =", max(results_gam$Rsquared), "MAE =", min(results_gam$MAE), "RMSE =", min(results_gam$RMSE), "\n"
)

结果展示:

模型模拟精度验证:

相关推荐
一叶_障目1 小时前
机器学习之决策树(DecisionTree——C4.5)
人工智能·决策树·机器学习
AIGC大时代2 小时前
分享14分数据分析相关ChatGPT提示词
人工智能·chatgpt·数据分析
SelectDB2 小时前
Apache Doris 2.1.8 版本正式发布
大数据·数据库·数据分析
十二测试录3 小时前
【自动化测试】—— Appium使用保姆教程
android·经验分享·测试工具·程序人生·adb·appium·自动化
Dipeak数巅科技4 小时前
数巅科技连续中标大模型项目 持续助力央国企数智化升级
大数据·人工智能·数据分析
Ray.19984 小时前
Flink 的核心特点和概念
大数据·数据仓库·数据分析·flink
快手技术4 小时前
KwaiCoder-23BA4-v1:以 1/30 的成本训练全尺寸 SOTA 代码续写大模型
算法·机器学习·开源
BlackPercy5 小时前
【线性代数】列主元法求矩阵的逆
线性代数·机器学习·矩阵
EQUINOX15 小时前
3b1b线性代数基础
人工智能·线性代数·机器学习
Swift社区5 小时前
统计文本文件中单词频率的 Swift 与 Bash 实现详解
vue.js·leetcode·机器学习