大家早上好,本人姓吴,如果觉得文章写得还行的话也可以叫我吴老师。欢迎大家跟我一起走进数据分析的世界,一起学习!

感兴趣的朋友可以关注我或者我的数据分析专栏,里面有许多优质的文章跟大家分享哦。


必看前言

不知道你是否已经看完了我之前讲过的有关机器学习的文章,如果没看过也没关系,因为本篇文章介绍的内容适用于所有分类模型(包括神经网络),主要就是介绍分类模型的评估指标。另外,在前面我还会提一下数据不平衡的问题该如何处理。

总之本篇文章实用性极强!

目录

  • 必看前言
  • 分类模型的评估指标
    • 1 样本不均匀问题
    • 2 混淆矩阵
      • 2.1 模型整体效果:准确率
      • 2.2 精确度 Precision
      • 2.3 召回率 Recall
      • 2.4 F1 measure
      • 2.5 假负率
      • 2.6 ROC 曲线
      • 2.7 sklearn 中的混淆矩阵
        • 2.7.1 混淆矩阵
        • 2.7.2 准确率
        • 2.7.2 召回率
        • 2.7.3 F 值
      • 2.8 总结
  • 结束语

分类模型的评估指标

1 样本不均匀问题

对于分类问题,永远都逃不过的一个痛点就是样本不均衡问题(本人曾做过一个科研项目,因不懂如何处理不平衡处理导致模型效果始终不如人意,真的很是心酸)。

而样本不均衡是指在一组数据集中,标签的一类天生占有很大的比例,但我们有着捕捉出某种特定的分类的需求的状况。比如,我们现在要对潜在犯罪者和普通人进行分类,潜在犯罪者占总人口的比例是相当低的,也许只有2%左右,98%的人都是普通人,而我们的目标是要捕获出潜在犯罪者。这样的标签分布会带来许多问题。

首先,分类模型天生会倾向于多数的类,让多数类更容易被判断正确,少数类被牺牲掉。因为对于模型而言,样本量越大的标签可以学习的信息越多,算法就会更加依赖于从多数类中学到的信息来进行判断。如果我们希望捕获少数类,模型就会失败。

其次,模型评估指标会失去意义。这种分类状况下,即便模型什么也不做,全把所有人都当成不会犯罪的人,准确率也能非常高,这使得模型评估指标 accuracy 变得毫无意义,根本无法达到我们的“要识别出会犯罪的人”的建模目的。 所以现在,我们首先要让算法意识到数据的标签是不均衡的,通过施加一些惩罚或者改变样本本身,来让模型向着捕获少数类的方向建模。

我们可以使用上采样和下采样来达成这个目的,所用的方法叫做 SMOTE,这种方法通过将少数类的特征重新组合,创造出更多的少数类样本。但这些采样方法会增加样本的总数,对于决策树这个样本总是对计算速度影响巨大的算法来说,我们完全不想轻易地增加样本数量,所以我们要寻求另一条路:改进我们的模型评估指标,使用更加针对于少数类的指标来优化模型。

class_weight

在决策树中,存在着调节样本均衡的参数:class_weight 和接口 fit 中可以设定的sample_weight。

在决策树中,参数 class_weight 默认 None,此模式表示假设数据集中的所有标签是均衡的,即自动认为标签的比例是 1:1。所以当样本不均衡的时候,我们可以使用形如 {“标签的值 1”:权重 1,“标签的值 2”:权重 2} 的字典来输入真实的样本标签比例,来让算法意识到样本是不平衡的。或者使用”balanced“模式

这里我们可以来做一下效果对比。

先导入所需模块:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_blobs #聚类产生数据集的方法

然后随机生成两类数据:

class_1 = 1000   #类别1 样本1000个
class_2 = 100    #类别2 样本100个
centers = [[0,0],[2.0,2.0]] #两个类别的中心点
clusters_std = [2.5,0.5] #两个类别的方差 X,y = make_blobs(n_samples=[class_1,class_2],centers=centers,cluster_std=clusters_std,random_state=420,shuffle=False)plt.scatter(X[:,0],X[:,1],c=y,cmap='rainbow',s=10)

生成数据如下:


接着我们来划分数据集:

#划分数据集
Xtrain,Xtest,Ytrain,Ytest = train_test_split(X,y,test_size=0.2,random_state=420)

接下来分别查看设置了class_weight的和不设置class_weight的区别。

#不设定class_weight
clf_01 = DecisionTreeClassifier()
clf_01.fit(Xtrain,Ytrain)#设定class_weight
clf_02 = DecisionTreeClassifier(class_weight='balanced')
clf_02.fit(Xtrain,Ytrain)
clf_01.score(Xtest,Ytest)

0.9

clf_02.score(Xtest,Ytest)

0.9045454545454545

这里可以看到是有所提升,而且如果数据不平衡情况更明显的话,提升也会更明显。

另外,有了权重之后,样本量就不再是单纯地记录数目,而是受输入的权重影响了,因此这时候剪枝,就需要搭配 min_ weight_fraction_leaf 这个基于权重的剪枝参数来使用。

请注意,基于权重的剪枝参数(例如 min_weight_ fraction_leaf)将比不知道样本权重的标准(比如min_samples_leaf)更少偏向主导类。如果样本是加权的,则使用基于权重的预修剪标准来更容易优化树结构,这确保叶节点至少包含样本权重的总和的一小部分。

2 混淆矩阵

从上面内容可以看出,如果我们的目标是希望尽量捕获少数类,那准确率这个模型评估逐渐失效,所以我们需要新的模型评估指标来帮助我们。如果简单来看,其实我们只需要查看模型在少数类上的准确率就好了,只要能够将少数类尽量捕捉出来,就能够达到我们的目的。

但此时,新问题又出现了,我们对多数类判断错误后,会需要人工甄别或者更多的业务上的措施来一一排除我们判断错误的多数类,这种行为往往伴随着很高的成本。比如银行在判断”一个申请信用卡的客户是否会出现违约行为“的时候,如果一个客户被判断为”会违约“,这个客户的信用卡申请就会被驳回,如果为了捕捉出”会违约“的人,大量地将”不会违约“的客户判断为”会违约“的客户,就会有许多无辜的客户的申请被驳回。信用卡对银行来说意味着利息收入,而拒绝了许多本来不会违约的客户,对银行来说就是巨大的损失。同理,大众在召回不符合欧盟标准的汽车时,如果为了找到所有不符合标准的汽车,而将一堆本来符合标准了的汽车召回,这个成本是不可估量的。

也就是说,单纯地追求捕捉出少数类,就会成本太高,而不顾及少数类,又会无法达成模型的效果。所以在现实中,我们往往在寻找捕获少数类的能力和将多数类判错后需要付出的成本的平衡。如果一个模型在能够尽量捕获少数类的情况下,还能够尽量对多数类判断正确,则这个模型就非常优秀了。为了评估这样的能力,我们将引入新的模型评估指标:混淆矩阵来帮助我们。

  • 混淆矩阵是二分类问题的多维衡量指标体系,在样本不平衡时极其有用。
  • 在混淆矩阵中,我们将少数类认为是正例,多数类认为是负例。
  • 在决策树,随机森林这些分类算法里,即是说少数类是 1,多数类是 0
  • 在 SVM 里,就是说少数类是 1,多数类是-1

我们来看下表:

其中:

  • 行代表预测情况,列则表示实际情况。
  • 预测值为 1,记为 P(Positive)
  • 预测值为 0,记为 N(Negative)
  • 预测值与真实值相同,记为 T(True)
  • 预测值与真实值相反,记为 F(False)

因此矩阵中四个元素分别表示:

  • TP(True Positive): 真实为 1,预测作 1
  • FN(False Negative): 真实为 1,预测作 0
  • FP(False Positive): 真实为 0,预测作 1
  • TN(True Negative): 真实为 0,预测作 0

基于混淆矩阵,我们有一系列不同的模型评估指标,这些评估指标的范围都在[0,1]之间,所有以 11 和00 为分子的指标都是越接近 1 越好,所以以 01 和 10 为分子的指标都是越接近 0 越好。对于所有的指标, 我们用橙色表示分母,用绿色表示分子,则我们有:

2.1 模型整体效果:准确率

