三大最常见机器学习任务

  • 回归方法 回归方法是一种对数值型连续随机变量进行预测和建模的监督学习算法。使用案例一般包括房价预测、股票走势或测试成绩等连续变化的案例。 回归任务的特点是标注的数据集具有数值型的目标变量。也就是说,每一个观察样本都有一个数值型的标注真值以监督算法。

回归技术预测的数据对象是连续值。 例如,温度变化或功率需求波动。 典型应用包括电力负荷预测和算法交易等。回归任务的常用算法有:线性回归、非线性回归、广义线性回归、支持向量机回归、高斯过程回归、回归树等。

  • 分类方法 分类方法是一种对离散型随机变量建模或预测的监督学习算法。使用案例包括邮件过滤、金融欺诈和预测雇员异动等输出为类别的任务。

许多回归算法都有与其相对应的分类算法,分类算法通常适用于预测一个类别(或类别的概率)而不是连续的数值。

分类技术预测的数据对象是离散值。例如,电子邮件是否为垃圾邮件,肿瘤是癌性还是良性等等。 分类模型将输入数据分类。 典型应用包括医学成像,信用评分等。分类任务的常用算法有:朴素贝叶斯、支持向量机、分类树、逻辑回归、集成方法等。

  • 聚类方法 聚类是一种无监督学习任务,该算法基于数据的内部结构寻找观察样本的自然族群(即集群)。使用案例包括细分客户、新闻聚类、文章推荐等。

因为聚类是一种无监督学习(即数据没有标注),并且通常使用数据可视化评价结果。如果存在「正确的回答」(即在训练集中存在预标注的集群),那么分类算法可能更加合适。

聚类算法用于在数据中寻找隐藏的模式或分组。聚类算法构成分组或类,类中的数据具有更高的相似度。聚类建模的相似度衡量可以通过欧几里得距离、概率距离或其他指标进行定义,聚类任务的常用算法有:k-means、层次聚类、高斯混合模型等。

学习方式

  • 监督学习
    在监督学习中,输入数据被称为“训练数据”,每组训练数据有一个明确的类标。在建立预测模型的时候,监督学习建立一个学习过程,将预测结果与“训练数据”的实际结果进行比较,不断的调整预测模型,直到模型的预测结果达到一个预期的准确率。
  • 非监督学习 在非监督学习中,数据并未被特别标识,学习模型是为了推断出数据的一些内在结构。 常见的应用场景包括关联规则的学习以及聚类等。
  • 半监督学习 在此学习方式下,输入数据部分被标识,部分没有被标识,这种学习模型可以用来进行预测,但是模型首先需要学习数据的内在结构以便合理的组织数据来进行预测。应用场景包括分类和回归,算法包括一些对常用监督式学习算法的延伸,这些算法首先试图对未标识数据进行建模,在此基础上再对标识的数据进行预测。
  • 强化学习 在强化学习(Reinforcement Learning)中,输入数据作为对模型的反馈,不像监督模型那样,输入数据仅仅是作为一个检查模型对错的方式。在强化学习中,输入数据直接反馈到模型,模型必须对此立刻作出调整。常见的应用场景包括动态系统以及机器人控制等。

在企业数据应用的场景下, 人们最常用的可能就是监督式学习和非监督式学习的模型。 在图像识别等领域,由于存在大量的非标识的数据和少量的可标识数据, 目前半监督式学习是一个很热的话题。 而强化学习更多的应用在机器人控制及其他需要进行系统控制的领域。

解决问题的步骤

1 定义问题

如果在解决问题的一开始就已经犯了方向性的错误,结果只能是南辕北辙。弄清楚问题的本质,结合问题的特点选择合适的算法才能够得到比较好的结果。

2 数据预处理

所有的机器学习算法都是建立在数据的基础之上的,优质的数据对机器学习有事半功倍的效果。

  • 收集数据,通过各种途径得到尽量完备和有用的数据。

  • 数据清洗,对收集到的数据进行清洗和软件包括数据格式的转化(希望转换成算法所能处理的形式),数据的清洗(处理噪声数据,缺失值的处理),以及数据的采样(有可能我们并不需要这么多的数据)。

  • 等价转换,对清洗过的数据做进一步的转换,例如统一数据的度量(这在距离计算时非常重要)、

  • 属性分解与合并,对某些属性进行拆分或合并 ,以使属性能更好地表达特性。一个属性能够分解为多个子属性,只有某一些子属性对于输出有着显著的影响。那我们就可以只存储这些子属性,而不用去存储原来的属性。同样的,将一些子属性合并成一个新属性后,这个属性对于输出的影响会更加显著。那我们就会选择将这些属性进行合并。

