1.评估分类方法的性能

  • 拥有能够度量实用性而不是原始准确度的模型性能评价方法是至关重要的。
  • 3种数据类型评价分类器:真实的分类值;预测的分类值;预测的估计概率。之前的分类算法案例只用了前2种。
  • 对于单一预测类别,可将predict函数设定为class类型,如果要得到预测的概率,可设为为prob、posterior、raw或probability等类型。predict大部分情况下返回对结果不同水平的预测概率。
#朴素贝斯分类的预测概率
predicted_prob=predict(model,test_data,type="raw")
#决策树C5.0分类器
predicted_proc=predict(model,test_data,type="prob")
  • 一般而言,预测值和真实值都是同一类时的预测概率会比较极端(接近0或1),但总有一些相反的,概率值介于中间,这时判断模型是否可用,可通过对测试数据应用各种误差度量的方法。
# obtain the predicted probabilities
sms_test_prob <- predict(sms_classifier, sms_test, type = "raw")
head(sms_test_prob)

1.1 混淆矩阵

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

  • 阳性和阴性:相对的概念,无任何隐含的价值判断。一般将感兴趣的类别(或目标)设为阳性。

  • 度量性能:准确度(成功率)

  • 错误率



    gmodels::CrossTable代码示例:

数据下载链接: 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

1.2 其他评价指标

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

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

1)Kappa统计量

  • Kappa对准确度进行调整,表示的是预测值和真实值之间的一致性

  • Kappa计算公式:



    Pr是预测值和真实值之间的真实一致性a和期望一致性e的比例。Kappa统计量使用期望的一致性Pr(e)对准确度进行调整,Pr(e)是完全的偶然性导致的预测值和实际值相同的概率。

计算示例:

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
  • 其他计算Kappa的函数:
# calculate kappa via the vcd package
library(vcd)
Kappa(table(sms_results$actual_type, sms_results$predict_type))

  • vcd::Kappa函数计算出来的kappa有加权和没加权的,对于二分类,加不加权都一样,一般关注不加权的就好。加权主要用于存在不同尺度一致性的情况。
# calculate kappa via the irr package
library(irr)
kappa2(sms_results[1:2])

  • irr::kappa2函数可直接使用数据框中的预测值向量和实际分类向量来计算Kappa值。

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

2)灵敏度与特异性

  • 用来权衡做决策时保守or激进的度量。权衡时最典型的做法是:对模型进行调整或者使用不同的模型,直到能通过灵敏度和特异性的阈值为止。
  • 灵敏度(真阳性率):度量阳性样本被正确分类的比例。

  • 特异性(真阴性率):度量阴性样本被正确分类的比例。



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

# 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)精确度与回溯精确度

  • 这两者也与分类时的折中方案有关。
  • 精确度(阳性预测值):真阳性在所有预测为阳性案例中的比例。

  • 回溯精确度:度量结果的完备性,真阳性与阳性总数的比例(计算与灵敏度一样,只是解释不同:捕捉大量阳性样本,具有很宽的范围)。



手动计算:

# 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度量

  • F度量(F1记分/F记分):将精确度和回溯精确度合并成一个单一值(通过调和平均值来整合)的模型性能度量方式。



计算:

# F-measure
f <- (2 * prec * rec) / (prec + rec)
f f <- (2 * 152) / (2 * 152 + 4 + 31)
f
  • 整合成一个单一值比较方便,但需要假设精确度和回溯精确度具有同样的权重。

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

  • 可视化可以考察度量如何在大范围的值之间变化,还可以在单个图形中同时比较多个分类器的方法。
  • ROC(受试者工作特征)曲线:常用来检查在找出真阳性和避免假阳性之间的权衡。
  • ROC曲线横轴表假阳性比例(1-特异性),纵轴表真阳性比例(灵敏度),所以也称为灵敏度/特异性图。

  • ROC曲线上的点表示不同假阳性阈值上的真阳性的比例。
  • AUC(Area Under the ROC):ROC曲线下面积来度量识别阳性值的能力。位于0.5(无预测值分类器)-1(完美分类器)之间,解释AUC得分可参考(比较主观):

  • ROC+AUC:两个ROC曲线可能形状不同,但具有相同的AUC,因此AUC可能具有误导性,最好是和ROC曲线定性分析结合使用。

    代码示例:
## 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)