Accuracy=11+0011+10+01+00Accuracy=\frac{11+00}{11+10+01+00}Accuracy=11+10+01+0011+00​准确率 Accuracy 就是所有预测正确的所有样本除以总样本,通常来说越接近 1 越好。 记住少数类是1,多数类是 0。

2.2 精确度 Precision

Precision=1111+01Precision=\frac{11}{11+01}Precision=11+0111​精确度 Precision,又叫查准率,表示在所有预测结果为 1 的样例数中,实际为 1 的样例数所占比重。精确度越低,意味着 01 比重很大,则代表你的模型对多数类 0 误判率越高,误伤了过多的多数类。 为了避免对多数类的误伤,需要追求高精确度。

精确度是” 将多数类判错后所需付出成本的衡量’’。

#所有判断正确并确实为 1 的样本 / 所有被判断为 1 的样本 #对于没有 class_weight 的决策树来说:
Precision_1 = (Ytest[Ytest == clf_01.predict(Xtest)] == 1).sum()/(clf_01.predict(Xtest) == 1).sum()
Precision_1

0.6363636363636364

#对于有 class_weight 的决策树来说:
Precision_2 = (Ytest[Ytest == clf_02.predict(Xtest)] == 1).sum()/(clf_02.predict(Xtest) == 1).sum()
Precision_2

0.68

在现实的样本不平衡例子中,当每一次将多数类判断错误的成本非常高昂的时候(比如大众召回车辆的例子),我们会追求高精确度。

当然了,如果我们的目标是不计一切代价捕获少数类,那我们并不在意精确度,而在意召回率。

2.3 召回率 Recall

召回率 Recall,又被称为敏感度(sensitivity),真正率,查全率,表示所有真实为 1 的样本中,被我们预测正确的样本所占的比例。

召回率越高,代表我们尽量捕捉出了越多的少数类。

召回率越低,代表我们没有捕捉出足够的少数类。

Recall=1111+10Recall=\frac{11}{11+10}Recall=11+1011​

#所有 predict 为 1 并且正确的点 / 全部为 1 的点的比例
#对于没有 class_weight 的决策树来说:
(ytest[ytest == clf.predict(Xtest)] == 1).sum()/(ytest == 1).sum()

0.4827586206896552

#对于有 class_weight 的决策树来说:
(ytest[ytest == wclf.predict(Xtest)] == 1).sum()/(ytest == 1).sum()

0.5862068965517241

可以看出,做样本平衡之前,我们只成功捕获了 48%左右的少数类点,而做了样本平衡之后的模型,捕捉出了 58%的少数类点。召回率可以帮助我们判断,我们是否捕捉除了全部的少数类,所以又叫做查全率。

如果我们希望不计一切代价,找出少数类(比如找出潜在犯罪者的例子),那我们就会追求高召回率,相反如果我们的目标不是尽量捕获少数类,那我们就不需要在意召回率。

注意召回率和精确度的分子是相同的(都是 11),只是分母不同。而召回率和精确度是此消彼长的,两者之间的平衡代表了捕捉少数类的需求和尽量不要误伤多数类的需求的平衡。

究竟要偏向于哪一方,取决于我们的业务需求:究竟是误伤多数类的成本更高,还是无法捕捉少数类的代价更高。

2.4 F1 measure

为了同时兼顾精确度和召回率,我们创造了两者的调和平均数作为考量两者平衡的综合性指标,称之为F1 measure

两个数之间的调和平均倾向于靠近两个数中比较小的那一个数,因此我们追求尽量高的 F1 measure,能够保证我们的精确度和召回率都比较高。

F1 measure 在[0,1]之间分布,越接近 1 越好。F−measure=21Precision+1Recall=2∗PrecisionPrecision+RecallF-measure=\frac{2}{\frac{1}{Precision}+\frac{1}{Recall}=\frac{2*Precision}{Precision+Recall}}F−measure=Precision1​+Recall1​=Precision+Recall2∗Precision​2​

2.5 假负率

从 Recall 延申出来的另一个评估指标叫做假负率(False Negative Rate),它等于 1 - Recall,用于衡量所有真实为 1 的样本中,被我们错误判断为 0 的,通常用得不多。FNR=1011+10FNR=\frac{10}{11+10}FNR=11+1010​

