准确度的陷阱和混淆矩阵和精准率召回率

准确度的陷阱

准确度并不是越高说明模型越好,或者说准确度高不代表模型好,比如对于极度偏斜(skewed data)的数据,假如我们的模型只能显示一个结果A,但是100个数据只有一个结果B,我们的准确率会是99%,我们模型明明有问题却有极高的准确率,这让我们对模型的评价容易出现问题。所以只用分类准确度是远远不够的,使用混淆矩阵做进一步分析。

混淆矩阵

精准率召回率


可以发现精确率跟召回率都是与预测值是1相关,我们通常把我们想预测实物的发生事件赋值为1,比如癌症发生的概率,信用卡失信的概率,赋值为1的通常是我们比较在意的,想知道的。

精准率:做了n次分类为1的预测,其中有几个正确的

召回率:样本中真实值有n个1,我们预测对了其中几个

动手实现以下精准率与召回率

采用digits数据集,为了达到极度偏斜的效果,我们将所有数据设为如果是9为1,不是9为0

import numpy as np
from sklearn import datasetsdigits = datasets.load_digits()
X = digits.data
y = digits.target.copy() #如果直接引用那么y变了,target也会变
y[digits.target==9] = 1
y[digits.target!=9] = 0from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=666)
# 逻辑回归预测一哈
from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression()
log_reg.fit(X_train, y_train)
log_reg.score(X_test, y_test)y_log_predict = log_reg.predict(X_test) # 获取预测的答案def TN(y_true, y_predict):assert len(y_true) == len(y_predict)return np.sum((y_true == 0) & (y_predict == 0))def FP(y_true, y_predict):assert len(y_true) == len(y_predict)return np.sum((y_true == 0) & (y_predict == 1))def FN(y_true, y_predict):assert len(y_true) == len(y_predict)return np.sum((y_true == 1) & (y_predict == 0))def TP(y_true, y_predict):assert len(y_true) == len(y_predict)return np.sum((y_true == 1) & (y_predict == 1))def confusion_matrix(y_true, y_predict):return np.array([[TN(y_true, y_predict), FP(y_true, y_predict)],[FN(y_true, y_predict), TP(y_true, y_predict)]])confusion_matrix(y_test, y_log_predict)def precision_score(y_true, y_predict):tp = TP(y_true, y_predict)fp = FP(y_true, y_predict)try:return tp / (tp + fp)except:return 0.0def recall_score(y_true, y_predict):tp = TP(y_true, y_predict)fn = FN(y_true, y_predict)try:return tp / (tp + fn)except:return 0.0
print("score:" , log_reg.score(X_test, y_test))
print("precision_score", precision_score(y_test, y_log_predict))
print("recall_score", recall_score(y_test, y_log_predict))
score: 0.9755555555555555
precision_score 0.9473684210526315
recall_score 0.8

scikit-learn中的混淆矩阵,精确率和召回率

#因为是与指标相关,所以都是metrics
from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, y_log_predict)from sklearn.metrics import precision_score
precision_score(y_test, y_log_predict)from sklearn.metrics import recall_score
recall_score(y_test, y_log_predict)
0.8

精准率召回率的选取

与模型应用的模型有关,如果与1代表股票的要升,0代表降,那么我们肯定更在乎精准率,精准率高代表我们预测对很多,买到升的股票的概率更高,召回率却没什么用了,就算有些本来要上升的股票我们却预测错了,也没什么损失,因为我们不会去买它。召回率在医疗领域比较重要,召回率高说明我们漏掉的有病的人比较少。

F1 Score

上面两个例子都较为极端,在一些两者差别不是很大的情况下,通常用F1 Score.
F1Score 是precision和recall的调和平均值,也就是如果一个很高另一个很低,那么他们的调和平均值也很低,只有二者都很高,调和平均值才会很高.F1 Score取值是在0到1之间的

from sklearn.metrics import f1_score
f1_score(y_test, y_predict)

精准率和召回率的平衡

精准率和召回率之间是互相矛盾的,如果提高召回率,精准率就不可避免的下降,如果精准率提高,召回率就不可避免的下降。

分类阈值的取值的影响

在逻辑回归中,我们让决策边界是 θ* X = 0作为决策边界,即大于0的分类1,小于0的分类0,我们可以不让他是0,而是一个常数threshold.下图是threshold取不同的值可能产生的变化

log_reg.decision_function(X_test)[:10]
# 这个函数就是逻辑回归模型里那个threshold的值,模型的默认值都是0
'''调用函数输出结果
array([-22.05700185, -33.02943631, -16.21335414, -80.37912074,-48.25121102, -24.54004847, -44.39161228, -25.0429358 ,-0.97827574, -19.71740779])'''
np.min(decision_scores) #分类标准阈值的最大值
np.max(decision_scores)
y_predict_2 = np.array(decision_scores >= 5, dtype='int') #这样就改变了分类标准的阈值,大于5的才是1