3 数据预分析

在拿到预处理完的数据之后,将其输入到算法之前,我们有必要对数据有一些了解,这样对模型中的参数选择能有一些帮助。这里主要包含两个方法:Summarize Data 和 Visualize Data。

  • Summarize Data主要是分析数据中的一些内在属性。主要包括两个方面:Data Structure 和 Data Distribution。Data Structure指的是数据每一维属性的类型(是连续的还是离散的)。在针对一些具体问题时,可能需要将离散的属性连续化。
  • Data Distribution指的自然是数据的分布。这里主要分析的是每一维数据的分布。如果是有标签的数据,可以弄清楚类别的分布,这样可以知道模型分类时准确率的下限。还可以做的更多的一点是,获取属性间的关联性。如果有关联的话,关联度有多大。这样有助于去除一些冗余属性(数据的降维),以及知道哪些属性对结果的影响比较大(权值的选择)。

  • Visualize Data是对数据进行可视化操作。一般通过柱状图和散点图等观察数据的分布、特征之间的关系等。

4 算法抽查

对于一个具体的问题,我们也许有很多种算法可以对其进行求解,但是并不是所有的算法都能有效。抽查(spot-checking)就是对多个算法进行快速验证,以决定对哪一个算法进行进一步的训练。

在进行算法的抽查时,并不需要使用使用数据集中的所有数据进行训练,只需要使用较小的一部分样本进行实验,选择在样本上表现较好的算法之后,再使用所有数据进行进一步的训练。可以使用交叉验证的方法来进行该过程。

在进行算法抽查时,处于候选集中的算法的种类越多样越好,这样才能测试出哪种类型的算法更能学习到数据中的结构。在选择完算法之后,并不一定直接使用该算法进行进一步的学习,可能会使用基于该算法的改进版本。

5 结果改进

算法训练完成之后,如果算法的结果不如意,该怎么办?如果算法的结果还比较令人满意,有没有方法可以将结果再提升一点?这一部分主要就是解决这两个问题。通常有以下三个方法可以尝试:

Algorithm tuning
Ensembles
Extreme Feature Engineering

6 结果展示

当算法能够较好地解决一个问题的时候,需要将成果以合适的形式展示给大家。写一篇论文(或者什么类似的东西)、将其与实际的产品相结合等等。

训练集、验证集与测试集划分

最佳的数据划分是将数据分为三部分,分别为训练集(trainning set),验证集(validation set)和测试集(test set)。

Training Set : a subset of the dataset used to build predictive models.

Validation Set : a subset of the dataset used to assess the performance of model built in the training phase. It provides a test platform for fine tuning model’s parameters and selecting the best-performing model. Not all modeling algorithms need a validation set.

Test Set : a subset of the dataset to assess the likely future performance of a model. If a model fit to the training set much better than it fits the test set, overfitting is probably the cause.

训练集是用作训练参数的,也就是算法用来生成模型各参数。

验证集是在每个 epoch 完成后,算法用来测试一下当前模型的准确率。因为验证集跟训练集没有交集,因此这个准确率是可靠的。

我们使用一个算法时,通过训练集和验证集,不断优化参数,得到最佳模型。

另外,神经网络等算法还有超参数的概念,比如网络层数、网络节点数、迭代次数、学习率等等,这些参数不在梯度下降的更新范围内。尽管现在已经有一些算法可以用来搜索模型的超参数,但多数情况下我们还是自己人工根据验证集来调。

测试集的作用是使用一个完全没有参与训练的数据集,在模型最终训练完成后,用来测试一下最后的准确率。

模型评估与选择

误差

  • 错误率(error rate):在分类任务中,错分的样本数占样本总数的比例。比如m个样本有a个预测错了,错误率就是a/m
  • 精度(accuracy):或者说正确率,数值上等于1-错误率。

-误差(error):模型输出和真实值之间的差异。在训练集上的误差称为训练误差(training error)或者经验误差(empirical error)。而在新样本上的误差则称为泛化误差(generalization error)。我们希望模型的泛化误差尽可能小,但现实是,我们无法知道新样本是怎样的,所以只能尽可能地利用训练数据来最小化经验误差。

