
2.1 模型评估指标
不同机器学习任务往往需要使用不同的评估指标,下面分别介绍机器学习中回归模型、分类模型和聚类模型的评估指标。
2.1.1 回归模型的评估指标
回归模型任务目标是使得预测值能尽量拟合实际值,因此常用的性能度量方式主要有绝对误差和均方误差两种。
1.绝对误差(mean_absolute_error)
绝对误差即预测点与真实点之间距离之差的绝对值的平均值,scikit-learn实现如下:

例1 绝对误差计算

输出:

2.均方误差(mean_squared_error)
均方误差即预测点与实际点之间距离之差平方和的均值,scikit-learn实现如下:

例2 均方误差计算

输出:

2.1.2 分类模型的评估指标
分类模型的评估指标较多,不同评估指标的侧重点可能不同,有时不同的评估指标彼此之间甚至有可能相互冲突,比如,精度和召回率就是一对矛盾的量,后面会介绍二者各自的含义及相互之间的关系。
1.准确率(accuracy)
准确率就是用来衡量模型对数据集中样本预测正确的比例,即等于所有预测正确的样本数目与所有参加预测的样本总数目的比:

scikit-learn实现如下:

其中,y_true是验证集的实际类别,y_pred是验证集的预测类别,参数normalize选择输出结果的类型(选择True,输出为准确率;选择False,输出为验证集被正确分类的数目)。
例3 准确率计算

输出:

2.精度(precision)
精度指的是所有预测为正例的样本(TP+FP)中真正为正例的样本(TP)的比率。一般来说,就是你找出的这些信息中真正是我想要的有多少,又叫“查准率”,即

scikit-learn实现如下:

其中,y_true是验证集的实际类别,y_pred是验证集的预测类别;参数average有None、binary、macro、weighted、micro几种选择,默认选择为binary,适用于二分类情况。在多分类问题中,不同的参数表示选用不同的计算方式:
● 当选择None时,会直接返回各个类别的精度列表。
● 当选择macro时,直接计算各个类别的精度值的平均(这在类别不平衡时不是一个好的选择)。
● 当选择weight时,可通过对每个类别的score进行加权求得。
● 当选择micro时,在多标签问题中大类将被忽略。
注意:查准率在购物推荐中比较重要。
例4 精度计算

输出:

表示类别0、类别1、类别2的查准率分别为0.8、0.33333333、0.5。
3.召回率(recall)
召回率指的是所有为正例的样本(TP+FN)中真的正例(TP)的比率,用来评判你有没有把样本中所有的真的正例全部找出来,所以又叫“查全率”。通俗地讲,就是你有没有把所有我感兴趣的都给找出来,计算公式为

scikit-learn实现如下:

参数与precision_score中一样。
注意:查全率在犯罪检索等行为中可能比较重要。
例5 召回率计算

输出:

4.F1值
在搜索引擎等任务中,用户关注的是“检索出的信息有多少是用户感兴趣的”“用户感兴趣的信息有多少被检索出来了”,这时候,查准率和查全率比较适合。
但是一般来说,查准率和查全率是一对相矛盾的量,用 P-R 曲线来展示,如图2-1所示。

图2-1 P-R曲线
图2-1中的横轴是“查全率”,纵轴是“查准率”,可以看到曲线的变化趋势:当recall值变大时,precision值会逐渐变小。
图2-1中的直线和各个机器学习曲线的交点表示recall=precision,这个交点就是recall和precision的一个“平衡点”,它是另外一种度量方式,即定义F1值:

scikit-learn实现如下:

参数与precision_score中一样。
注意:如果一个机器学习的曲线被另一个机器学习的曲线完全包住,则可断言后者优于前者,如图2-1所示,曲线B代表的模型就优于曲线A。
例6 F1值计算

输出:

以上三者也可以作为一个整体用一个函数 classification_report 进行输出, scikit-learn实现如下:

上面结果输出是一个矩阵的形式,矩阵的行是各个类别,列分别是precision(查准率)、recall(查全率)、f1-score(F1值)、support(预测的各类别下的样本数目);y_true是验证集的实际类别,y_pred是验证集的预测类别,target_names是一个字符列表形式,可以用来指定输出类别的名字。
例7 一次性计算查全率、查准率和F1值

输出:

5.ROC曲线
很多学习器是为了测试样本产生一个实值或概率,然后将这个预测值与一个分类阈值进行比较,大于阈值就取1,小于阈值就取0。在不同应用中,我们可以根据任务需要选取不同的阈值点;ROC曲线就是从这个角度来研究学习器的泛化性能的。
我们根据学习器预测结果(概率)对样例进行排序,按此顺序逐个把样本作为正例进行预测,每次计算出两个重要的值(纵轴:真正率TP;横轴:假正率FP),分别以它们为横轴和纵轴作图就可得到ROC曲线。具体如下:
(1)假如已经得到了所有样本的概率输出prob值,我们就可以根据每个测试样本属于正样本的概率值从大到小排序。
(2)接下来,我们从高到低,依次将prob值作为阈值(threshold),当测试样本属于正样本的概率大于或等于这个 threshold 时,我们认为它为正样本,否则为负样本。
(3)每次选取一个不同的threshold,我们就可以得到一组FP和TP,即ROC曲线上的一点。这样我们可以得到很多组FP和TP的值,将它们画在ROC曲线上的结果如图2-2所示。