2.6 ROC 曲线

ROC 的全称是 Receiver Operating Characteristic Curve,其主要的分析方法就是画这条特征曲线。

该曲线的横坐标为假正率(False Positive Rate, FPR), N 是真实负样本的个数, FP 是 N 个负样本中被分类器器预测为正样本的个数。

横坐标为假正率:FPR=0101+00FPR=\frac{01}{01+00}FPR=01+0001​纵坐标为召回率,真正率(True Positive Rate, TPR):TPR=1111+10TPR=\frac{11}{11+10}TPR=11+1011​P 是真实正样本的个数,TP 是 P 个正样本中被分类器器预测为正样本的个数。

根据横纵坐标的定义我们不难理解,如果说模型的ROC曲线越贴近y轴(越凸)说明效果就越好,越靠近x轴(越凹)说明效果越差。

这里可以补充一个AUC(Area Under roc Curve)的知识点,其实顾名思义也就是曲线下覆盖的面积,所以就是AUC越大越好。

2.7 sklearn 中的混淆矩阵

含义
sklearn.metrics.confusion_matrix 混淆矩阵
sklearn.metrics.accuracy 准确率accuracy
sklearn.metrics.precision_score 精确率precision sklearn.metrics.recall_score
sklearn.metrics.precision_recall_curve 精确率-召回率平衡曲线
sklearn.metrics.f1_score F1_measure
sklearn.metrics.classification_report 准确率精确率召回率应有尽有

2.7.1 混淆矩阵

#平衡前
metrics.confusion_matrix(Ytest,clf_01.predict(Xtest))

array([[183, 8],
[ 15, 14]], dtype=int64)

#平衡后
metrics.confusion_matrix(Ytest,clf_02.predict(Xtest))

array([[182, 9],
[ 12, 17]], dtype=int64)

2.7.2 准确率

metrics.precision_score(Ytest,clf_01.predict(Xtest))

0.6363636363636364

metrics.precision_score(Ytest,clf_02.predict(Xtest))

0.6538461538461539

2.7.2 召回率

metrics.recall_score(Ytest,clf_01.predict(Xtest))

0.4827586206896552

metrics.recall_score(Ytest,clf_02.predict(Xtest))

0.5862068965517241

2.7.3 F 值

metrics.f1_score(Ytest,clf_01.predict(Xtest))

0.5490196078431373

metrics.f1_score(Ytest,clf_02.predict(Xtest))

0.6181818181818182

2.8 总结

总的来说,最最最常用的评估指标就是混淆矩阵和ROC曲线。

结束语

到这里,有关于监督学习的分类模型就讲完啦。后面我会结合实战再同大家分享,而且也会介绍回归模型和一些无监督学习的算法,感兴趣的可以点击下方专栏进行关注。

推荐关注的专栏

