1.分类准确度的问题

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

2.混淆矩阵

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

分类算法的评价

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

3.精准率和召回率

分类算法的评价

精准率:分类正确的正样本个数占分类器判定为正样本的样本个数的比例(预测分类为1,相应的预测对的概率)。

    对应于检索中的查准率检索出相关文档数/检索出的文档总数

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

分类算法的评价

召回率:分类正确的正样本个数占真正的正样本个数的比例(真实分类为1,相应的预测对的概率)。

    对应于检索中的查全率检索出相关文档数/文档库中相关文档总数

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

 

区别精确率和召回率主要记住他们是分母不同就好了,召回率是对应测试集中的正类数据而言,而准确率是对应预测结果为正类的数据而言。

另一种图解:

分类算法的评价

 

 

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

分类算法的评价

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

4.代码实现

4.1 自己编写代码动手实现以下精准率与召回率:

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

import numpy as np
from sklearn import datasets

digits = datasets.load_digits()
X = digits.data
y = digits.target.copy() #如果直接引用那么y变了,target也会变
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)

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.0

def 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
View Code

相关文章:

  • 2021-11-17
  • 2021-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-08-28
猜你喜欢
  • 2021-05-24
  • 2021-08-18
  • 2022-02-08
  • 2021-06-30
  • 2022-02-08
  • 2021-04-10
  • 2021-11-23
相关资源
相似解决方案