多分类算法的评估指标

在以往的分类问题求解当中,我们遇到的问题多为二分类问题,我们常用的评估指标有accuracy, precision, recall_score, f1-score, roc_auc_score等。但是在实际生活中,多分类问题也是大量存在的。这一小节,我们就详细的说明一下多分类问题的评估指标。
多分类算法的评估指标_第1张图片

我们先来看一下sklearn库中的二分类的评估指标,以recall_score为例。在recall_score方法中,有一个很重要的参数’average’,它的默认值为’binary’。当在默认参数的情况,该评估方法只能求解二分类问题,如果将该评估方法用于多分类问题,则系统会报错。但’average’同时也向我们提供了其他四个用于解决多分类的问题的参数’micro’,‘macro’,‘weighted’,‘samples’。下面我们以鸢尾花数据集为例来对这四个参数进行逐一说明。
[sklearn.metrics.recall_score]('https://scikit-learn.org/stable/modules/generated/sklearn.metrics.recall_score.html
')

sklearn.metrics.recall_score(y_true, y_pred, labels=None, 
pos_label=1, average='binary', sample_weight=None, zero_division='warn')

我们以recall_score的计算为例,recall_score的计算公式如下:
R e c a l l = T P T P + F N Recall = \frac {TP}{TP + FN} Recall=TP+FNTP
为了计算recall_score,我们必须先计算出TP,FN值。我们采用sklearn中的混淆矩阵来计算TP,FN值。

#导入数据分析的常用工具包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

#导入iris数据集
from sklearn import datasets
iris = datasets.load_iris()

#对iris数据集进行切分
from sklearn.model_selection import train_test_split
X = iris.data
Y = iris.target
X_train,X_test,Y_train,Y_test = train_test_split(X,Y,test_size = 0.3,random_state = 0)

#建立一个基础的逻辑回归模型
from sklearn.linear_model import LogisticRegression
LR = LogisticRegression()
LR.fit(X_train,Y_train)
prediction = LR.predict(X_test)

#计算混淆矩阵
from sklearn.metrics import confusion_matrix
cnf = confusion_matrix(Y_test,prediction,labels = [0,1,2])
print(cnf)
[out]:
array([[16,  0,  0],
       [ 0, 13,  5],
       [ 0,  0, 11]], dtype=int64)

该分类问题的混淆矩阵如下,列为真实类别,行为预测类别:

class 0 1 2
0 16 0 0
1 0 13 5
2 0 0 11

混淆矩阵(confusion matrix)说明:
TP(True positive):把正例正确地预测为了正例,如把类别0预测为0的个数有16个。
FN(False negative):把正例错误地预测为了负列,如把类别1预测为2的个数有5个。
FP(False positive):把负例错误地预测为了正例,假设0为正例,错误地把1,2预测为0就是FP。
TN(True negative):把负例正确地预测为了负例,假设0为正例,1,2为负例,正确地把1,2预测为1,2就是TN。
对于混淆矩阵,可以这样理解。第一个字母T/F,表示预测的正确与否;第二个字母P/N,表示预测的结果为正例或者负例。如TP就表示预测对了,预测的结果是正例,那它的意思就是把正例预测为了正例。

1.Micro

Micro:把所有类汇总在一起计算出最终recall值,其计算公式如下:
R e c a l l = T P 0 + T P 1 + T P 2 T P 0 + F N 0 + T P 1 + F N 1 + T P 2 + F N 2 Recall = \frac{TP_0 + TP_1 + TP_2}{TP_0 + FN_0 + TP_1 + FN_1 + TP_2 + FN_2} Recall=TP0+FN0+TP1+FN1+TP2+FN2TP0+TP1+TP2
在使用Micro参数时,其recall_score = (16+13+11)/(16+13+11+5) = 0.89。
使用sklearn.metrics方法计算:

from sklearn.metrics import recall_score
recall_score(Y_test,prediction,average = 'micro')
[out]:0.8888888888888888

从上述计算结果可以看出,两者的计算结果是一致的,均为0.89。

2.Macro

Macro:分别计算出每一类的recall值,再取算数平均值,其计算公式如下:
R e c a l l = ( T P 0 T P 0 + F N 0 + T P 1 T P 1 + F N 1 + T P 2 T P 2 + F N 2 ) ∗ 1 3 Recall =( \frac{TP_0}{TP_0 + FN_0} + \frac{TP_1}{TP_1 + FN_1} + \frac{TP_2}{TP_2 + FN_2}) * \frac{1}{3} Recall=(TP0+FN0TP0+TP1+FN1TP1+TP2+FN2TP2)31
在使用Macro参数时,其recall_score = [16/(16+0+0) + 13/(0+13+5) + 11/(11+0+0)] * 1/3 = 0.91
使用sklearn.metrics方法计算:

from sklearn.metrics import recall_score
recall_score(Y_test,prediction,average = 'macro')
[out]:0.9074074074074074

从上述计算结果可以看出,macro参数下的recall值为0.91。

3.Weighted

Weighted:分别计算每一类的recall值,再乘以各自的权重,然后求和,其计算公式如下:
R e c a l l = T P 0 T P 0 + F N 0 ∗ W 0 + T P 1 T P 1 + F N 1 ∗ W 1 + T P 2 T P 2 + F N 2 ∗ W 2 Recall =\frac{TP_0}{TP_0 + FN_0} * W_0+ \frac{TP_1}{TP_1 + FN_1} * W_1 + \frac{TP_2}{TP_2 + FN_2} * W_2 Recall=TP0+FN0TP0W0+TP1+FN1TP1W1+TP2+FN2TP2W2
计算各类的权重:

W0,W1,W2 = np.bincount(Y_test) / len(Y_test)
print(W0,W1,W2)
[out]:0.35555555555555557 0.4 0.24444444444444444

在使用weighted参数时,其recall_score = 16/(16+0+0) * 0.356 + 13/(0+13+5) * 0.4 + 11/(11+0+0) * 0.244 = 0.89
使用sklearn.metrics方法计算:

from sklearn.metrics import recall_score
recall_score(Y_test,prediction,average = 'weighted')
[out]:0.8888888888888888

从上述计算结果可以看出,weighted参数下的recall值为0.89。

4.Samples

samples应用于多标签的分类问题,每一个样本拥有一个以上的标签。如一个感染病毒性肺炎的患者,就可以说他既属于病毒性肺炎患者这一类,也可以说他属于肺炎患者类。

小结:
1.对于多分类算法的评估,我们需要将sklearn.metrics.recall_score中的’average’参数修改为’micro’或’macro’或者’weighted’。
2.在这个例子当中,我们以recall来举例,像其他的评估指标precision, roc_auc_score, f1-score都是采用同样的方法。

文章参考:
[1].https://zhuanlan.zhihu.com/p/59862986

你可能感兴趣的:(机器学习)