是否经验误差小,泛化误差就一定小呢?这不是一定的,如果模型相比训练数据来说过于复杂,那就很有可能把训练数据本身的一些特点当作整个样本空间的特点,从而使得在训练数据上有很小的经验误差,但一旦面对新样本就会有很大误差,这种情况叫做过拟合(overfitting)。相对的是欠拟合(underfitting)

欠拟合很容易避免,只要适当地增加模型复杂度(比方说增加神经网络的层数)就好。但过拟合是无法彻底避免的,只能缓解(减少模型复杂度/增加训练数据),这也是机器学习发展中的一个关键阻碍。

在现实任务中,要处理一个问题,我们往往有多种算法可以选择,即使是同一个算法也需要进行参数的选择,这就是机器学习中的模型选择(model selection)问题。既然泛化误差无法使用,而经验误差又存在着过拟合问题,不适合作为标准,那么我们应该如何进行模型选择呢?模型选择问题可以拆解为(1)评估方法;(2)性能度量;(3)比较检验;三个子问题:

  • 评估方法:用什么数据做评估?如何获得这些数据?

  • 性能度量:评估时如何衡量模型的好坏?有哪些评价标准?

  • 比较检验:如何比较模型的性能?

评估方法

前面已经提到了不能把经验误差用作模型评估,否则会存在过拟合的嫌疑。那么很自然地,我们就会想到是否有一种方法能近似泛化误差呢?答案是有的,就是使用测试集(testing set)进行评估,利用测试误差(testing error)来近似泛化误差。

测试集和训练集一样,从样本空间中独立同分布采样而得,并且应尽可能与训练集互斥,也即用于训练的样本不应再出现在测试集中,否则就会高估模型的性能。为什么呢?举个例子,老师布置了2道题做课后作业,如果考试还是出这2两题,只能证明大家记住了这2道题;只有出不一样的题,才能看出大家是否真的掌握了知识,具备了举一反三的能力。

注意!!测试数据更多地是指模型在实际使用中遇到的数据,为了和模型评估中使用的测试集进行区分,一般会把模型评估用的测试集叫做验证集(validation set)。举个例子,在Kaggle或者天池上参加比赛,我们一般会拿到一份带标记的原始数据集和一份不带标记的测试数据集。我们需要选用一种评估方法来把原始数据集划分成训练集和验证集,然后进行训练,并按照模型在验证集上的性能表现来进行选择。最后挑出最好的模型对测试集的样本进行预测,并提交预测结果。下文将介绍几种常用的评估方法。

留出法

直接将数据集划分为两个互斥集合,注意保持数据分布的一致性(比如比例相似)。保留类别比例的采样方式又叫分层采样(stratified sampling)。举个例子,原始数据集有100个样本,假设训练集占70个,验证集占30个。若训练集中正例反例各35个,也即比例为1:1,那么验证集中就应该正例反例个15个,同样保持1:1的比例。当然,这个比例最好还是遵循原始数据集中数据的分布规律。

单独一次留出法的结果往往不可靠,一般是进行多次随机划分,然后取各次评估的平均值作为评估结果。

留出法最大的缺点就是要进行划分,当训练集占的比例较大时,模型可以更准确地刻画原始数据集的特征,但是因为验证集较小,评估的结果往往不稳定也不准确;当训练集占的比例较小时,训练出的模型又不能充分学习到原始数据集的特征,评估结果可信度不高。这个问题没有完美的解决方案,一般取数据集2/3~4/5的样本作为训练集,余下的作为验证集。

交叉验证

又称为k折交叉验证(k-fold cross validation),将数据集划分为k个互斥子集。每次使用k-1个子集的并集作为训练集,余下的一个子集作为验证集,这就构成了k组训练/验证集,从而可以进行k次训练和验证。最终取k次验证的均值作为评估结果。 常用的k值包括5,10,20。

类似于留出法,因为存在多种划分k个子集的方式,为了减少因不同的样本划分而引入的差别,需要进行多次k折交叉验证。例如10次10折交叉验证,指的是进行了总计100次训练和100次评估。

特别地,令k=数据集样本数的交叉验证称为留一法(Leave-One-Out,简称LOO),即有多少样本就进行多少次训练/验证,并且每次只留下一个样本做验证。这样做的好处是不需要担心随即样本划分带来的误差,因为这样的划分是唯一的。一般来说,留一法的评估结果被认为是比较准确的。但是!当数据集较大时,使用留一法需要训练的模型太多了!这种计算开销是难以忍受的!

