机器学习基础-8.分类算法的评价

本文探讨了分类算法评估的各种指标,包括准确率、精准率、召回率等,并介绍了如何使用混淆矩阵来评估二分类和多分类问题。此外,还讨论了ROC曲线和精准率-召回率曲线在评估模型性能中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、分类算法评价指标

1.分类准确度的问题

分类算法如果用分类准确度来衡量好坏将会存在问题。例如一个癌症预测系统,输入体检信息,可以判断是否有癌症,预测准确度可以达到99.9%,看起来预测系统还可以,但是如果癌症的产生概率只有0.1%,那么系统只要预测所有人都是健康的就可以达到99.9%的准确率,因此虽然准确率很高,但是预测系统实际上没有发挥什么作用。更加极端的如果癌症概率只有0.01%,那么预测所有人都是健康的概率是99.99%,比预测系统的结果还要好。因此可以得到结论:在存在极度偏斜的数据中,应用分类准确度来评价分类算法的好坏是远远不够的。

2.混淆矩阵

对于二分类问题。可以得到如下的混淆矩阵。

通过混淆矩阵可以得到精准率和召回率,用这两个指标评价分类算法将会有更好的效果。

3.精准率和召回率

之所以使用1的分类来计算精准率是因为,在实际生活中,1代表着受关注的对象,例如:癌症预测系统中,1就代表着患癌症,40%意味着,系统做出100次病人患有癌症的预测结论,其中有40%结论是准确的。

召回率意味着如果有10个癌症患者,将会有8个被预测到。

现在假设有10000个人,预测所有的人都是健康的,假设有10个患病,则有如下的混淆矩阵。

对于准确率:9990/10000=99.9%。对于精准率:0/0没有意义。对于召回率:0/10=0。可以看出模型对于预测疾病其实并不好。

4.sklearn代码实现

由于计算逻辑比较简单,所以直接给出sklearn中封装好的实现。

import numpy as np
from sklearn import datasets

digits = datasets.load_digits()
x = digits.data
y = digits.target.copy()

y[digits.target==9]=1 #这里将数据弄成明显的倾斜数据
y[digits.target!=9]=0

from 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) #0.9755555555555555
y_log_predict = log_reg.predict(x_test)

from sklearn.metrics import confusion_matrix
confusion_matrix(y_test,y_log_predict)
from sklearn.metrics import precision_score #sklearn中的精准率
precision_score(y_test,y_log_predict)
from sklearn.metrics import recall_score    #sklearn中的召回率
recall_score(y_test,y_log_predict)

5.对精准率和召回率的分析

对于一个模型得到了精准率和召回率,那么应该如何通过这两个指标对模型进行评价,又或者是一个模型经过调参后,得到不同的精准率和召回率,应该选取哪个参数对应的精准率和召回率才好。这个需要根据不同的场景进行选择。

例如:对于股票预测,更多的应该是关注精准率,假设关注股票上升的情况,高精准率意味着TP值高(正确地预测到股票会升),这个时候可以帮助人们调整投资,增加收入,如果这一指标低,就以为FP值高(错误地认为股票会升),也就是说股票其实是降的,而预测成升了,这将会使用户亏钱。而召回率低只是意味着在股票上升的情况中,对几个股票上升的情况没有被预测到,这对于投资者来说也是可以接受的,毕竟没有亏钱,因此低召回率对用户影响不是很大。

例如:对于疾病预测领域,更多的应该关注召回率,因为高召回率意味着能够更多地将得病的病人预测出来,这个对于患病者非常重要。而精准率低意味着错误地预测病人患病,而这个时候只要被预测患病的人再去检查一下即可,实际上是可以接受的,因此低精准率对用户影响不大。

而某些情况可能需要同时考虑到两个指标,以达到一个均衡。这个时候就需要F1 score。这个称为精准率和召回率的调和平均值。可以发现只有两个值都比较高的时候,F1才会比较高。

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

二、精准率和召回率

1.精准率和召回率的矛盾

实际中,要想同时获得高的精准率和召回率是很难的,有可能就不能实现。

