模型性能评价实战

简介: 模型性能评价实战

1 目的

  在机器学习领域,模型性能评估是一个至关重要的环节。我们的核心目的是通过采用科学、合理的模型性能评估方法,对机器学习在实际案例中的应用效果进行准确、全面的评价。这种评估不仅能够帮助我们了解模型在特定场景下的表现,还能为后续的模型优化和改进提供有力依据。

2 度量分类方法性能指标

2.1 预测值

  运行代码:

data1<-read.csv("F:\\sms_results.csv") #读取数据
head(data1)                            #查看数据前六行

  结果展示:

##   actual_type predict_type   prob_spam prob_ham
## 1         ham          ham 0.000000256 1.00e+00
## 2         ham          ham 0.000130984 1.00e+00
## 3         ham          ham 0.000080900 1.00e+00
## 4         ham          ham 0.000139651 1.00e+00
## 5        spam         spam 1.000000000 8.58e-11
## 6         ham          ham 0.003504181 9.96e-01

 根据结果可以看到案列分类属于垃圾信息和非垃圾信息预测概率情况,前六行数据真实值和预测值结果一致,且预测概率都很接近0或1,说明该判别可信度很高。

  运行代码:

head(subset(data1,prob_spam>0.4&prob_ham<0.6))

  结果展示:

##    actual_type predict_type prob_spam prob_ham
## 5         spam         spam 1.0000000 8.58e-11
## 10        spam         spam 1.0000000 2.90e-10
## 14        spam         spam 0.9999996 3.82e-07
## 15        spam         spam 1.0000000 4.85e-12
## 35        spam         spam 0.9995596 4.40e-04
## 40        spam         spam 0.9999986 1.38e-06

  运行代码:

head(subset(data1,actual_type != predict_type))

  结果展示:

##     actual_type predict_type   prob_spam prob_ham
## 53         spam          ham 0.000679622    0.999
## 59         spam          ham 0.133396102    0.867
## 73         spam          ham 0.358266535    0.642
## 76         spam          ham 0.122462553    0.878
## 81         spam          ham 0.022486322    0.978
## 184        spam          ham 0.032005962    0.968

 通过结果,我们可以看到部分样本数据的预测可信度偏低,且存在真实值与预测值结果不一致的情况。

2.2 深入探讨混淆矩阵

  运行代码:

table(data1$actual_type,data1$predict_type)

  结果展示:

##       
##         ham spam
##   ham  1202    5
##   spam   29  154

  运行代码:

library("gmodels")
CrossTable(data1$actual_type,data1$predict_type)

  结果展示:

## 
##  
##    Cell Contents
## |-------------------------|
## |                       N |
## | Chi-square contribution |
## |           N / Row Total |
## |           N / Col Total |
## |         N / Table Total |
## |-------------------------|
## 
##  
## Total Observations in Table:  1390 
## 
##  
##                   | data1$predict_type 
## data1$actual_type |       ham |      spam | Row Total | 
## ------------------|-----------|-----------|-----------|
##               ham |      1202 |         5 |      1207 | 
##                   |    16.565 |   128.248 |           | 
##                   |     0.996 |     0.004 |     0.868 | 
##                   |     0.976 |     0.031 |           | 
##                   |     0.865 |     0.004 |           | 
## ------------------|-----------|-----------|-----------|
##              spam |        29 |       154 |       183 | 
##                   |   109.256 |   845.876 |           | 
##                   |     0.158 |     0.842 |     0.132 | 
##                   |     0.024 |     0.969 |           | 
##                   |     0.021 |     0.111 |           | 
## ------------------|-----------|-----------|-----------|
##      Column Total |      1231 |       159 |      1390 | 
##                   |     0.886 |     0.114 |           | 
## ------------------|-----------|-----------|-----------|
## 
##

  通过代码运行输出简略混淆矩阵和更详细的混淆矩阵。

2.2.1 准确度和错误率

  运行代码:

actual<-(1202+154)/1390    
actual                        ##准确率
error<-1-actual
error                         ##错误率

  结果展示:

