深度学习R语言收藏复现

【机器学习与R语言】12- 如何评估模型的性能?

2020-09-11  本文已影响0人  生物信息与育种

1.评估分类方法的性能

#朴素贝斯分类的预测概率
predicted_prob=predict(model,test_data,type="raw")
#决策树C5.0分类器
predicted_proc=predict(model,test_data,type="prob")
# obtain the predicted probabilities
sms_test_prob <- predict(sms_classifier, sms_test, type = "raw")
head(sms_test_prob)

1.1 混淆矩阵

混淆矩阵是一张二维表(第一维是所有可能的预测类别,第二维是真实的类别),按照预测值是否匹配真实值来对预测值进行分类。二值分类是2X2混淆矩阵,三值分类模型是3X3混淆矩阵。


image.png

数据下载链接: https://pan.baidu.com/s/1YiFdOHX8rWrVKB97FRY8Iw 提取码: eka6

## Confusion matrixes in R ----
sms_results <- read.csv("sms_results.csv")

# the first several test cases
head(sms_results)

# test cases where the model is less confident
head(subset(sms_results, prob_spam > 0.40 & prob_spam < 0.60))

# test cases where the model was wrong
head(subset(sms_results, actual_type != predict_type))

# specifying vectors
table(sms_results$actual_type, sms_results$predict_type)

# alternative solution using the formula interface (not shown in book)
xtabs(~ actual_type + predict_type, sms_results)

# using the CrossTable function
library(gmodels)
CrossTable(sms_results$actual_type, sms_results$predict_type)

# accuracy and error rate calculation --
# accuracy
(152 + 1203) / (152 + 1203 + 4 + 31)
# error rate
(4 + 31) / (152 + 1203 + 4 + 31)
# error rate = 1 - accuracy
1 - 0.9748201
image.png

1.2 其他评价指标

分类和回归训练R包caret提供了更多的计算性能度量指标的函数。

## Beyond accuracy: other performance measures ----
library(caret)
confusionMatrix(sms_results$predict_type, 
            sms_results$actual_type, 
            positive = "spam") #检测垃圾信息是目标,将其设为阳性
image.png

1)Kappa统计量

计算示例:


image.png
pr(a)=0.865+0.111=0.976
pr(e)=0.868*0.886+0.132*0.114=0.784096
kappa=(pr(a)-pr(e))/(1-pr(e))=0.89
# calculate kappa via the vcd package
library(vcd)
Kappa(table(sms_results$actual_type, sms_results$predict_type))
image.png
# calculate kappa via the irr package
library(irr)
kappa2(sms_results[1:2])
image.png

注意不要用内置的kappa函数,它与Kappa统计量没关系。

2)灵敏度与特异性

image.png image.png

如上面的混淆矩阵中,手动计算:

# Sensitivity and specificity
# example using SMS classifier
sens <- 152 / (152 + 31)
sens

spec <- 1203 / (1203 + 4)
spec

caret包中的sensitivity和specificity函数可直接计算:

# example using the caret package
library(caret)
sensitivity(sms_results$predict_type, 
            sms_results$actual_type, 
            positive = "spam")
specificity(sms_results$predict_type, 
            sms_results$actual_type, 
            negative = "ham")

3)精确度与回溯精确度

image.png image.png

手动计算:

# Precision and recall
prec <- 152 / (152 + 4)
prec

rec <- 152 / (152 + 31)
rec

caret包中的posPredValue函数计算:

# example using the caret package
library(caret)
posPredValue(sms_results$predict_type, 
             sms_results$actual_type, 
             positive = "spam")
sensitivity(sms_results$predict_type, 
            sms_results$actual_type, 
            positive = "spam")

4)F度量

image.png

计算:

# F-measure
f <- (2 * prec * rec) / (prec + rec)
f

f <- (2 * 152) / (2 * 152 + 4 + 31)
f

1.3 性能权衡可视化(ROC曲线)

image.png
## Visualizing Performance Tradeoffs ----
library(ROCR)
pred <- prediction(predictions = sms_results$prob_spam,
                   labels = sms_results$actual_type)

# ROC curves
perf <- performance(pred, measure = "tpr", x.measure = "fpr")
plot(perf, main = "ROC curve for SMS spam filter", col = "blue", lwd = 2)

# add a reference line to the graph
abline(a = 0, b = 1, lwd = 2, lty = 2)
image.png

定性分析可看到上图ROC曲线占据了图形左上角的区域,接近完美分类器;定量分析则通过函数来计算AUC。

# calculate AUC
perf.auc <- performance(pred, measure = "auc")
#返回S4对象,存储信息的位置称为槽(slots),槽的前缀为@
str(perf.auc) #查看所有槽
unlist(perf.auc@y.values) #简化为数值向量

AUC值可达到0.98。但这个模型对其他数据集是否也表现好呢?需要测试外部数据来推断模型的预测性能。

2.评估未来的性能

2.1 保持法

数据下载链接: https://pan.baidu.com/s/1O9JYXUZnQfVGIU-VWGTptA 提取码: 7q7q

# partitioning data
library(caret)
credit <- read.csv("credit.csv")

# Holdout method
# using random IDs
random_ids <- order(runif(1000))
credit_train <- credit[random_ids[1:500],]
credit_validate <- credit[random_ids[501:750], ]
credit_test <- credit[random_ids[751:1000], ]

# using caret function
#返回行号
in_train <- createDataPartition(credit$default, 
                                p = 0.75, #该划分中样本的比例
                                list = FALSE) #防止结果存储成列表
credit_train <- credit[in_train, ]
credit_test <- credit[-in_train, ]

2.2 交叉验证

# 10-fold CV
folds <- createFolds(credit$default, k = 10)
str(folds)
credit01_test <- credit[folds$Fold01, ]
credit01_train <- credit[-folds$Fold01, ]
image.png

可以用不同数据集手动执行以上步骤10次,然后建模评估,最后将所有性能度量取均值作为总体的性能。但我们肯定可以通过编程来实现自动化,这里以10折CV建立C5.0决策树模型为例,然后估计Kappa统计量:

## Automating 10-fold CV for a C5.0 Decision Tree using lapply() ----
library(caret)
library(C50)
library(irr)

credit <- read.csv("credit.csv")

set.seed(123)
folds <- createFolds(credit$default, k = 10)

cv_results <- lapply(folds, function(x) {
  credit_train <- credit[-x, ]
  credit_test <- credit[x, ]
  credit_model <- C5.0(default ~ ., data = credit_train)
  credit_pred <- predict(credit_model, credit_test)
  credit_actual <- credit_test$default
  kappa <- kappa2(data.frame(credit_actual, credit_pred))$value
  return(kappa)
})

str(cv_results)
mean(unlist(cv_results))
image.png

kappa值很低,总体模型性能差,下一章会讲如何改进。

2.3 自助法抽样

上一篇 下一篇

猜你喜欢

热点阅读