R分类器性能评价:图形方法

  1. 几个基本概念 对于二元分类器,我们可以把分类样本的真实值记为1(positive,正例/阳性),-1(或0,negative,负例/阴性)分类结果记作1(success)和-1(或0,failure)。分类器分类正确,为真(true);分类器分类错误为假(false) 那么分类结果会有四种可能: TP,真正例/真阳性,预测为1且预测正确 TN,真反例/真阴性,预测为-1且预测正确 FP,假正例/假阳性,预测为1且预测错误 FN,假反例/假阴性,预测为-1且预测错误 把上面的这四种结果构造列联表,就得到混淆矩阵(Confusion Matrix) 例:使用caret包的GermanCredit数据。信用卡的评分,包括多个预测变量,其中多数为0-1属性变量。分类为Good和Bad两类。采用logistic回归作为分类器,输出结果是分类为正例的概率。对这个概率取一个阈值(这里取的是1/2),大于阈值的判为正例小于阈值的判为反例。 library(caret) ## Loading required package: lattice ## Loading required package: ggplot2 data(GermanCredit) GermanCredit$Class <- factor(GermanCredit$Class, levels = c("Bad", "Good", 0, 1)) class <- GermanCredit$Class GermanCredit$Class[which(class == "Bad")] <- 0 GermanCredit$Class[which(class == "Good")] <- 1 GermanCredit$Class <- factor(GermanCredit$Class, levels = c(0, 1)) # remove near-zero variance predictors then get rid of a few predictors that # duplicate values GermanCredit <- GermanCredit[, -nearZeroVar(GermanCredit)] GermanCredit$CheckingAccountStatus.lt.0 <- NULL GermanCredit$SavingsAccountBonds.lt.100 <- NULL GermanCredit$EmploymentDuration.lt.1 <- NULL GermanCredit$EmploymentDuration.Unemployed <- NULL GermanCredit$Personal.Male.Married.Widowed <- NULL GermanCredit$Property.Unknown <- NULL GermanCredit$Housing.ForFree <- NULL # create training amd prediction datasets set.seed(1) train <- sample(1:1000, 900) credit.train <- GermanCredit[train, ] credit.test <- GermanCredit[-train, ] credit.glm <- glm(Class ~ ., family = binomial, data = credit.train) # Now to prediction credit.p <- predict(credit.glm, newdata = credit.test, type = "response") credit.n <- data.frame(credit.test$Class, credit.p) head(credit.n) ## credit.test.Class credit.p ## 16 0 0.4874 ## 18 1 0.1227 ## 19 0 0.5552 ## 26 1 0.8185 ## 27 1 0.8539 ## 43 1 0.8482 # set cutoff=1/2 cut = 1/2 Class.p <- floor(credit.p + cut) confusion <- table(credit.test$Class, Class.p) # confunsion matrix confusion ## Class.p ## 0 1 ## 0 15 13 ## 1 10 62 记全部样本个数为T,正例个数为P,负例个数为N。 可以计算各种比率,其中TPR=TP/P称为灵敏度(sensitivity)/召回率(recall), TNR=TN/N称为特指度(specicity),FPR=FP/P称误警率(Fallout),FNR=FP/N称为漏查率(miss). 分类器预测正确的比例称正确率(accuracy):(TP+TN)/T 分类器预测错误的比例称错误率(error rate):(FP+FN)/T TP <- confusion[4] TN <- confusion[3] FP <- confusion[2] FN <- confusion[1] N <- sum(credit.test$Class == 0) P <- sum(credit.test$Class == 1) TPR <- TP/P TNR <- TN/N FPR <- FP/P FNR <- FP/N ACC <- (sum(TN) + sum(TP))/sum(confusion) ERR <- (sum(FN) + sum(FP))/sum(confusion) 很多时候,我们更关心正例的分类精确与否,因此可以定义下面两个比率: TPR又可称为查全率,表示正确分类的正例占实际正例(TP/(TP+FN))的比例,用于衡量分类器预测正例的可信程度。 相对应的概念有查准率(precision),表示正确分类的正例占全部预测正例的比例(TP/(TP+FP))。 ROC和AUC 对于更关注于正例的情况,ROC(Receiver Operating Characteristic)是很常用的一种图形评价方法。 ROC曲线使用了上面定义的两种比率,灵敏度和误警率。 sensitivity(TPR):正确分类的正例数占实际正例的比例; specicity(TNR):正确分类的反例数占实际反例的比例; 1-specicity=FPR,错误分类的反例(“报警”)占实际反例的比例。 ROC曲线描述的是二元分类器TPR和FPR的相对变化情况。 如果二元分类模型输出的是分类为正例的概率,那么设置分类一个阈值就可以计算相应阈值下的sensitivity和1-specicity。如果取一组阈值,把对每个阈值计算得到的sensitivity和1-specicity绘制在图中,就得到ROC曲线。ROC曲线表示在尽量少的误判的基础上,尽可能多的判出正例的个体。 roc <- function(p, y, n) { y <- factor(y) l <- length(p) criteria <- p > matrix(rep(seq(1, 0, length = n), l), ncol = n, byrow = T) fpr <- colSums((y == levels(y)[1]) * criteria)/sum(y == levels(y)[1]) tpr <- colSums((y == levels(y)[2]) * criteria)/sum(y == levels(y)[2]) roc <- data.frame(tpr, fpr) } roc.result <- roc(credit.p, credit.test$Class, 100) library(ggplot2) ggplot(roc.result, aes(x = fpr, y = tpr)) + geom_line(color = "blue") + geom_segment(aes(x = 0, y = 0, xend = 1, yend = 1), color = "grey", lty = 2)