> actual  
## [1] 0.9755396
> error 
## [1] 0.02446043

  根据结果显示,该模型的预测准确率达97.55%,错误率大约为2.45%。

2.2.2 Kappa统计量

  运行代码:

library("e1071")
library("caret")
confusionMatrix(data1$predict_type,data1$actual_type,positive = "spam")

  结果展示:

## Confusion Matrix and Statistics
## 
##           Reference
## Prediction  ham spam
##       ham  1202   29
##       spam    5  154
##                                         
##                Accuracy : 0.9755        
##                  95% CI : (0.966, 0.983)
##     No Information Rate : 0.8683        
##     P-Value [Acc > NIR] : < 2.2e-16     
##                                         
##                   Kappa : 0.8867        
##                                         
##  Mcnemar's Test P-Value : 7.998e-05     
##                                         
##             Sensitivity : 0.8415        
##             Specificity : 0.9959        
##          Pos Pred Value : 0.9686        
##          Neg Pred Value : 0.9764        
##              Prevalence : 0.1317        
##          Detection Rate : 0.1108        
##    Detection Prevalence : 0.1144        
##       Balanced Accuracy : 0.9187        
##                                         
##        'Positive' Class : spam          
##

  根据结果可以看到一些其他性能指标,例如Kappa统计量值为0.8867、灵敏度为0.8415、特异性为0.9959。

  运行代码:

pr_a<-1202/1390+154/1390             #分类器和真实值之间的真实一致性比例
pr_e<-0.868*0.886+0.132*0.114        #分类器和真实值之间的期望一致性比例
k<-(pr_a-pr_e)/(1-pr_e)
k
library("vcd")                                     #加载包
Kappa(table(data1$actual_type,data1$predict_type)) #Kappa值
library("irr")                                     #加载包
kappa2(data1[1:2])                                 #kappa值

  结果展示:

> k  
## [1] 0.8867069
> actual  
##             value     ASE     z Pr(>|z|)
## Unweighted 0.8867 0.01909 46.45        0
## Weighted   0.8867 0.01909 46.45        0
> kappa2(data1[1:2])                                 #kappa值
##  Cohen's Kappa for 2 Raters (Weights: unweighted)
## 
##  Subjects = 1390 
##    Raters = 2 
##     Kappa = 0.887 
## 
##         z = 33.2 
##   p-value = 0

 三种方法显示Kappa值均为0.887,表示该分类器分类结果具有不错的一致性。

2.2.3 灵敏度和特异性

  运行代码:

sens<-154/(29+154)
sens
spec<-1202/(1202+5)
spec
sensitivity(data1$predict_type,data1$actual_type,positive = "spam")
sensitivity(data1$predict_type,data1$actual_type,positive = "ham")

  结果展示:

> sens  
## [1] 0.8415301
> spec  
## [1] 0.9958575
> sensitivity(data1$predict_type,data1$actual_type,positive = "spam")
## [1] 0.8415301
> sensitivity(data1$predict_type,data1$actual_type,positive = "ham")
## [1] 0.9958575

 两种方法结果相同,灵敏度为0.8415、特异性为0.9959,表示84.15%的垃圾信息被正确分类,99.59%的非垃圾信息被正确分类。

2.2.4 预测精确度和回溯精确度

  运行代码:

prec<-154/(154+5)
prec
rec<-154/(154+29)
rec
posPredValue(data1$predict_type,data1$actual_type,positive = "spam")
sensitivity(data1$predict_type,data1$actual_type,positive = "spam")

  结果展示:

prec  
## [1] 0.9685535
> rec  
## [1] 0.8415301
> posPredValue(data1$predict_type,data1$actual_type,positive = "spam")
## [1] 0.9685535
> sensitivity(data1$predict_type,data1$actual_type,positive = "spam")
## [1] 0.8415301

 两种方法结果相同,其中预测精确度为96.86%,回溯精确度为84.15%,表示被正确分类的垃圾信息在预测的垃圾信息中占比96.86%,被正确分类的垃圾信息占所有垃圾信息的84.15%。