图2-2 ROC曲线
scikit-learn实现如下:

其中,参数y_true是验证集样本的实际类别,y_pred_prob是验证集样本的预测概率值;pos_label是指正例的类别。
注意:和 P-R 曲线图相似,如果一条曲线完全包裹另一条曲线,则外面曲线的性能更优。
6.AUC
当两条ROC曲线发生交叉时,谁的性能更优就难以判定了,这时就要根据两条ROC曲线下面的面积大小来比较判断,即面积大者相对更优。这个ROC曲线下面的面积就是AUC。
AUC的scikit-learn实现如下:

其中,y_true 是验证集样本的实际类别,y_pred_prob 是验证集样本的预测概率值,返回结果为ROC曲线下的面积,即AUC。
注意:此实现仅限于真实值为二分类的情况。
例8 AUC计算

输出:

7.混淆矩阵
混淆矩阵(Confusion Matrix)是一种评估分类模型好坏的形象化展示工具。例如,有150个样本数据,把这些数据平均分成3类,每类50个。分类结束后得到的混淆矩阵如图2-3所示。

图2-3 混淆矩阵
每行之和为50,表示50个样本,第一行说明类1的50个样本有43个分类正确, 5个错分为类2,2个错分为类3。
由此可以看出,如果混淆矩阵中非对角线元素全为0,则表示是一个完美的分类器。
混淆矩阵的scikit-learn实现如下:

其中,y_true是验证集的实际类别;y_pred是验证集的预测类别;labels参数是一个字符类别的形式,可以用来指定各个类别显示的名称,默认为None。
例9 混淆矩阵计算

输出:

2.1.3 聚类模型的评估指标
前面说过,聚类是将样本集划分为若干个不相交的子集,即样本簇,同样需要通过某些性能度量方式来评估其聚类结果的好坏。直观上看,我们是希望同一簇内的样本能尽可能相似,而不同簇的样本之间尽可能不同。用机器学习的语言来讲,就是希望簇内相似度高,而簇间相似度低。
实现这一目标主要有外部指标和内部指标两种方式。
1.外部指标(External Index)
外部指标需提供一个参考模型,然后将聚类结果与该参考模型进行比较得到一个评判值;常用的有Jaccard系数、FM指数、Rand指数和标准化互信息。
假设给定数据集为T={x1,x2,…,xM},其被某个参考划分为,即被划分为J个簇;现采用某种聚类模型后,其实际被划分为C={c1,c2,…,cK},即被划分为K个簇。相应地,令λ∗和λ分别表示C∗和C的簇标记向量。我们将样本两两配对考虑,则定义如下指标。
● SS:同时隶属于λi和的样本对,设对应数目为a。
● SD:隶属于λi但不属于的样本对,设对应数目为b。
● DS:隶属于但不属于λi的样本对,设对应数目为c。
● DD:既不隶属于λi,又不隶属于的样本对,设对应数目为d。
假设现在有5个样本{x1,x2,x3,x4,x5},它们的实际聚类结果和用聚类算法预测的聚类结果分别如下所示:

根据上面的定义,可知λi取值为0或1,取值为0或1或2,可以得到如表2-1所示聚类结果。
表2-1 聚类结果

说明:样本对x1,x2在 labels_pred 中对应的是0,0,属于同一类别;在labels_true中对应的是0,0,也属于同一类别,所以数目a计一分。样本对x1,x3在labels_pred中对应的是0,1,不属于同一类别;在labels_true中对应的是0,0,属于同一类别,相当于样本对x1,x3隶属于但不属于λi,所以数目c计一分。依次类推,可以统计出所有样本对的标签,最后求得a,b,c,d的值。
(1)Jaccard系数(Jaccard Coefficient,JC)

(2)FM指数(Fowlkes and Mallows Index,FMI)

(3)Rand指数(Rand Index,RI)

其中,M是样本总数,表示N个样本可组成的两两配对数。a表示在C与K中都是同类别的元素对数,b表示在C与K中都是不同类别的元素对数;RI的取值范围为[0,1],值越大意味着聚类结果与真实情况越吻合。
另外,在聚类结果随机产生的情况下,为了使结果值尽量接近于零,进一步提出调整的兰德指数(Adjusted Rand Index,ARI),它比兰德指数具有更高的区分度,定义如下:

其中,(RI)E是随机聚类时对应的兰德指数。ARI的取值范围为[−1,1],值越大意味着聚类结果与真实情况越吻合。从广义的角度来讲,ARI 衡量的是两个数据分布的吻合程度。
ARI的scikit-learn实现如下:

