您的当前位置:首页正文

朴素贝叶斯 混淆矩阵,2分类下的混淆矩阵,精确率与召回率,F1-score

2024-11-08 来源:个人技术集锦


1.混淆矩阵

混淆矩阵就是分别统计分类模型归错类,归对类的观测值个数,然后把结果放在一个表里展示出来。这个表就是混淆矩阵。

在分类任务中,预测结果与正确标记之间存在四种不同的组合,构成混淆矩阵,以下是二分类的混淆矩阵:

假设有一组数据集,一共有66个样本,三个目标值,猫、狗、猪。

混淆矩阵为:

关于这个混淆矩阵,从真实值为猫这一列开始看,代表有18个目标值为猫的样本,预测出10只为猫,3只为狗,5只为猪。所以正确率为10/18=55.5%。

狗这一列有22个样本数,预测结果为1只为猫,15只为狗,6只为猪,正确率68.1%。

猪这一列有26个样本,预测结果为2只猫,4只狗,20只猪,正确率为76.9%。

 

那么对于以上混淆矩阵,可转化为2分类的混淆矩阵,如下:

对于是猫的18个样本(猫),预测不正确的数量为8,正确的数量为10。

对于不是猫的48个样本(非猫),预测不正确的数量为3,正确的数量为45。

对于预测结果,又把是猫称为正例,不是猫称为假例。

对于预测值的正例,正确的称为真正例TP,不正确的称为伪正例FP。

预测值为假例,不正确的称为伪反例FN,正确的称为真反例TN。

 

 

 

 

2.精确率(Precision)与召回率(Recall)

精确率预测结果为正例样本中真实为正例的比例,用于评估预测的准确性。 

如图,正正例TP为10。准确性=10/18=55.5%

召回率:真实为正例的样本中预测结果为正例的比例。在真正样本数量下,抽取作为预测样本的数量,评估是否查的全。

以猫为例,在总共18只真猫中,我们的模型认为里面只有10只是猫,剩下的3只是狗,5只都是猪。这5只八成是橘猫,能理解。所以,Recall(猫)= 10/18 = 55.6%

精确率与召回率的区别

召回率是先与精确率的,假设真实样本数为100,我们预测了95个,遗漏了5了,那么召回率是95%。

那么在预测了的95个里,预测正确的90个,预测错误的5个,那么精确率为94.7%。

为什么真实样本数为100而实际被预测的只有95个?

假设对于一种分类,如猫,常规来说,猫的特征大致相同,但如果出现某些变异体,其特征与普通的猫差的非常远(如无毛猫),这时候就不太容易作为被预测对象。

什么时候强调召回率

对于预测癌症患者,真实样本数(被检测的人)有100人,而预测样本数为95,那么就有5人未被预测,此时的召回率是95%.

但是对于癌症患者来说,宁可误判不能漏判,所以此时就非常强调召回率。

 

 

3. F1-score

F1-score:反应模型的稳健性,F1-Score指标综合了Precision与Recall的产出的结果。F1-Score的取值范围从0到1的,1代表模型的输出最好,0代表模型的输出结果最差。

公式为:

对于猫的案例,F1-Score为:

F1-Score=(2 * 0.769 *  0.556)/( 0.769 +  0.556) = 64.54%

 

4.sklearn API接口

接口:

sklearn.metrics.classification_report(y_true,y_pred,target_names=None)
  • y_true:真实目标值
  • y_pred:估计器预测的目标值
  • target_names:目标类别名称
  • return:每个类别精确率与召回率

一下是sklearn库提供的20newsgroups数据集,有若干篇新闻文章,我们利用朴素贝叶斯算法进行预测。

from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.datasets import fetch_20newsgroups
from sklearn.metrics import classification_report

def bayes():
    news = fetch_20newsgroups(subset="all")

    #训练集划分
    x_train,x_test,y_train,y_test=train_test_split(news.data,news.target,test_size=0.25)

    #文本特征抽取
    tf = TfidfVectorizer()
    #估计器:从训练集中抽取文本特征
    tf.fit(x_train)
    #转换器:文本特征值化
    x_train = tf.transform(x_train)
    x_test = tf.transform(x_test)

    #调用朴素贝叶斯算法进行预估,P(C|F1,F2..FN)=P(F1,F2..FN|C)*P(C)
    #计算单个样本的特征值在每个分类下的概率
    #平滑系数为1(排除特征值为0的干扰)
    mlt=MultinomialNB(alpha=1.0)
    mlt.fit(x_train,y_train)

    predict=mlt.predict(x_test)
    #估算出的目标值与实际目标值对比,满足即预测正确,统计总的正确率
    score=mlt.score(x_test,y_test)

    print("预测的文章类别",predict)
    print("精确性:",score)
    print("每个类别的精确率与召回率",classification_report(y_test,predict,target_names=news.target_names))

if __name__ =="__main__":
    bayes()

使用 classification_report(y_test,predict,target_names=news.target_names)返回精确率与召回率,f1-score

参考文档

混淆矩阵 

显示全文