自助法

在留出法和交叉验证法中,我们都需要对数据集进行划分,从而使得训练所用的数据集比源数据集小,引入了一些因规模不同而造成的偏差,有没有办法避免规模不同造成的影响呢?

自助法(bootstrapping)正是我们需要的答案,以自助采样(bootstrap sampling)为基础,对包含m个样本的源数据集进行有放回的m次采样以获得同等规模的训练集。在这m次采样中都不被抽到的概率大约为0.368,也即源数据集中有大约1/3的样本是训练集中没有的。因此,我们可以采用这部分样本作为验证集,所得的结果称为包外估计(out-of-bag estimate)

注意,自助法适用于数据集小,难以划分训练/验证集的情况。因为自助法能产生多个不同训练集,所以对集成学习也大有好处。但是!自助法改变了数据集的分布,也因此引入了一些额外的误差。因此,数据量足的时候还是留出法和交叉验证法用得多一些。

调参和最终模型

调参(parameter tuning)一般先选定一个范围和变化步长,比如(0,1],步长0.2,这样就有五个参数候选值。然后进行评估,选出最好的一个。这样选出的未必是全局最优的参数,但为了在开销和性能之间折中,只能这么做,毕竟我们无法试尽参数的所有取值。而且多个参数组合的情况是指数上升的,比方说有3个参数,每个参数评估5种取值,就需要测试多达 $5^3$ 种情形。

特别注意,训练/验证这个过程是为了让我们确定学习算法和算法的参数,确定了这些之后,我们需要再利用整个源数据集进行训练,这次训练所得的模型才是最终模型,也即提交给用户,进行测试的模型。

性能度量

性能度量(performance measure)指的是用于衡量模型泛化能力的评价标准。使用不同的性能度量往往导致不同的评判结果。比方说搭建推荐系统,两个模型中一个精度高,一个覆盖度高,如果我们想让更多的商品得到推荐可以就会选后一个模型。所以说,模型的好坏是相对的,取决于我们采用什么性能度量,而采用什么性能度量则应取决于我们的任务需求

这里主要介绍分类任务中常用的性能度量。

错误率和精度

在本章的开头已经提及到了,不再累述,这两个性能度量可写作更一般的形式,基于数据分布和概率密度函数进行定义。

查准率,查全率,F1

假设我们正常处理一个二分类问题,按照模型预测值和真实值可以把测试样本划分为四种情形:真正例(true positive),假正例(false positive),真反例(true negative),假反例(false negative)。可以把结果表示为下图这个矩阵——混淆矩阵(confusion matrix)

真实情况 预测结果
正例 反例
正例 TP(真正例) FN(假反例)
反例 FP(假正例) TN(真反例)

查准率,又称准确率(precision),用于衡量模型避免错误的能力,分母是模型预测的正例数目。

\[precision = \frac{TP}{TP+FP}\]

查全率,又称召回率(recall),用于衡量模型避免缺漏的能力,分母是测试样本真正包含的正例数目。

一般来说,这两者是矛盾的,提高其中一者则另一者必然会有所降低。

\[recall = \frac{TP}{TP+FN}\]

F1,是查准率和查全率的调和平均,用于综合考虑这两个性能度量。

\[\frac{1}{F1} = \frac{1}{2} \times (\frac{1}{precision} + \frac{1}{recall}) \Rightarrow F1 = \frac{2 \times precision \times recall}{presion + recall}\]

有时候我们对查准率,查全率的需求是不同的。比方说广告推荐,要尽量避免打扰用户,因此查准率更重要;而逃犯检索,因为漏检的危害很大,所以查全率更重要。这时就需要使用$F_\beta$了。

$F_\beta$,是查准率和查全率的加权调和平均,用于综合考虑这两个性能度量,并采用不同的权重。

\[\frac{1}{F_\beta} = \frac{1}{1+\beta^2} \times (\frac{1}{precision} + \frac{\beta^2}{recall}) \Rightarrow F_\beta = \frac{(1+\beta^2) \times precision \times recall}{(\beta^2 \times presion) + recall}\]

其中 $\beta>0$ 度量了查全率对查准率的相对重要性,等于1时$F_\beta$退化为F1,小于1时查准率更重要,大于1时查全率更重要。

