混淆矩阵就是分别统计分类模型归错类,归对类的观测值个数,然后把结果放在一个表里展示出来。这个表就是混淆矩阵。
在分类任务中,预测结果与正确标记之间存在四种不同的组合,构成混淆矩阵,以下是二分类的混淆矩阵:
假设有一组数据集,一共有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。
精确率:预测结果为正例样本中真实为正例的比例,用于评估预测的准确性。
如图,正正例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%.
但是对于癌症患者来说,宁可误判不能漏判,所以此时就非常强调召回率。
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%
接口:
sklearn.metrics.classification_report(y_true,y_pred,target_names=None)
一下是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
混淆矩阵