缘由

艺多不压身

碎碎念

我们继续飞行在云层和雾气之间,飞行在一个无光无影的空洞世界中。 ——《风沙星辰》

Ref

9 Judging Model Effectiveness | Tidy Modeling with R

解读

从回归到分类:tidymodels 模型评估全流程

一、最简单的回归模型:Garage 面积预测房价

我们用 Ames 房价数据集 来演示,先把房价取对数(平滑分布):

library(tidymodels)
library(modeldata)
tidymodels_prefer()
 
data(ames)
ames <- mutate(ames, Sale_Price = log10(Sale_Price))
 
set.seed(502)
ames_split <- initial_split(ames, prop = 0.80, strata = Sale_Price)
ames_train <- training(ames_split)
ames_test  <- testing(ames_split)

建一个最简单的线性回归:

lm_model <-  linear_reg() %>% set_engine("lm")
lm_fit <- fit(lm_model, Sale_Price ~ Garage_Area, data = ames_train)
 
ames_test_res <- predict(lm_fit, new_data = ames_test) %>%
  bind_cols(ames_test %>% select(Sale_Price))

可视化预测效果

ggplot(ames_test_res, aes(x = Sale_Price, y = .pred)) + 
  geom_abline(lty = 2) + 
  geom_point(alpha = 0.5) + 
  coord_obs_pred()

理想状态下,点应该均匀分布在对角线上。


二、回归模型评估指标

常见指标有:

  • RMSE(均方根误差)
  • R²(判定系数)
  • MAE(平均绝对误差)
ames_metrics <- metric_set(rmse, rsq, mae)
ames_metrics(ames_test_res, truth = Sale_Price, estimate = .pred)

你也可以手动实现公式:

rmse_basic <- function(actual, predicted) {
  sqrt(mean((actual - predicted)^2))
}
 
rsq_basic <- function(actual, predicted) {
  ss_res <- sum((actual - predicted)^2)
  ss_tot <- sum((actual - mean(actual))^2)
  1 - (ss_res / ss_tot)
}

三、二分类任务:

二分类常用指标公式对照表

指标公式直观含义
准确率 (Accuracy)(TP + TN) / (TP + TN + FP + FN)预测正确的比例(整体表现)
精确度 (Precision)TP / (TP + FP)预测为正例的样本中,有多少是真的正例
召回率 (Recall / Sensitivity)TP / (TP + FN)真正的正例中,有多少被模型找出来
特异度 (Specificity)TN / (TN + FP)真正的负例中,有多少被模型正确识别

其中:

  • TP = 真正例 (True Positive)
  • TN = 真负例 (True Negative)
  • FP = 假正例 (False Positive)
  • FN = 假负例 (False Negative)

切换到分类任务,用 two_class_example 演示:

data(two_class_example)
 
conf_mat(two_class_example, truth = truth, estimate = predicted)
accuracy(two_class_example, truth, predicted)  
mcc(two_class_example, truth, predicted)       
f_meas(two_class_example, truth, predicted)    
  • Accuracy:整体预测正确率
  • MCC:Matthews 相关系数,考虑类别不平衡更稳健
  • F1-score (F-measure):查准率和查全率的调和平均
classification_metrics <- metric_set(accuracy, mcc, f_meas)
classification_metrics(two_class_example, truth = truth, estimate = predicted)

还可以画 ROC 曲线:

two_class_curve <- roc_curve(two_class_example, truth, Class1)
autoplot(two_class_curve)

四、多分类与类别不平衡

再看一个更复杂的数据集 hpc_cv:

data(hpc_cv)
 
accuracy(hpc_cv, obs, pred)
mcc(hpc_cv, obs, pred)

类别分布统计

在多分类任务中,类别不平衡往往是关键问题。

class_totals <- 
  count(hpc_cv, obs, name = "totals") %>% 
  mutate(class_wts = totals / sum(totals))
 
class_totals

通过观察每个类别占比,可以决定是否需要加权或采样。