定性分析可看到上图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 保持法

  • 保持法就是常见的数据划分训练集和测试集的过程:训练集用来生成模型,应用到测试集来生成预测结果进行评估。一般1/3的数据用于测试,2/3用于训练。
  • 保持法不允许测试集的结果影响模型,但如果基于重复测试的结果选择一个最好的模型,则会违反这个原则。因此可再分出第三个数据集,集验证集。(注:前面的章节中我们只划分了训练和测试集两类数据,实际上违反了这一原则,那些测试集更准确地应该称为验证集。如果我们使用测试集来做决策,从结果中挑选最好的模型,那么评估将不再是对未来性能的无偏估计)
  • 验证集用来对模型迭代和改善。测试集只使用一次,最后输出对未来预测的错误率估计。一般数据划分50%训练集,25%测试集,25%验证集。
  • 分层随机抽样:确保随机划分后每个类别的比例与总体数据中的比例近似相等。可用caret:::createDataPartition函数实现。

数据下载链接: 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 交叉验证

  • 重复保持法使k折交叉验证(k折CV,将数据随机分成k个完全分隔的部分)的基础,k折交叉验证已称为业界评估模型性能的标准。
  • 最常用10折交叉验证(每一折包含总数据的10%),机器学习模型使用剩下的90%数据建模,包含10%数据的这一折用来评估,训练和评估模型进行不同的10次,将输出所有折的平均性能指标。
  • 留一交叉验证法:将每个样本作为1折,用最大数目的样本来建模,但计算量太大,很少用。
  • 使用caret::createFolds函数创建交叉验证数据集:
# 10-fold CV
folds <- createFolds(credit$default, k = 10)
str(folds)
credit01_test <- credit[folds$Fold01, ]
credit01_train <- credit[-folds$Fold01, ]

可以用不同数据集手动执行以上步骤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))



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

2.3 自助法抽样

  • 自助法抽样(bootstrap):主要指一些统计方法,通过对数据进行随机抽样的方式来估计大数据集的内容。各种随机产生的数据集的结果可以通过平均值计算得到一个最终的估计值,用来评估未来的性能。
  • 与k折CV的不同:交叉验证将数据分隔开来,每个样本只能出现一次,而自助法是有放回的抽样,每个样本可以被选择多次。因此自助法抽样对完整数据集的代表性更弱,但它对于小数据集的效果更好。除了度量性能之外,它还能提高模型性能。
  • 0.632自助法:每个样本包含在训练集中的概率是63.2%。通过训练数据集(过于乐观)和测试集(过于悲观)的函数来计算最终的性能度量:


机器学习与R语言系列推文汇总:

【机器学习与R语言】1-机器学习简介

【机器学习与R语言】2-K近邻(kNN)

【机器学习与R语言】3-朴素贝叶斯(NB)

【机器学习与R语言】4-决策树

【机器学习与R语言】5-规则学习

【机器学习与R语言】6-线性回归

【机器学习与R语言】7-回归树和模型树

【机器学习与R语言】8-神经网络

【机器学习与R语言】9-支持向量机

【机器学习与R语言】10-关联规则

【机器学习与R语言】11-Kmeans聚类

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

【机器学习与R语言】13-如何提高模型的性能?