书中还介绍了如何对多次训练/测试产生的多个混淆矩阵进行评估,包括宏方法(先分别计算性能度量,再计算均值)和微方法(先对混淆矩阵各元素计算均值,再基于均值计算性能度量)两种途径。

ROC与AUC

很多时候,使用模型对测试样本进行预测得到的是一个实值或者概率(比如神经网络),需要进一步设置阈值(threshold),然后把预测值和阈值进行比较才能获得最终预测的标记。

我们可以按照预测值对所有测试样本进行排序,最可能是正例的排前面,最不能是正例的排后面。这样分类时就像是在这个序列中以某个截断点(cut point)把样本分成两部分。我们需要根据任务需求来设置截断点。比如广告推荐更重视查准率,可能就会把截断点设置得更靠前。

因此!排序本身的质量很能体现出一个模型的泛化性能,ROC曲线就是一个用来衡量排序质量的工具。

ROC,全称受试者工作特征(Receiver Operating Characteristic)。怎样画ROC曲线呢?先定义两个重要的计算量:真正例率(True Positive Rate,简称TPR)假正例率(False Positive Rate,简称FPR)

\[TPR = \frac{TP}{TP+FN}\] \[FPR = \frac{FP}{TP+FN}\]

TPR其实就等于召回率。在绘制ROC曲线时,纵轴为TPR,横轴为FPR。首先按预测值对样本进行排序,然后按序逐个把样本预测为正例,并计算此时的TPR和FPR,然后在图上画出该点,并与前一个点连线。如下图:

ROC curve

有两个值得注意的特例:

  • 经过 (0,1) 点的曲线,这代表所有正例都在反例之前出现(否则会先出现假正例从而无法经过 (0,1) 点),这是一个理想模型,我们可以设置一个阈值,完美地分割开正例和反例。

  • 对角线,这对应于随机猜测模型,可以理解为真正例和假正例轮换出现,即每预测对一次接下来就预测错一次,可以看作是随机猜测的结果。

若一个模型的ROC曲线完全包住了另一个模型的ROC曲线,我们就认为这个模型更优。但是如果两条曲线发生交叉,要怎么判断呢?比较合理的判据是AUC(Area Under ROC Curve),即ROC曲线下的面积。

\[AUC=\frac{1}{2}\sum_{i=1}^{m-1}(x_{i+1}-x_i)\cdot(y_i+y_{i+1})\]

补充一点,ROC曲线上的面积等于排序损失(loss)。也即有:

\[AUC = 1 - \ell_{rank}\]

代价敏感错误率与代价曲线

现实任务中,有时会遇到不同类型错误造成后果不同的状况。比如医生误诊,把患者诊断为健康人的影响远大于把健康人诊断为患者,因为可能因为这次误诊丧失了最佳治疗时机。为了权衡不同类型错误带来的不同损失,可以为这些错误类型赋以非均等代价(unequal cost)

还是举二分类为类,可以根据任务的领域知识来设定一个代价矩阵(cost matrix):

真实类别 预测类别
第0类 第1类
第0类 0 $cost_{01}$
第1类 $cost_{10}$ 0

预测值与真实值相等时,自然错误代价为0。但把第0类错预测为第1类和把第1类错预测为第0类这两种错误的代价是不同的。注意,重要的不是代价在数值上的大小,而是它们的比值。比方说 $\frac{cost_{01}}{cost_{10}} > 1$, 这就说明把第0类错预测为第1类的代价更高。

使用了非均等代价之后,我们在使用性能度量时自然也需要作出相应的改变,比方说代价敏感(cost-sensitive)版本的错误率:

\[E(f;D;cost) = \frac{1}{m}\lgroup\sum_{x_i \in D^+}\mathbb{I}(f(x_i) \neq y_i) \times cost_{01} + \sum_{x_i \in D^-}\mathbb{I}(f(x_i) \neq y_i) \times cost_{10}\rgroup\]

由于ROC曲线不能反应使用非均等代价之后的期望总体代价,所以改用代价曲线(cost curve)来取替。

代价曲线图的纵轴为归一化代价(将代价映射到 [0,1] 区间),横轴为正例概率代价。画法类似于ROC曲线,它是将ROC曲线的每一个点转为图中的一条线。依次计算出ROC曲线每个点对应的FPR和FNR,然后把点 (0,FPR) 和点 (0,FNR) 连线。最终所得的图中,所有线的下界所围成的面积就是该模型的期望总体代价。