2.2.5 F度量

  运行代码:

f<-(2*prec*rec)/(prec+rec)
f
f<-(2*154)/(2*154+5+29)
f

  结果展示:

f  
## [1] 0.9005848
> f  
## [1] 0.9005848

 两种方法结果相同,根据结果显示,F度量值为0.9005848,它能描述变化率的平均值。

2.3 性能权衡的可视化

  运行代码:

library("ROCR")
pred<-prediction(predictions=data1$prob_spam,labels=data1$actual_type)
pref<-performance(pred,measure = "tpr",x.measure = "fpr")
plot(pref,main="ROC curve for SMS spam filter",col="blue",lwd=3)
abline(a=0,b=1,lwd=2,lty=2)
text(x=0.6,y=0.4,"没有预测价值的分类器")
text(x=0.1,y=0.8,"测试分类器")
text(x=0.05,y=1.0,"完美分类器")

  结果展示:

  运行代码:

pref.auc<-performance(pred,measure="auc")
str(pref.auc)

  结果展示:

## Formal class 'performance' [package "ROCR"] with 6 slots
##   ..@ x.name      : chr "None"
##   ..@ y.name      : chr "Area under the ROC curve"
##   ..@ alpha.name  : chr "none"
##   ..@ x.values    : list()
##   ..@ y.values    :List of 1
##   .. ..$ : num 0.983
##   ..@ alpha.values: list()

  运行代码:

unlist(pref.auc@y.values)

  结果展示:

## [1] 0.9829999

 通过ROC曲线及AUC=0.9829999,说明此分类器接近于完美分类器,分类效果较好。

2.4 评估未来的性能

2.4.1 保持法

  运行代码:

credit<-read.csv("F:\\机器学习\\第三次作业\\credit.csv")#读取数据
random_ids<-order(runif(1000))                        #生成随机1000个随机ID并排序
credit_train<-credit[random_ids[1:500],]              #创建训练集
credit_validata<-credit[random_ids[501:750],]         #创建验证数据集
credit_test<-credit[random_ids[751:1000],]            #创建测试集
in_train<-createDataPartition(credit$default,p=0.75,list=F)
credit_train<-credit[in_train,]                #训练集
credit_test<-credit[-in_train,]                #测试集

  首先利用典型划分方法划分50%的数据为训练集、25%的数据为验证数据集、25%的数据为测试集。然后利用分层随机抽样的方法划分数据。

2.4.2 10折交叉验证法

  运行代码:

folds<-createFolds(credit$default,k=10)        #创建10折
str(folds)                                     #查看数据类型

  结果展示:

## List of 10
##  $ Fold01: int [1:100] 4 20 29 30 46 51 57 62 65 69 ...
##  $ Fold02: int [1:100] 3 25 45 74 78 80 95 103 121 134 ...
##  $ Fold03: int [1:100] 2 13 14 18 23 61 67 75 76 98 ...
##  $ Fold04: int [1:100] 9 11 12 16 26 28 43 73 87 89 ...
##  $ Fold05: int [1:100] 5 6 10 21 42 44 64 82 83 84 ...
##  $ Fold06: int [1:100] 24 33 63 86 101 102 108 109 128 131 ...
##  $ Fold07: int [1:100] 7 34 35 41 47 48 52 54 58 70 ...
##  $ Fold08: int [1:100] 31 36 50 60 68 77 79 96 122 133 ...
##  $ Fold09: int [1:100] 15 17 27 32 37 40 49 53 55 66 ...
##  $ Fold10: int [1:100] 1 8 19 22 38 39 56 59 72 92 ...

  运行代码:

credit01_test<-credit[folds$Fold01,]           #训练集
credit01_train<-credit[-folds$Fold01,]         #测试集
library("C50")                                   #加载包
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)                                  #查看Kappa统计量

  结果展示:

## List of 10
##  $ Fold01: num 0.381
##  $ Fold02: num 0.525
##  $ Fold03: num 0.247
##  $ Fold04: num 0.316
##  $ Fold05: num 0.387
##  $ Fold06: num 0.368
##  $ Fold07: num 0.122
##  $ Fold08: num 0.141
##  $ Fold09: num 0.0691
##  $ Fold10: num 0.381

  运行代码:

mean(unlist(cv_results))                         #平均Kappa统计量

  结果展示:

## [1] 0.2939567

  根据结果发现平均Kappa值为0.2939567,在评价体系的解释中对应着”很差”,说明这个信用计分模型的效果并不比随机猜测好很多。

2.4.3 0.632自助法

  运行代码:

library("C50")
data1_train<-credit[random_ids[1:632],]         #训练集
data1_test<-credit[random_ids[633:1000],]       #测试集
data1_model<-C5.0(default~.,data=data1_train)
data1_pred<-predict(data1_model,data1_train)
data1_pred1<-predict(data1_model,data1_test)
table(data1_train$default,data1_pred)

  结果展示:

##      data1_pred
##        no yes
##   no  427  18
##   yes  93  94

  运行代码:

table(data1_test$default,data1_pred1)

  结果展示:

##      data1_pred1
##        no yes
##   no  224  31
##   yes  73  40

  运行代码:

error1<-0.632*(22+66)/632+0.368*(37+65)/368
error1

  结果展示:

## [1] 0.19

  根据结果显示,0.632自助法错误率为19%。

相关文章
|
10月前
|
编解码 缓存 并行计算
YOLOv5入门实践(4)——手把手教你训练自己的数据集
YOLOv5入门实践(4)——手把手教你训练自己的数据集
1363 0
YOLOv5入门实践(4)——手把手教你训练自己的数据集
|
20天前
|
机器学习/深度学习 人工智能 自然语言处理
LLM 大模型学习必知必会系列(一):大模型基础知识篇
LLM 大模型学习必知必会系列(一):大模型基础知识篇
LLM 大模型学习必知必会系列(一):大模型基础知识篇
|
机器学习/深度学习 存储 数据可视化
【PyTorch基础教程23】可视化网络和训练过程
为了更好确定复杂网络模型中,每一层的输入结构,输出结构以及参数等信息,在Keras中可以调用一个叫做model.summary()的API能够显示我们的模型参数,输入大小,输出大小,模型的整体参数等。
1384 0
【PyTorch基础教程23】可视化网络和训练过程
|
20天前
|
机器学习/深度学习 API 开发者
深入浅出:使用Python实现机器学习模型的部署
在本文中,我们将探讨如何使用Python语言将机器学习模型从开发环境迁移到生产环境的过程。与传统的技术文章摘要不同,我们不仅会概述关键步骤和常见挑战,还将引入一个简易的案例研究,通过这个案例,读者能够更直观地理解模型部署的全过程及其重要性。我们将重点讨论模型封装、API设计、容器化技术以及云服务部署等关键技术,旨在为广大开发者提供一个清晰、实用的模型部署指南。
|
10月前
|
XML 数据格式 Python
YOLOv5入门实践(3)——手把手教你划分自己的数据集
YOLOv5入门实践(3)——手把手教你划分自己的数据集
2460 0
YOLOv5入门实践(3)——手把手教你划分自己的数据集
|
7月前
|
机器学习/深度学习 算法 PyTorch
机器学习-逻辑回归:从技术原理到案例实战
机器学习-逻辑回归:从技术原理到案例实战
154 0
|
10月前
|
机器学习/深度学习 PyTorch 算法框架/工具
深度学习实践篇 第三章:模型与模型的搭建
主要介绍了pytorch中nn.Module()类和模型搭建
177 0
|
10月前
|
机器学习/深度学习 算法 PyTorch
深度学习实践篇 第四章:模型训练与示例
简要介绍pytorch中模型训练的流程和部分原理知识。
|
11月前
|
机器学习/深度学习 数据库 计算机视觉
图像分类基础与实战
图像分类基础与实战(1)
|
11月前
|
异构计算