Precision-Recall-Curve(PR曲线)

随着分类阈值的不断变化,precision和recall值也会不断变化,那么我们可以画出其相应的曲线,可以在曲线中找到一个F1 Score最高的分类阈值。通常在recall要急剧下降的那个位置。

实现自己的PR曲线

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasetsdigits = datasets.load_digits()
X = digits.data
y = digits.target.copy()
y[digits.target==9] = 1
y[digits.target!=9] = 0from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=666)from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression()
log_reg.fit(X_train, y_train)
decision_scores = log_reg.decision_function(X_test)from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
precisions = []
recalls = []
thresholds = np.arange(np.min(decision_scores), np.max(decision_scores), 0.1) #以0.1为步长获取分类阈值最大值到最小值里的点
for threshold in thresholds:y_predict = np.array(decision_scores >= threshold, dtype='int') # 每个点求一次 precision_score和recall_scoreprecisions.append(precision_score(y_test, y_predict))recalls.append(recall_score(y_test, y_predict))
#画出对应的值
plt.plot(thresholds, precisions)
plt.plot(thresholds, recalls)
plt.show()

scikit-learn 中的PR曲线

from sklearn.metrics import precision_recall_curve
precisions, recalls, thresholds = precision_recall_curve(y_test, decision_scores)
#注意通过这个函数得到的precision和recall的最后一个值分别为1和0,没有对应的Score
plt.plot(thresholds, precisions[:-1])  #所以不取最后一个
plt.plot(thresholds, recalls[:-1])
plt.show()plt.plot(precisions, recalls)
plt.show()

ROC曲线

ROC曲线是用来描述TPR与FPR之间的曲线之间的关系.

TPR(True-Positive-Rate): 代表预测为1并且预测对了的样本数量占真实值为1的百分比为多少

FPR(False-Positive-Rate):代表预测为1但预测错了的样本数量占真实值为0的百分比是多少

分类阈值改变,TPR和FPR的变化

会发现当阈值变低,TPR与FPR值都变高,阈值变低那么预测值更容易变成1,所以预测值为1的样本也多了,真实值为1的总量是不变的,所以TPR变高,同理预测错了的样本也会变多。

ROC曲线的面积越大,那么我们的模型就越好,因为如果绘制一个FPR-TPR的曲线,在同样的FPR(犯错率)之下,TCP的值越高,模型越好,相应的他的面积越大

ROC对有偏数据并不敏感,主要用来比较两个模型谁更好一些,比如一个算法不同参数,或者两个不同的算法,都可以用这个来比较,如果他们的数据不是极度偏移的话

from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression()
log_reg.fit(X_train, y_train)
decision_scores = log_reg.decision_function(X_test) #获取逻辑回归每个样本的decision_scoresfrom sklearn.metrics import roc_curve
fprs, tprs, thresholds = roc_curve(y_test, decision_scores) #获取tpr与fpr的值plt.plot(fprs, tprs)
plt.show()from sklearn.metrics import roc_auc_score #求面积, 面积最大就为1,因为TPR与FPR最大值都为1
roc_auc_score(y_test, decision_scores)

对多分类的模型评价

这里只研究多分类混淆矩阵,其他的以后在详细研究一下。

import numpy as np
import matplotlib.pyplot as pltfrom sklearn import datasets
digits = datasets.load_digits()
X = digits.data #数据并没有进行切割,所以这是10分类问题
y = digits.targetfrom sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.8, random_state=666)from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression()
log_reg.fit(X_train, y_train)
log_reg.score(X_test, y_test)y_predict = log_reg.predict(X_test)from sklearn.metrics import precision_score
precision_score(y_test, y_predict) #如果直接获取矩阵,会报错
ValueError: Target is multiclass but average='binary'. Please choose another average setting.
precision_score(y_test, y_predict, average="micro") #根据错误提示,需要更改参数from sklearn.metrics import confusion_matrix
confusion_matrix(y_test, y_predict) #跟2分类的混淆矩阵的含义一样,行代表真实值列代表预测值
array([[147,   0,   1,   0,   0,   1,   0,   0,   0,   0],[  0, 123,   1,   2,   0,   0,   0,   3,   4,  10],[  0,   0, 134,   1,   0,   0,   0,   0,   1,   0],[  0,   0,   0, 138,   0,   5,   0,   1,   5,   0],[  2,   5,   0,   0, 139,   0,   0,   3,   0,   1],[  1,   3,   1,   0,   0, 146,   0,   0,   1,   0],[  0,   2,   0,   0,   0,   1, 131,   0,   2,   0],[  0,   0,   0,   1,   0,   0,   0, 132,   1,   2],[  1,   9,   2,   3,   2,   4,   0,   0, 115,   4],[  0,   1,   0,   5,   0,   3,   0,   2,   2, 134]], dtype=int64)
cfm = confusion_matrix(y_test, y_predict)
plt.matshow(cfm, cmap=plt.cm.gray) #一个矩阵的绘制参数,第一个参数是矩阵,第二个参数是颜色
plt.show()