(4)标准化互信息(Normalized Mutual Information,NMI)
标准化互信息是信息论里一种有用的信息度量方式,它可以看成是一个随机变量中包含的关于另一个随机变量的信息量,或者说是一个随机变量由于已知另一个随机变量而减少的不肯定性,用I(X,Y)表示,表达式如下:

实际上,互信息就是后面决策树中要讲到的信息增益(Information Gain),其值等于随机变量Y的熵H(Y)与Y的条件熵H(Y|X)之差,即
I(X,Y)=H(Y)−H(Y|X)
NMI的scikit-learn实现如下:

2.内部指标(Internal Index)
内部指标不需要有外部参考模型,可直接通过考察聚类结果得到,常用的有DB指数和 Dunn 指数。假设给定数据集为T={x1,x2,…,xM},被某种聚类模型划分为C={c1,c2,…,cK} 个簇,则定义
● avg(ck):簇ck中每对样本之间的平均距离。
● diam(ck):簇ck中距离最远的两个点之间的距离。
● dmin(ck,cl):簇ck和簇cl之间最近点的距离。
● dcen(ck,cl):簇ck和簇cl中心点之间的距离。
(1)DB指数(Davies-Bouldin Index,DBI)

即给定两个不同簇,先计算这两个簇样本之间的平均距离之和与这两个簇中心点之间的距离的比值,然后再取所有簇的该值的平均值,就是 DBI。显然,每个簇样本之间的平均距离越小(表示相同簇内的样本距离越近),簇间中心点距离越大(表示不同簇样本相隔越远),DBI值就越小,所以DBI值可以较好地衡量簇间样本距离和簇内样本距离的关系,其值越小越好。
(2)Dunn指数(Dunn Index,DI)

即用任意两个簇之间最近距离的最小值除以任意一个簇内距离最远的两个点的距离的最大值就是 DI。显然,任意两个不同簇之间的最近距离越大(表示不同簇样本相隔越远),任意一个簇内距离最远的两个点之间的距离越小(表示相同簇内的样本距离越近),DI值就越大;所以DI值也可以较好地衡量簇间样本距离和簇内样本距离的关系,其值越大越好。
3.轮廓系数
轮廓系数适用于训练样本类别信息未知的情况。假设某个样本点与它同类别的群内点的平均距离为a,与它距离最近的非同类别的群外点的平均距离为b,则轮廓系数定义为

对于一个样本集合,它的轮廓系数是所有样本轮廓系数的平均值。
轮廓系数的取值范围是[−1,1],同类别样本点的距离越近,且不同类别的样本点距离越远,则得到的轮廓系数的值就越大。
轮廓系数的scikit-learn实现如下:

其中,X是样本特征矩阵;labels是每个样本的预测类别标签;metric是计算距离选用的度量方式,默认是 euclidean,表示欧氏距离;sample_size 是设定计算轮廓系数时采用的样本数,相当于对数据做一个采样,默认是None,表示不进行采样。
2.1.4 常用距离公式
上面讲轮廓系数时提到了欧氏距离,实际上,除欧氏距离外,在机器学习中还可能用到各种其他类型的距离度量方式,所以这里补充讲解一下常用的几种距离公式的Python实现。
设有两个n维向量A=(x11,x12,…,x1n)和B=(x21,x22,…,x2n)。
1.曼哈顿距离
曼哈顿距离也称为城市街区距离,数学表达式为

Python实现:

2.欧氏距离
欧氏距离就是我们熟悉的L2范数,数学表达式为

Python实现:

3.闵可夫斯基距离
闵可夫斯基距离可以看作欧氏距离的一种推广,数学表达式为

可以看到,当p值取1时,闵可夫斯基距离就是曼哈顿距离;当p值取2时,闵可夫斯基距离就是欧氏距离。
4.切比雪夫距离
切比雪夫距离就是无穷级数,即
d12=max(|x1i−x2i|)
Python实现:

5.夹角余弦
夹角余弦的取值范围为[-1,1],可以用来衡量两个向量方向的差异。夹角余弦越大,表示两个向量的夹角越小。当两个向量的方向重合时,夹角余弦取最大值1;当两个向量的方向完全相反时,夹角余弦取最小值-1。机器学习中用这一概念来衡量样本向量之间的差异,其数学表达式为

Python实现:

6.汉明距离
汉明距离定义的是两个字符串中不相同位数的数目。例如,字符串‘1111’与‘1001’之间的汉明距离为2。
7.杰卡德相似系数
两个集合A和B的交集元素在A和B的并集中所占的比例称为两个集合的杰卡德相似系数,用符号J(A,B)表示,数学表达式为

杰卡德相似系数是衡量两个集合相似度的一种指标,一般可以将其用在衡量样本的相似度上,在聚类问题中会用到。
8.杰卡德距离
与杰卡德相似系数相反的概念是杰卡德距离,其数学表达式为