【机器学习与R语言】12- 如何评估模型的性能?的更多相关文章

  1. 【机器学习与R语言】13- 如何提高模型的性能?

    目录 1.调整模型参数来提高性能 1.1 创建简单的调整模型 2.2 定制调整参数 2.使用元学习来提高性能 2.1 集成学习(元学习)概述 2.2 bagging 2.3 boosting 2.4 ...

  2. 【机器学习与R语言】7-回归树和模型树

    目录 1.理解回归树和模型树 2.回归树和模型树应用示例 1)收集数据 2)探索和准备数据 3)训练数据 4)评估模型 5)提高模型性能 1.理解回归树和模型树 决策树用于数值预测: 回归树:基于到达 ...

  3. 【机器学习与R语言】11- Kmeans聚类

    目录 1.理解Kmeans聚类 1)基本概念 2)kmeans运作的基本原理 2.Kmeans聚类应用示例 1)收集数据 2)探索和准备数据 3)训练模型 4)评估性能 5)提高模型性能 1.理解Km ...

  4. 【机器学习与R语言】10- 关联规则

    目录 1.理解关联规则 1)基本认识 2)Apriori算法 2.关联规则应用示例 1)收集数据 2)探索和准备数据 3)训练模型 4)评估性能 5)提高模型性能 1.理解关联规则 1)基本认识 购物 ...

  5. 【机器学习与R语言】9- 支持向量机

    目录 1.理解支持向量机(SVM) 1)SVM特点 2)用超平面分类 3)对非线性空间使用核函数 2. 支持向量机应用示例 1)收集数据 2)探索和准备数据 3)训练数据 4)评估模型 5)提高性能 ...

  6. 【机器学习与R语言】8- 神经网络

    目录 1.理解神经网络 1)基本概念 2)激活函数 3)网络拓扑 4)训练算法 2.神经网络应用示例 1)收集数据 2)探索和准备数据 3)训练数据 4)评估模型 5)提高性能 1.理解神经网络 1) ...

  7. 【机器学习与R语言】6-线性回归

    目录 1.理解回归 1)简单线性回归 2)普通最小二乘估计 3)相关系数 4)多元线性回归 2.线性回归应用示例 1)收集数据 2)探索和准备数据 3)训练数据 4)评估模型 5)提高模型性能 1.理 ...

  8. 【机器学习与R语言】5-规则学习算法

    目录 1.分类规则原理 1.1 1R单规则算法 1.2 RIPPER算法 2. 规则学习应用示例 1)收集数据 2)探索和准备数据 3)训练数据 4)评估性能 5)提高性能 6)选择决策树中的分类规则 ...

  9. 【机器学习与R语言】4-决策树

    目录 1.决策树原理 2.决策树应用示例 2.1)收集数据 2.2)探索和准备数据 2.3)训练模型 2.4)评估模型性能 2.5)提高模型性能 通过自适应增强算法(boosting) 将惩罚因子分配 ...

随机推荐

  1. OO第四单元作业总结及课程总结

    一.本单元作业架构设计 1.第一次作业 本单元首次接触到UML以及相关概念,在面对第一次作业时首先花了很大功夫去阅读官方接口中各种UmlElement的代码,才理解了输入的模型元素中各属性的含义.总的 ...

  2. FastAPI 学习之路(二十九)使用(哈希)密码和 JWT Bearer 令牌的 OAuth2

    既然我们已经有了所有的安全流程,就让我们来使用 JWT 令牌和安全哈希密码让应用程序真正地安全. 关于 JWT 它是一个将 JSON 对象编码为密集且没有空格的长字符串的标准.字符串看起来像这样: e ...

  3. 前端大牛带你了解JavaScript 函数式编程

    前言 函数式编程在前端已经成为了一个非常热门的话题.在最近几年里,我们看到非常多的应用程序代码库里大量使用着函数式编程思想. 本文将略去那些晦涩难懂的概念介绍,重点展示在 JavaScript 中到底 ...

  4. 绘制PCB电路原理图的8种方法

    1.选择集成电路,变压器,晶体管等组件,这些组件体积庞大,有许多引脚并在电路中起主要作用,然后从选定的参考引脚中抽取,以减少错误. 2.如果PCB上标有元件编号(如VD870,R330,C466等), ...

  5. 万维网www与HTTP协议

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105901440 学习课程:<2019王道考研计算机网络> 学习目的 ...

  6. PCIE学习笔记--TLP Header详解(三)

    目录篇地址为:http://blog.chinaaet.com/justlxy/p/5100053481 Completions Completions的TLP Header的格式如下图所示: 这里来 ...

  7. JAVA笔记15__TCP服务端、客户端程序 / ECHO程序 /

    /** * TCP:传输控制协议,采用三方握手的方式,保证准确的连接操作. * UDP:数据报协议,发送数据报,例如:手机短信或者是QQ消息. */ /** * TCP服务器端程序 */ public ...

  8. $.ajax、$.get和$.post方法成功,完成请求,错误或失败的回调

    一.$.get和$.post的不同    1.get通过url提交的,post是通过http消息实体提交的    2.get提交大小限制为2kb,post不限制    3.get提交会被缓存下来,有安 ...

  9. lumen、laravel问题汇总

    框架报500 1.chmod 777 -R storage 将日志目录权限设置下. 2.修改fastcgi,将代码目录包含进去. fastcgi_param PHP_ADMIN_VALUE " ...

  10. 【完美解决】IDEA 中 Maven 报错 Cannot resolve xxx 和 Maven 中 Dependencies 报红/报错。

    目录 前提 场景 解决办法 1.首先,清除缓存,点击之后重启IDEA. 2.关闭IDEA,打开项目文件夹 3.重新打开 IDEA,找到右边的 Maven 4.解决 Maven 中 Dependenci ...