row_sums = np.sum(cfm, axis=1)
err_matrix = cfm / row_sums #绘制比例
np.fill_diagonal(err_matrix, 0) # 因为对角线肯定对的多,赋值为0plt.matshow(err_matrix, cmap=plt.cm.gray)
plt.show() #这样就看出把什么看成什么的错误多了

机器学习-------评价分类结果相关推荐

  1. [Python从零到壹] 十四.机器学习之分类算法五万字总结全网首发(决策树、KNN、SVM、分类对比实验)

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  2. 机器学习 文本分类 代码_无需担心机器学习-如何在少于10行代码中对文本进行分类

    机器学习 文本分类 代码 This article builds upon my previous two articles where I share some tips on how to get ...

  3. 机器学习5—分类算法之随机森林(Random Forest)

    随机森林(Random Forest) 前言 一.随机森林 1.什么是随机森林 2.随机森林的特点 3.随机森林的生成 二.随机森林的函数模型 三.随机森林算法实现 1.数据的读取 2.数据的清洗和填 ...

  4. 《学术小白的实战之路》01 LDA-Word2Vec-TF-IDF组合特征的机器学习情感分类模型研究

    书山有路勤为径,学海无涯苦作舟 三更灯火五更鸡,正是男儿读书时 一.传统的机器学习分类模型 1.1 对文本的数据进行分词 数据样式 自定义分词词典.去除停用词,分词 #---------------- ...

  5. 机器学习—— SVM分类垃圾短信

    机器学习-- SVM分类算法 垃圾短信分类问题 Python语言凭借其强大的特性,其众多的外部库支持下,在机器学习和数据挖掘等领域发挥着强大的作用.本文基于python的机器学习库scikit-lea ...

  6. 机器学习——二分类、多分类的精确率和召回率

    机器学习有很多评估的指标.有了这些指标我们就横向的比较哪些模型的表现更好.我们先从整体上来看看主流的评估指标都有哪些: 分类问题评估指标: 准确率 – Accuracy 精确率(差准率)- Preci ...

  7. 人工智能概述、人工智能发展历程、人工智能主要分支、机器学习工作流程、完整机器学习项目的流程、机器学习算法分类、独立同分布、模型评估、深度学习简介

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) 1.1 人工智能概述 1 人工智能应用场景 2 人工智能小案例 ...

  8. 机器学习 二分类分类阈值_分类指标和阈值介绍

    机器学习 二分类分类阈值_分类指标和阈值介绍_weixin_26752765的博客-CSDN博客 机器学习 二分类分类阈值_分类指标和阈值介绍_weixin_26752765的博客-CSDN博客

  9. 收藏!机器学习算法分类图谱及其优缺点综合分析

    来源:必达智库 近日,Coggle对各类机器学习算法进行了归纳整理,形成了一个较为完整的机器学习算法分类图谱,并对每一类算法的优缺点进行了分析.具体分类如下: 正则化算法(Regularization ...

最新文章

  1. 增强现实系统的三大关键技术是什么?
  2. 【Python】蒙特卡罗方法计算圆周率及给定随机数种子
  3. Linux共享库路径配置
  4. left join和left outer join的区别
  5. Spring详解(八)------事务管理
  6. 蓝桥杯第七届决赛之---阶乘位数
  7. vi设计手册的编辑形式
  8. mysql中+desc用法,数据库desc的用法有哪些用法
  9. 个人笔记:Kotlin开发制作首页引导页
  10. linux crontab修改不生效,crontab 内容修改不生效
  11. qq2007服务器中断,自动重启pubwin2007服务器脚本
  12. 如何使用启动盘PE桌面工具安装原版win7系统?
  13. 使用EasyExcel进行百万数据文件导出思路
  14. 基于DOA联合TDOA时间积累下二维平面GDOP
  15. 如何实现同一网络的计算机共享文件,同一个局域网内如何共享文件
  16. 牛客网项目 1.5Mybatis入门
  17. 没钱不能创业,教写商业计划书
  18. keil建立stm32工程即标准库函数目录结构
  19. Photoshop安装问题:106 无法写入注册表
  20. C语言 1~100之间3的倍数

热门文章

  1. 魅族16t无法点击计算机传输,总结魅族16T输给IQOO的原因,三个缺点太明显
  2. import(导入)和export(导出)
  3. FPC软板材料及其性能简介
  4. NLP文本预处理去除标点符号
  5. GOF(五)-原型模式【推荐】
  6. python下Opencv读取图片
  7. Linux下快速使用makedown
  8. 【FFTNTT入门】大整数乘法
  9. 魅族mx四核即将使用android,魅族mx四核怎么样ne?魅族mx四核怎么样ne? 爱问知识人...
  10. 关于设计一个群发短信的小程序