你真的了解分类模型评估指标都有哪些吗?【附Python代码实现】相关推荐

  1. multi-class分类模型评估指标的定义、原理及其Python实现

    诸神缄默不语-个人CSDN博文目录 本文介绍multi-class分类任务中的模型评估指标及其使用Python的实现方式(包括使用sklearn进行实现,以及使用原生Python函数进行实现的操作). ...

  2. R语言分类模型:逻辑回归模型LR、决策树DT、推理决策树CDT、随机森林RF、支持向量机SVM、Rattle可视化界面数据挖掘、分类模型评估指标(准确度、敏感度、特异度、PPV、NPV)

    R语言分类模型:逻辑回归模型LR.决策树DT.推理决策树CDT.随机森林RF.支持向量机SVM.Rattle可视化界面数据挖掘.分类模型评估指标(准确度.敏感度.特异度.PPV.NPV) 目录

  3. R语言编写自定义函数计算分类模型评估指标:准确度、特异度、敏感度、PPV、NPV、数据数据为模型预测后的混淆矩阵、比较多个分类模型分类性能(逻辑回归、决策树、随机森林、支持向量机)

    R语言编写自定义函数计算分类模型评估指标:准确度.特异度.敏感度.PPV.NPV.数据数据为模型预测后的混淆矩阵.比较多个分类模型分类性能(逻辑回归.决策树.随机森林.支持向量机) 目录

  4. 3个最常用的分类模型评估指标!

    针对二元分类结果,常用的评估指标有如下三个:查准率(Precision).查全率(Recall)以及F-score.这篇文章将讨论这些指标的含义.设计初衷以及局限性. 01 二元分类问题 在机器学习领 ...

  5. 关于分类模型评估指标的理解

    准确度.精确率.召回率.F1值作为评估指标,经常用到评估模型的分类效率.准确度评估预测正确的比例,精确率评估预测正例的查准率,召回率评估真实正例的查全率,二分类问题比较好理解,面对多分类问题拆分成多个 ...

  6. [机器学习] 二分类模型评估指标---精确率Precision、召回率Recall、ROC|AUC

    一 为什么要评估模型? 一句话,想找到最有效的模型.模型的应用是循环迭代的过程,只有通过持续调整和调优才能适应在线数据和业务目标. 选定模型时一开始都是假设数据的分布是一定的,然而数据的分布会随着时间 ...

  7. 分类模型-评估指标(2):ROC曲线、 AUC值(ROC曲线下的面积)【只能用于二分类模型的评价】【不受类别数量不平衡的影响;不受阈值取值的影响】【AUC的计算方式:统计所有正负样本对中的正序对】

    评价二值分类器的指标很多,比如precision.recall.F1 score.P-R曲线等.但这些指标或多或少只能反映模型在某一方面的性能.相比而言,ROC曲线则有很多优点,经常作为评估二值分类器 ...

  8. 最完整的检测模型评估指标mAP计算指南(附代码)在这里!

    http://baijiahao.baidu.com/s?id=1605049172612184744&wfr=spider&for=pc

  9. 图像质量评估指标:PSNR / SSIM 原理及Python代码

    1. PSNR   PSNR(峰值信噪比,Peak Signal-to-Noise Ratio),用于衡量两张图像之间差异,例如压缩图像与原始图像,评估压缩图像质量:复原图像与ground truth ...

最新文章

  1. Python的scrapy之爬取顶点小说网的所有小说
  2. jQuery.sap.require
  3. Apache用户身份验证
  4. M. Monster Hunter(树形dp)
  5. 【JAVA线程间通信技术】
  6. linux分支结构,实验四 Shell脚本中的分支结构
  7. android7.0 ActivityManagerService(AMS)启动流程
  8. 双A复制mysql_mysql双主复制并利用keepalived做高可用
  9. 西工大疫情期间关于如何做好博士学位论文专题讲座笔记
  10. 共享茶室小程序开发解决方案
  11. 【openGL2021版】天空盒
  12. source-map配置
  13. 2018年中考计算机考试成绩,2018年北京中考考试科目、时间及成绩公布通知
  14. python symbols函数_Python的武器库07:sympy模块
  15. 6 - 常用模块(os,sys,timedatetime,random,jsonpicle,shelve,hashlib)
  16. Win11电脑名如何更改?Win11更改电脑名的方法
  17. Android使用xml自定义软键盘效果(附源码)
  18. MIS系统开发利器,快速的字典录入解决方案,另类的、可管理的.NET DataWindow
  19. [C语言]实现字符串从头尾分别输出字符的动画效果
  20. ubuntu18.04 台式机无线网卡驱动安装 Tenda U10 rtl8811CU

热门文章

  1. 深入探索Win32结构化异常处理
  2. 社区计算机义务维修策划书,义务维修电脑策划书.doc
  3. Emoj cheat sheet
  4. 京东推荐商品列表API接口-(item_recommend-获取推荐商品列表API接口),京东API接口
  5. Linux 驱动程序 USB控制
  6. 渗透测试-Docker容器
  7. java捕获唯一约束异常_java – 捕获JPA上唯一约束的原因
  8. STM32CubeMx开发之路—使用SysTick实现微妙延时函数delay_us()
  9. 我对移动支付的看法_对移动支付的看法作文_作文写作问答 - 归教作文网
  10. UE4 的 VR 视野破碎或右眼错误的解决方案 —— 从 Ocean Floor Environment 项目