“所有模型都是坏的,但有些模型是有用的”。建立模型之后,接下来就要去评估模型,以确定此模型是否“有用”。sklearn库的metrics模块提供各种评估方法,包括分类评估、回归评估、聚类评估和交叉验证等,本节主要介绍分类模型评估方法。
评估分类是判断预测值时否很好的与实际标记值相匹配。正确的鉴别出正样本(True Positives)或者负样本(True Negatives)都是True。同理,错误的判断正样本(False Positive,即一类错误)或者负样本(False Negative,即二类错误)。
注意:True和False是对于评价预测结果而言,也就是评价预测结果是正确的(True)还是错误的(False)。而Positive和Negative则是样本分类的标记。
metrics模块分类度量有6种方法,如表1所示:
指标 | 描述 | metrics方法 |
---|---|---|
Accuracy | 准确度 | from sklearn.metrics import accuracy_score |
Precision | 查准率 | from sklearn.metrics import precision_score |
Recall | 查全率 | from sklearn.metrics import recall_score |
F1 | F1值 | from sklearn.metrics import f1_score |
Classification Report | 分类报告 | from sklearn.metrics import classification_report |
Confusion Matrix | 混淆矩阵 | from sklearn.metrics import confusion_matrix |
ROC | ROC曲线 | from sklearn.metrics import roc_curve |
AUC | ROC曲线下的面积 | from sklearn.metrics import auc |
7.7.1 准确度
准确度是预测正确的数(包括正样本和负样本)占所有数的比例。在对模型进行评估前,要按照前面的章节所述步骤,对数据进行收集或创建、预处理、建模和预测等操作,示例代码:
# 创建数据集,其中矩阵X表示特征值,向量y表示所属类目标记值
import numpy as np
X=np.random.random((10,5))
y=np.array(['M','M','F','F','M','F','M','M','F','F'])
X[X<0.7]=0
# 对矩阵X特征值进行二值化处理
from sklearn.preprocessing import Binarizer
binarizer = Binarizer(threshold=0.0).fit(X)
binary_X=binarizer.transform(X)
# 对y标记值进行类条件编码
from sklearn.preprocessing import LabelEncoder
enc=LabelEncoder()
enc_y=enc.fit_transform(y)
# 数据切分为训练集和测试集
from sklearn.cross_validation import train_test_split
X_train,X_test,y_train,y_test=train_test_split(binary_X,enc_y,random_state=0)
# 利用knn模型对数据进行拟合
from sklearn import neighbors
knn = neighbors.KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train,y_train)
# 对测试集数据预测
y_pred = knn.predict(X_test)
print(y_pred)
print(y_test)
运行结果
[0 1 1] #预测标记值
[0 0 1] #测试标记值
经历过以上操作后,利用accuracy_score函数对预测数据进行模型评估,其中第一个参数是测试标记,第二个参数是预测标记值。示例代码:
from sklearn.metrics import accuracy_score
accuracy_score(y_test, y_pred)
运行结果
0.66666666666666663
由结果可知,knn模型预测的准确率约为66.7%,其中测试标记值y_test的结果为array([0, 0, 1], dtype=int64),而y_pred结果为array([0, 1, 1], dtype=int64),由于数据量比较小,因此准确率为2/3即约等于66.7%。
7.7.2 查准率(Precision)和查全率(Recall)
查准率和查全率应用在信息处理领域的多个子领域。为加深理解,先引入下图1,然后再具体分析。其中,用P代表Precision,R代表Recall。
图1 Precision和Recall查准率和查全率用来衡量搜索引擎的性能,查全率=(检索出的相关信息量/系统中的相关信息总量)x100%,查准率=(检索出的相关信息量/检索出的信息总量)x100%。一般来说,Precision 就是检索出来的条目中(比如:文档、网页等)有多少是准确的,Recall就是所有准确的条目有多少被检索出来了。为什么要引入这两个概念?
假设有一个大小为1000的带布尔标签数据集,里面的“真”样本只有100不到,剩下都是假样本。假设训练一个模型,不管输入什么数据,它只给出“假”的预测,那么正确率依旧是90%以上,很明显,这个时候准确率accuracy就失去它的作用。因此,查全率和查准率一般用在倾斜数据集的时候。
查全率是衡量检索系统和检索者检出相关信息的能力,查准率是衡量检索系统和检索者拒绝非相关信息的能力。
实验证明,在查全率和查准率之间存在着相反的相互依赖关系--如果提高输出的查全率,就会降低其查准率,反之亦然。
sklearn的metrics模块分别提供了precision_score和recall_score函数用来评估分类模型的查全率和查准率,示例代码:
from sklearn.metrics import precision_score
print(precision_score(y_test, y_pred))
from sklearn.metrics import recall_score
print(recall_score(y_test, y_pred))
运行结果:
0.5 # 查准率
1.0 # 查全率
由结果可知,查准率为0.5,由于测试集中正确的正样本只有1个,预测的正样本有2个,所以依据查准率公式得1/2即0.5。而对于查全率,唯一的1个正确的正样本被预测样本涵盖,因此依据查全率公式得1/1即1.0。
7.7.3 F1值(F1-Measure)
如上所述,P和R指标有的时候是矛盾的,F-Measure综合这二者指标的评估指标,用于综合反映整体的指标。F-Measure是Precision和Recall加权调和平均,公式如图2所示:
图2 F-Measure当参数a=1时,就是最常见的F1了,如图3所示:
图3 F1-Measure很容易理解,F1综合了P和R的结果,当F1较高时则比较说明实验方法比较理想。利用F1评估分类模型示例代码:
from sklearn.metrics import f1_score
f1_score(y_test,y_pred)
运行结果:
0.66666666666666663
7.7.4 分类报告(Classification Report)
metrics模块的classification_report方法,综合提供了查准率(precision)、查全率(recall)和f1值三种评估指标。示例代码:
from sklearn.metrics import classification_report
print(classification_report(y_test,y_pred))
运行结果:
precision recall f1-score support
0 1.00 0.50 0.67 2
1 0.50 1.00 0.67 1
avg / total 0.83 0.67 0.67 3
7.7.5 混淆矩阵(Confusion Matrix)
混淆矩阵是一个N X N矩阵,N为分类的个数。假如我们面对的是一个二分类问题,也就是N=2,我们就得到一个2 X 2矩阵。在学习这个矩阵之前,我们需要知道一些简单的定义。
Accuracy(准确度):预测正确的数占所有数的比例。
Positive Predictive Value(阳性预测值) or Precision(查准率):阳性预测值被预测正确的比例。
Negative Predictive Value(阴性预测值):阴性预测值被预测正确的比例。
Sensity(灵敏度) or Recall(查全率):在阳性值中实际被预测正确所占的比例。
Specificity(特异度):在阴性值中实现被预测正确所占的比例。
所有概念及运算方法如图4所示:
sklearn库的metrics模块提供了confusion_matrix方法,用来计算混淆矩阵值,示例代码:
from sklearn.metrics import confusion_matrix
print(confusion_matrix(y_test, y_pred))
运行结果:
[[1 1] # True Positives = 1, False Negatives = 1
[0 1]] # False Positives = 0, True Negatives = 1
7.7.6 ROC曲线
ROC(receiver operating characteristic curve)曲线指受试者工作特征曲线或者是接收器操作特性曲线, 它是反映敏感性和特异性连续变量的综合指标,是用构图法揭示敏感性和特异性的相互关系,它通过将连续变量设定出多个不同的临界值,从而计算出一系列敏感性和特异性,再以敏感性为纵坐标、(1-特异性)为横坐标绘制成曲线,曲线下面积越大,诊断准确性越高。在ROC曲线上,最靠近坐标图左上方的点为敏感性和特异性均较高的临界值。
考虑一个二分问题,即将实例分成正类(positive)或负类(negative)。对一个二分问题来说,会出现四种情况。如果一个实例是正类并且也被 预测成正类,即为真正类(True positive),如果实例是负类被预测成正类,称之为假正类(False positive)。相应地,如果实例是负类被预测成负类,称之为真负类(True negative),正类被预测成负类则为假负类(false negative)。
TP:正确肯定的数目;
FN:漏报,没有正确找到的匹配的数目;
FP:误报,给出的匹配是不正确的;
TN:正确拒绝的非匹配对数;
列联表如下表所示,1代表正类,0代表负类。
| | | 预测 | ||
| :---------------- |:-------------|:--------|
| | | 1 | 0 | 合计 |
| 实际 | 1 | True Positive(TP)| False Negative(FN)| Actual Positive(TP+FN) |
| | 0 | False Positive(FP) | True Negative(TN) | Actual Negative(FP+TN) |
| 合计 | | Predicted Positive(TP+FP) | Predicted Negative(FN+TN) | TP+FP+FN+TN |
从列联表引入两个新名词。其一是真正类率(true positive rate ,TPR), 计算公式为TPR=TP/ (TP+ FN),刻画的是分类器所识别出的 正实例占所有正实例的比例。另外一个是假正类率(false positive rate, FPR),计算公式为FPR= FP / (FP + TN),计算的是分类器错认为正类的负实例占所有负实例的比例。还有一个真负类率(True Negative Rate,TNR),也称为specificity,计算公式为TNR=TN/ (FP+ TN) = 1-FPR。如图5所示:
图5 TPR和FPR如上图所示,两列True matches和True non-match分别代表应该匹配上和不应该匹配上的,两行Pred matches和Pred non-match分别代表预测匹配上和预测不匹配上的。
FPR = FP/(FP + TN) 负样本中的错判率(假警报率)
TPR = TP/(TP + TN) 判对样本中的正样本率(命中率)
ACC = (TP + TN) / P+N 判对准确率
在一个二分类模型中,对于所得到的连续结果,假设已确定一个阀值,比如说 0.6,大于这个值的实例划归为正类,小于这个值则划到负类中。如果减小阀值,减到0.5,固然能识别出更多的正类,也就是提高了识别出的正例占所有正例 的比类,即TPR,但同时也将更多的负实例当作了正实例,即提高了FPR。为了形象化这一变化,在此引入ROC,ROC曲线可以用于评价一个分类器。
ROC曲线其实就是从混淆矩阵衍生出来的图形,其横坐标为1-Specificity,纵坐标为Sensitivity。1-specificity=FPR(False positive rate),即假正类率。Sensitivity=TPR(True positive rate),即是真正类率。如图6所示:
上图说明,理想情况下,TPR应该接近1,FPR应该接近0。ROC曲线上的每一个点对应于一个threshold,对于一个分类器,每个threshold下会有一个TPR和FPR。比如Threshold最大时,TP=FP=0,对应于原点;Threshold最小时,TN=FN=0,对应于右上角的点(1,1)。在ROC空间,ROC曲线越凸向左上方向效果越好;越靠近对角线,分类器越趋向于随机分类器。
利用metrics计算roc曲线,roc曲线有三个属性:fpr,tpr,和阈值,因此该函数返回这三个变量。示例代码:
import numpy as np
from sklearn.metrics import roc_curve
y = np.array([1,1,2,2])
pred = np.array([0.1, 0.4, 0.35, 0.8])
fpr, tpr, thresholds = roc_curve(y, pred, pos_label=2)
fpr,tpr,thresholds分别值为
array([ 0. , 0.5, 0.5, 1. ])
array([ 0.5, 0.5, 1. , 1. ])
array([ 0.8 , 0.4 , 0.35, 0.1 ])
7.7.7 AUC(ROC曲线下面积)
ROC曲线是根据与那条参照线进行比较来判断模型的好坏,但这只是一种直觉上的定性分析,如果我们需要精确一些,就要用到AUC,也就是ROC曲线下面积。其判定方法是AUC应该大于0.5。如图7所示:
图7 AUC曲线如上图所示,参考线的面积是0.5,ROC曲线与它偏离越大,ROC曲线就越往左上方靠拢,它下面的面积(AUC)也就越大,这里面积是0.869。我们可以根据AUC的值与0.5相比,来评估一个分类模型的预测效果。如果AUC的值达到0.80,那说明分类器分类非常准确;如果AUC值在0.60~0.80之间,那分类器有优化空间,可以通过调节参数得到更好的性能;如果AUC值小于0.60,那说明分类器模型效果比较差。
利用刚才求得的fpr和tpr的结果作为参数,可以求得AUC的值,示例代码:
from sklearn.metrics import auc
auc(fpr, tpr)
运行结果
0.75
网友评论