如果ROC曲线可以经过点(0,1),即特指度和灵敏度都是1,那么就是一个最优的分类器。但是绝大多数分类器做不到这一点。因此,引入AUC:ROC曲线下的面积来度量不同分类器的表现。AUC越大,则分类性能越好。

3.提升度和提升曲线 分类器分类为正例的比例称为深度(depth):(TP+FP)/T,T是全部待判样本数量。 提升度(lift)等于TPR/depth 以深度为横轴,以提升度为纵轴绘制曲线,得到提升曲线。 绘制提升曲线的思路和ROC类似。当阈值为0的时候,所有的样本都会判为正例,此时深度为1,提升为1;随阈值增大,深度减小,提升随之逐渐增大。一个好的模型要在大的深度下得到尽量大的提升。 lift.c <- function(p, y, n) { y <- factor(y) l <- length(p) criteria <- p > matrix(rep(seq(1, 0, length = n), l), ncol = n, byrow = T) fp <- colSums((y == levels(y)[1]) * criteria) tp <- colSums((y == levels(y)[2]) * criteria) fpr <- fp/sum(y == levels(y)[1]) tpr <- tp/sum(y == levels(y)[2]) depth <- (tp + fp)/length(y) tpr <- tpr[depth != 0] depth <- depth[depth != 0] lift <- tpr/depth lift.c <- data.frame(depth, lift) } lift.result <- lift.c(credit.p, credit.test$Class, 100) ggplot(lift.result, aes(x = depth, y = lift)) + geom_line(color = "blue")

提升曲线常用于市场营销。一个经常在各种书籍中被举出的例子是邮寄广告促销(现在是短信?)。只有很少的人(潜在客户)会响应这种促销,因此对大量人群的进行邮寄广告促销会有较高的成本。因此通过分类器寻找可能会积极响应的客户,其中的潜在客户的比例提升了。 其他图形化方法还有 precision/recall曲线,洛伦兹曲线等。 4.ROCR包 图形方法(特别是ROC)是在机器学习/数据挖掘中用来评价模型的重要方法。在R当中,有多个package可用来绘制相应的图形。其中最常用的一个当属ROCR包,可用于绘制ROC曲线和提升曲线。 使用ROCR包来绘制上面的ROC曲线,并计算AUC值 library(ROCR) pre <- prediction(credit.p, credit.test$Class) plot(performance(pre, "tpr", "fpr"), main = "ROC CURVE", colorize = T) performance(pre, measure = "auc")@y.values ## [1] ## [1] 0.7902

其中prediction函数产生预测对象,performance函数可以计算对预测对象的各种评价方法(结果是个S4类)。使用plot函数可以绘制ROC曲线,colorize=T表示可以按颜色在图形上表示出阈值的分布。 绘制提升曲线 plot(performance(pre, "lift", "rpp"), main = "LIFT CURVE", colorize = T)

R的Daim包和pROC包也可以绘制ROC曲线

(原文:http://site.douban.com/182577/widget/notes/10567212/note/348006411/)

原文发布于微信公众号 - 大数据挖掘DT数据分析(datadw)

原文发表时间:2016-02-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器学习算法与Python学习

SVM大解密(附代码和公式)

1815
来自专栏专知

【专知-Java Deeplearning4j深度学习教程05】无监督特征提取神器—AutoEncoder:图文+代码

【导读】主题链路知识是我们专知的核心功能之一,为用户提供AI领域系统性的知识学习服务,一站式学习人工智能的知识,包含人工智能( 机器学习、自然语言处理、计算机视...

47811
来自专栏专知

100+中文词向量,总有一款适合你

2174
来自专栏大学生计算机视觉学习DeepLearning

深度学习(七)U-Net原理以及keras代码实现医学图像眼球血管分割

原文链接:https://www.cnblogs.com/DOMLX/p/9780786.html

1K4
来自专栏机器之心

ACL 2018 | 神经语言模型如何利用上下文信息:长距离上下文的词序并不重要

2215
来自专栏PPV课数据科学社区

学习SVM,这篇文章就够了!

支持向量机(SVM),一个神秘而众知的名字,在其出来就受到了莫大的追捧,号称最优秀的分类算法之一,以其简单的理论构造了复杂的算法,又以其简单的用法实现了复杂的问...

3724
来自专栏人工智能

kNN-Iris分类器(一)

“著名的鸢尾花(Iris)数据集(由Ronald Fisher于1936年发表)是一种展示机器学习框架API的好方法。从某种程度上说,Iris数据集是机器学习界...

35410
来自专栏AI派

如何使用sklearn加载和下载机器学习数据集

sklearn 中提供了很多常用(或高级)的模型和算法,但是真正决定一个模型效果的最后还是取决于训练(喂养)模型时所用的数据。sklearn 中的 sklear...

6195
来自专栏Coding迪斯尼

手算梯度下降法,详解神经网络迭代训练过程

1564
来自专栏数据派THU

一文读懂支持向量机SVM(附实现代码、公式)

支持向量机(SVM),一个神秘而众知的名字,在其出来就受到了莫大的追捧,号称最优秀的分类算法之一,以其简单的理论构造了复杂的算法,又以其简单的用法实现了复杂的问...

4293

扫码关注云+社区