比较检验

看起来似乎有了获取测试集$^{*}$的评估方法和用于比较模型的性能度量之后,就能够通过不同模型在测试集上的性能表现来判断优劣了。但是!事实上,在机器学习中,模型比较并不是这样简单的比大小,而是要考虑更多。

注:指验证集,但无论是书中还是论文中,都使用测试集较多,明白两者的区别就可以了。

在模型比较中,主要有以下三个重要考虑:

  1. 测试集上的性能只是泛化性能的近似,未必相同;
  2. 测试集的选择对测试性能有很大影响,即使规模一致,但测试样例不同,结果也不同;
  3. 一些机器学习算法有随机性,即便算法参数相同,在同一测试集上跑多次,结果也可能不同;

那么应该如何有效地进行模型比较呢?答案是采用假设检验(hypothesis test)。基于假设检验的结果,我们可以推断出,若在测试集上观察到模型A优于B,则是否A的泛化性能在统计意义上也优于B,以及做这个结论的把握有多大。

本小节首先介绍最基本的二项检验和t检验,然后再深入介绍其他几种比较检验方法。默认以错误率作为性能度量。

几个基础概念:

  • 置信度:表示有多大的把握认为假设是正确的。
  • 显著度:也称“显著性水平”,表示假设出错的概率。显著度越大,假设被拒绝的可能性越大。
  • 自由度:不被限制的样本数,也可以理解为能自由取值的样本数,记为 $v$ 或 $df$。

单个模型、单个数据集上的泛化性能检验

我们有多大把握相信对一个模型泛化性能的假设?

二项检验

在进行比较检验前,完成了一次模型预测,已知测试错误率为 $\hat{\epsilon}$。

一个泛化错误率为 $\epsilon$ 的模型在 $m$ 个样本上预测错 $m’$ 个样本的概率为:

\[P(\hat{\epsilon};\epsilon) = \binom{m}{m'} \epsilon^{m'} (1-\epsilon)^{m - m'}\]

这个概率符合二项分布:

二项分布

又因为已知测试错误率为 $\hat{\epsilon}$,也即知道了该模型在 $m$ 个样本上实际预测错 了$\hat{\epsilon} \times m$ 个样本。代入公式,对 $\epsilon$ 求偏导会发现,给定这些条件时,$\epsilon = \hat{\epsilon}$ 的概率是最大的

使用二项检验(binomial test),假设泛化错误率 $\epsilon \leq \epsilon_0$,并且设定置信度为 $1-\alpha$。则可以这样定义错误率的阈值 $\overline{\epsilon}$:

\[\overline{\epsilon} = \max{\epsilon} \qquad s.t. \qquad \sum_{i=\epsilon_0 \times m+1}^m \binom{m}{i}\epsilon^i (1-\epsilon)^{m-i} < \alpha\]

其中 $s.t.$ 表示左式在右边条件满足时成立。右式计算的是发生不符合假设的事件的总概率,如果我们要有 $1-\alpha$ 的把握认为假设成立,那么发生不符合假设的事件的总概率就必须低过 $\alpha$。

在满足右式的所有 $\epsilon$ 中,选择最大的作为阈值 $\overline{\epsilon}$。如果在测试集中观测到的测试错误率 $\hat{\epsilon}$ 是小于阈值 $\overline{\epsilon}$的, 我们就能以$1-\alpha$ 的把握认为假设成立,即该模型的泛化误差 $\epsilon \leq \epsilon_0$。

t检验

二项检验只用于检验某一次测试的性能度量,但实际任务中我们会进行多次的训练/测试,得到多个测试错误率,比方说进行了k次测试,得到 $\hat{\epsilon}_1$,$\hat{\epsilon}_2$, … ,$\hat{\epsilon}_k$。这次就会用到t检验(t-test)

定义这 $k$ 次测试的平均错误率 $\mu$ 和方差 $\sigma^2$:

\[\mu = \frac{1}{k} \sum_{i=1}^k \hat{\epsilon_i}\] \[\sigma^2 = \frac{1}{k-1} \sum_{i=1}^k (\hat{\epsilon_i} - \mu)^2\]

注意!这里使用的是无偏估计样本方差,分母是 $k-1$,因为当均值确定,并且已知 $k-1$ 个样本的值时,第 $k$ 个样本的值是可以算出来的,也可以说是受限的

假设泛化错误率 $\epsilon = \epsilon_0$,并且设定显著度为 $\alpha$。计算统计量t:

\[t = \frac{\sqrt{k}(\mu-\epsilon_0)}{\sigma}\]

该统计量服从自由度 $v = k-1$ 的t分布,如下图:

t分布

自由度越大,约接近于正态分布,自由度为无穷大时变为标准正态分布($\mu=0$,$\sigma=1$)。

如果计算出的t统计量落在临界值范围 [$t_{-a/2}$,$t_{a/2}$] 之内(注:临界值由自由度 $k$ 和显著度 $\alpha$ 决定,通过查表得出),我们就能以$1-\alpha$ 的把握认为假设成立,即该模型的泛化误差 $\epsilon = \epsilon_0$。

两个模型/算法、单个数据集上的泛化性能检验

我们有多大把握相信两个模型的泛化性能无显著差别?

交叉验证t检验

对两个模型A和B,各使用k折交叉验证分别得到k个测试错误率,即$\hat{\epsilon}_1^A$,$\hat{\epsilon}_2^A$, … ,$\hat{\epsilon}_k^A$ 和 $\hat{\epsilon}_1^B$,$\hat{\epsilon}_2^B$, … ,$\hat{\epsilon}_k^B$。使用k折交叉验证成对t检验(paired t-tests)来进行比较检验。

对于这两组k个测试错误率,计算两组之间的每一对的差,即 $\triangle_i = \hat{\epsilon}_k^A - \hat{\epsilon}_k^B$,从而得到k个 $\triangle$。我们可以计算 $\triangle$ 的均值 $\mu$ 和方差 $\sigma^2$,定义统计量t:

\[t = \lvert \frac{\sqrt{k}\mu}{\sigma} \rvert\]

可以看到,和前面的t检验相比,这里的分子没有被减项,其实是省略了。因为我们假设两个模型的泛化错误率相同,实际上是假设 $\lvert \epsilon^A - \epsilon^B \rvert = 0$,这个 $0$ 被省略了。

类似地,这个统计量服从自由度 $v = k-1$ 的t分布。我们设定好显著度 $\alpha$,查表获取临界值范围,如果计算出的t统计量落在在范围内,就能以$1-\alpha$ 的把握认为假设成立,即两个模型的泛化性能无显著差别,否则认为平均测试错误率较低的模型更胜一筹。

McNemar检验

对于一个二分类问题,如果使用留出法,我们不仅可以获得两个算法A和B各自的测试错误率,或能够获得它们分类结果的差别(都预测正确、都预测错误、一个预测正确一个预测错误),构成一张列联表(contingency table)

算法B 算法A
分类正确 分类错误
分类正确 $e_{00}$ $e_{01}$
分类错误 $e_{10}$ $e_{11}$

假设两个算法的泛化性能无显著区别,则 $e_{01}$ 应该等于 $e_{10}$,变量 $\lvert e_{01}-e_{10} \rvert$ 应服从均值为 $1$,方差为 $e_{01} + e_{10}$ 的正态分布,可以计算统计量 $\chi^2$:

\[\chi^2 = \frac{(\lvert e_{01}-e_{10} \rvert -1)^2}{e_{01} + e_{10}}\]

该变量服从自由度为 $v=1$ 的 $\chi^2$ 分布(卡方分布),类似t检验,设定好显著度 $\alpha$,按照自由度和显著度查表获得临界值。若计算所得的统计量 $\chi^2$ 小于临界值,则能以$1-\alpha$ 的把握认为假设成立,即两个算法的泛化性能无显著差别,否则认为平均测试错误率较低的算法更胜一筹。

注:这里 $v$ 为1是因为只有2个算法

多个模型/算法、多个数据集上的泛化性能检验

我们有多大把握相信多个模型的泛化性能皆无显著差别?若有,接下来怎样做?

一组数据集上进行多个算法的比较,情况就变得较复杂了,一种做法是使用前面的方法分开两两比较;另一种更直接的做法是使用基于算法排序的Friedman检验。

Friedman检验

假设有 $N=4$ 个数据集,$k=3$ 种算法,可以使用一种评估方法,获得各个算法在各个数据集上的测试结果,然后按照性能度量由好到坏进行排序,序值为1,2,3。若并列,则取序值的平均值。然后对各个算法在各数据集上的序值求平均得到平均序值,如:

数据集 算法A 算法B 算法C
D1 1 2 3
D2 1 2.5 2.5
D3 1 2 3
D4 1 2 3
平均序值 1 2.125 2.875

令 $r_i$ 表示第 $i$ 个算法的平均序值,则 $r_i$ 服从均值为 $\frac{k+1}{2}$,方差为 $\frac{(k^2)-1}{12}$ 的正态分布。可以计算统计量 $\chi^2$:

\[\chi^2 = \frac{12N}{k(k+1)}(\sum_{i=1}^k r_i^2 - \frac{k(k+1)^2}{4})\]

在 $k$ 和 $N$ 都较大时(通常要求 $k>30$),该变量服从自由度为 $v=k-1$ 的 $\chi^2$ 分布(卡方分布)。

以上这种检验方式也称为原始Friedman检验,被认为过于保守,现在通常用统计量 $F$ 代替:

\[F = \frac{(N-1)\chi^2}{N(k-1)-\chi^2}\]

该变量服从于自由度为 $v=k-1$ 或 $v=(k-1)(N-1)$ 的 $F$ 分布。

和前面的检验方式有所区别,F检验是根据设定的显著度 $\alpha$ 和算法个数 $k$ 以及 数据集个数$N$ 这三者来查表的,如果计算出的统计量 $F$ 小于查表所得的临界值,则假设成立,能以$1-\alpha$ 的把握认为认为这 $k$ 个算法的泛化性能无显著区别。

但如果这个假设被拒绝了呢?这时就需要进行后续检验(post-hoc test),常用的有 Nemenyi后续检验

Nemenyi后续检验

定义平均序值差别的临界值域为:

\[CD = q_\alpha \sqrt{\frac{k(k+1)}{6N}}\]

其中 $q_\alpha$是由 显著度 $\alpha$ 和算法个数 $k$ 确定的,通过查表获取。若两个算法的平均序值之差不超过 $CD$,则能以$1-\alpha$ 的把握认为这两个算法的泛化性能无显著区别,否则认为平均序值较小的更胜一筹。

Nemenyi后续检验还可以通过Friedman检验图更直观地体现出来,横轴为性能度量,纵轴为算法,每个算法用一段水平线段表示,线段中心点为该算法的平均序值,线段长度为 $CD$。若两个算法的线段投影到x轴上有重叠部分,则可以认为这两个算法的泛化性能无显著区别。

偏差与方差

除了估计算法的泛化性能,我们往往还希望知道为什么有这样的性能?这时一个有用的工具就是偏差-方差分解(bias-variance decomposition)

对学习算法的期望繁华错误率进行拆解,最终会发现能拆解为三个项(需要推导):

\[E(f;D) = \mathbb{E}_D[(f(x;D) - \overline{f}(x))^2] + (\overline{f}(x) - y)^2 + \mathbb{E}_D[(y_D - y)^2]\]

依次对应于方差(variance)偏差(bias)噪声(noise)

\[E(f;D) = var(x) + bias^2(x) + \epsilon^2\]
  • 方差:使用同规模的不同训练集进行训练时带来的性能变化,刻画数据扰动带来的影响

  • 偏差:学习算法的期望预测与真实结果的偏离程度,刻画算法本身的拟合能力

  • 噪声:当前任务上任何算法所能达到的期望泛化误差的下界(即不可能有算法取得更小的误差),刻画问题本身的难度

也即是说,泛化性能是有学习算法的拟合能力,数据的充分性以及问题本身的难度共同决定的。给定一个任务,噪声是固定的,我们需要做得就是尽量降低偏差和方差。

但是这两者其实是有冲突的,这称为偏差-方差窘境(bias-variance dilemma)。给定一个任务,我们可以控制算法的训练程度(如决策树的层数)。在训练程度较低时,拟合能力较差,因此训练数据的扰动不会让性能有显著变化,此时偏差主导泛化错误率;在训练程度较高时,拟合能力很强,以至于训练数据自身的一些特性都会被拟合,从而产生过拟合问题,训练数据的轻微扰动都会令模型产生很大的变化,此时方差主导泛化错误率。

注意,将泛化性能完美地分解为方差、偏差、噪声这三项仅在基于均方误差的回归任务中得以推导出,分类任务由于损失函数的跳变性导致难以从理论上推导出分解形式,但已经有很多方法可以通过实验进行估计了。

版权声明:本文为博主原创文章,转载请注明出处。 旭日酒馆