如图所示,五角星为1,圆形为0。划的竖线代表决策边界。可以看到,当精准率提高时,召回率就下降,当召回率提高时,精准率就下降,二者是个矛盾。

那么如何选择决策边界,使得模型能够达到目标。

2.绘制精准率和召回率曲线

import numpy as np
from sklearn import datasets
import matplotlib.pyplot as plt

digits = datasets.load_digits()
x = digits.data
y = digits.target.copy()

y[digits.target==9]=1 #这里将数据弄成明显的倾斜数据
y[digits.target!=9]=0

from 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
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
log_reg = LogisticRegression()
log_reg.fit(x_train,y_train)
decision_score = log_reg.decision_function(x_test)

precisions = []
recalls = []

thresholds = np.arange(np.min(decision_score),np.max(decision_score),0.1)
for threshold in thresholds:
    y_predict = np.array(decision_score >= threshold,dtype='int')
    precisions.append(precision_score(y_test,y_predict))
    recalls.append(recall_score(y_test,y_predict))
plt.plot(thresholds,precisions,label="precision")
plt.plot(thresholds,recalls,label="recall")
plt.legend()
plt.show()

绘制precision和recall曲线。

plt.plot(precisions,recalls)
plt.show() #快速下降的点,可能就是比较平衡的点

 

3.sklearn中的precision和recall曲线绘制

 

from sklearn.metrics import precision_recall_curve
precisions,recalls,thresholds = precision_recall_curve(y_test,decision_score)
plt.plot(thresholds,precisions[:-1],label="precision")#这里之所以将最后一列去掉,是因为thresholds维度比precision和recall少1
plt.plot(thresholds,recalls[:-1],label="recall")
plt.legend()
plt.show()

三、ROC

ROC:receive operation characteristic curve,描述的是TPR和FPR之间的关系。

TPR即召回率,FPR为FP/(TN+FP)。下面看看他们之间的关系。

可以看到FPR和TPR呈现相一致的关系,这个也容易理解。当召回率提高时,说明会尽量将1样本都包含进去(竖线左移),而这个时候就会增加错分的0样本(更多的0被包含进去),因此TN减小,FP增大,必然导致FPR的增大。

from sklearn.metrics import roc_curve
fprs,tprs,thresholds=roc_curve(y_test,decision_score)
plt.plot(fprs,tprs)
plt.show()

容易理解,当FPR比较低时,TPR就比较高,这样就会有比较好的模型,对应的曲线底下的面积也将会比较大,因此ROC底下的面积可以作为衡量分类算法好坏的一个指标。

from sklearn.metrics import roc_auc_score #计算面积大小
roc_auc_score(y_test,decision_score) 

这个将会得到比较高的值,说明auc对于有偏数据并不是很敏感,auc一般用于比较两个模型之间的好坏。

四、多分类评价

1.多分类问题中的混淆矩阵

import numpy as np
from sklearn import datasets
import matplotlib.pyplot as plt

digits = datasets.load_digits()
x = digits.data
y = digits.target.copy()

from 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
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score

log_reg = LogisticRegression()
log_reg.fit(x_train,y_train)
y_predict = log_reg.predict(x_test)

precision_score(y_test,y_predict,average='micro') #为了求出多分类的精准度和召回率,必须传入参数average='micro'
from sklearn.metrics import confusion_matrix  #查看多分类的混淆矩阵
confusion_matrix(y_test,y_predict)

其中对角线的代表该分类预测正确的数量,其他位置的值代表预测错误所对应的值。为了直观,现在绘制出图像。

from sklearn.metrics import confusion_matrix
cfm = confusion_matrix(y_test,y_predict)
row_sums = np.sum(cfm,axis=1)#将每行相加,得到每行的样本总数
err_matrix = cfm/row_sums
np.fill_diagonal(err_matrix,0)#将对角线的元素全部置为0
plt.matshow(err_matrix,cmap=plt.cm.gray) #越亮代表值越大,也就是错分的越多
plt.show()


这里可以看到1和8之间混淆地比较多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值