模型的评估与选择(第一部分)

对一类问题,机器学习的算法层出不穷,得出的模型也各有千秋,那么到底应该选择什么样的模型呢?我们需要进行模型评估。我们可以把要解决的问题看作是一辆破损的汽车,解决问题的模型看作是扳手、钳子之类的工具,用不同的工具去维修这辆破损的汽车会得到不同的结果,要去判断这个结果的好坏就需要使用测量工具来评估,也许我们要用量角器、也许直接使用直尺,这就要根据情况而定了。

经验误差与过拟合

错误率(error rate):我们通常把分类错误的样本数占样本总数的比例称为错误率。

精度(accuracy):精度等与1减去错误率。

误差(error):我们把机器学习的实际预测输出与样本的真实输出之间的差异称之为误差。

训练误差(training error):机器学习在训练集上的误差称之为训练误差。

泛化误差(generaliztion error):机器学习在新样本上的误差称之为泛化误差。

很明显,我们希望得到泛化误差很小的学习器,但是由于不知道新样本是什么样的,所以只能尽量让训练误差最小。看上去这没什么问题,但是事实上凡事都需要有一个度,很多时候我们甚至能得到在训练集中分类错误率为0,精度为100%的学习器,但是大多数时候这样的模型并不好用。

当学习器把训练样本学的太好了,很可能会把训练样本本身的特点当成了所有潜在样本的特点,事实上这些特点是训练样本所独有的,那么最终的泛化误差就会很大了,也就是说返回性能下降了,这种现象在机器学习中称作过拟合。与过拟合相对的是欠拟合,简单的来说,就是对训练样本的学习还不太到位。

回到最开始的问题,很明显要评估一个模型是否适合解决此类问题最好的办法就是利用泛化误差,但是新样本到底是个什么鬼我们终究还是不知道的,也就无法得到泛化误差,而使用训练误差又会存在过拟合的问题,那么到底应该怎么去评估呢?

评估方法

要得到泛化误差看上去不太可能,但是我们可以得到一个近似值。我们从已有数据集中抽出来一部分作为测试集,得到测试误差,把这个测试误差作为淡化误差的近似。简单来说,就是把训练集中的一部分数据当做训练集,还有一部分假装是未知样本,然后用这些样本来校验模型。需要注意的问题就是,这一部分被临时抽出来假扮路人的测试集,从头至尾都不可以参加训练。那么,对于一组数据集,又搞训练,有得客串测试,到底要怎么做呢?下面是几种常见的办法:

留出法(hold-out)

直接将数据集$D$分为两个互斥的集合,其中一个作为训练集$S$,另一个作为测试集$T$,他们满足如下关系:
$$D=S \cup T , S \cap T=\emptyset $$

比如,$D$现在包含1000个样本,训练集$S$包含其中的700个样本,测试集$T$包含另外的300个样本,用$S$进行训练之后得到的模型在$T$里面应用,最终发现有90个样本分类错误,那么错误率就为 $(90/300)\times100 \%=30 \%)$,相应的精度为$1-30 \% = 70 \%$.

在留出法中需要注意以下三点:

  1. 要注意在训练集和测试集中保持数据分布的一致性,避免因为数据划分过程引入额外的偏差对最终结果造成影响,比如上面的集合D中包含500个正例和500个反例,那么700个样本组成的训练集中就应当包含350个正例和350个反例,同样的测试集中就应当包含150个正例和150个反例。

  2. 要注意就算数据在总体数据集、训练集和测试集中分布一致,但是是存在很多种划分方法,这个时候会对某些特征的权重产生影响。解决这个问题的办法就是进行多次划分,多次训练,多次测试。比如进行100次随机划分(同时保持一致性),然后会得到100个结果(测试误差),最终返回这100个结果的平均。

  3. 最后一个需要注意的问题是,因为D被分为了S和T,如果T的占比及较大,训练得到的模型可能更接近于D的模型,而T又太小,评估结果明显不可靠。如果T中多包涵一些样本,相应的S就得减少,最后训练出来的模型可能和D的模型有比较大的差别,从而降低了评估结果的保真性。对于这个问题,没有完美的解决方案,一般的做法是将大约2/3到4/5的样本用于训练,其他的用来测试。

交叉验证法

交叉验证法是把数据集分为k个大小相似的互斥子集,然后每次用低k个子集作为测试器,其他的子集作为训练集。这样循环下去最终会进行k次训练和k次测试,最后返回k个测试结果的均值。通常这个方法也被称作为k交叉验证。
$$ D = D_1 \cup D_2 \cup D_3 \cdots \cup D_k, D_i \cap D_j \neq \emptyset(i \neq j) .$$

需要注意的问题:

  1. 与留出法一样,也需要保持数据分布的一致性。

  2. k的取值,常见的有10次10折交叉验证,也就是k=10

  3. 如果数据的样本数m和分成的子集数量k相等,这个时候每一个测试集其实只有一个样本,这种方法也被称为留一法,往往留一法被认为比较准确,但是换来的结果是开销会非常大,再者结果也未必精确,因为NFL定理在这里同样适用。

自助法

自助法对于包含m个样本的数据集$D$,对它进行采样产生数据集$D\prime$,每次一从D中随机挑选一个样本,将其拷贝放入$D\prime$,然后再把这个样本放回到$D$中,是的样本在下次采样的时候让然能够被采集到;把这个过程重复执行m次之后,就得到了包含m个样本数据$D\prime$ ,这样做的结果是$D$中会有一部分样本在$D\prime$中多次出现,而另一部分不出现。而样本在$m$次采集中始终不被采集到的概率是$(1-\frac{1}{m})^m$,取极限得到:
$$\lim_{m\rightarrow+\infty} (1-\frac{1}{m})^m\rightarrow \frac{1}{m} \approx 0.368$$

于是,我们可以将$D\prime$用作训练集,$D - D\prime$用作测试集;这样实际评估的模型和期望评估的模型都是用m个训练样本,而我们仍有数据总量越$1/3$的、没在训练集中出现的样本用于测试,这样的测试结果,也称作“包外估计”。

要注意的问题:

  1. 自助法在数据集比较小,难以有效划分训练集、测试集的时候很有用。同时,自助法能从初始数据集中产生多个不同的训练集。

  2. 自助法产生的数据集改变了初始数据集的分布,会引入估计偏差,当数据量足够的时候留出法和交叉验证法更常用一些。

性能度量

对机器学习的泛化性能进行评估,除了上面的评估其误差外,还需要去评估其能力,这就是性能度量。也就是预测的数值到底和原始数值有多接近。

在预测任务中,给定样例集$D={(x_1,y_1), (x_2,y_2),\cdots ,(x_m,y_m) }$,其中$y_i$是实例$x_i$的真实标记,要评估学习器$f$的性能,就要把学习器预测结果$f(x)$与真实标记$y$作比较。

回归问题的性能度量: 均方误差(mean squared error)

回归任务最常用的性能度量是均方误差(方差的平均数):
$$E(f;D) = \frac{1}{m} \sum_{i=1}^{m}(f(x_i)-y)^2$$
更一般的,对于数据分布$D$和概率密度函数$p(*),均方误差可以描述为$
$$E(f;D) = \int_{x-D}(f(x)-y)^2p(x)dx$$

分类问题的粗略度量:错误率与精度

错误率和精度是分类任务中常用的两种性能度量,既适用于二分类任务,也适用于多分类任务。错误率是分类错误的样本数占样本总数的比例,精度则是分类正确的样本数占总数的比例。
错误率可以定义为:
$$E(f;D) = \frac{1}{M} \sum_{i=1}^{m} \amalg(f(x_i)\neq y_i) $$
精度可以定义为:
$$add(f;D) = \frac{1}{M} \sum_{i=1}^{m} \amalg(f(x_i) = y_i) $$
$$ =1 - E(f;D) $$

分类任务的精确度量:查准率、查全率与F1

错误率与精度虽然常用,但不能满足所有任务需求。比如,在一个人工智能辅助诊断病情的模型中,错误率衡量的是有多少比例的人的身体状况被判别错误,但是我们关心的是“有多少**有病的人被诊断出来没有病**”,那么错误率显然是不能给出答案的。查准率与查全率则更适应于此类场景。

拿最简单的二分类问题来说,对于二分类问题,可以根据真实类别与机器学习预测的类别的组合划分出来四种不同的情况,假设上面的诊断模型输出的结果为有病或没病,那么预测结果与真实结果可以得到下面组合:

情况 预测有病 预测没病
真实有病 130 40
真实没病 50 200

我们想要知道的是,有病的人是真的有病,而不是假的有病,真的有病的人又查出来了几个,用上面的表格计算可以得到:

$$ 查的全不全=\frac{真的有病查出来也有病}{真的有病查出来也有病+真的有病但没查出来}=\frac{130}{130+40}$$

$$查的准不准=\frac{真的有病查出来也有病}{真实没病但查出来有病}=\frac{130}{130+50}$$

可以看出来,查的全不全这个问题上,模型诊断出来了130个人是有病的,但是事实上真实有病的病人一共有130+40个,漏掉了40个真的有病的人。 $\frac{130}{130+40}$就是查全率。

而对于查的准不准这个问题上,预测了130+50个人是有病的,但是这其中50个人其实是没有病的,真正正确的只有130个人,其他50个人是假的有病(网络流行语)。
$\frac{130}{130+50}$就是查准率。

把上面这个看病的例子,用一个泛型(面向对象程序设计中的一种实现多态,多类型支持的技巧)来描述,就有了下面这个混淆矩阵:

情况 预测为True 预测为False
真实为True TP(真正例) FN(假反例)
真实为False FP(假正例) TN(真反例)

对于这个矩阵,查准率P与查全率R可以表示为:
$$P=\frac{TP}{TP+FP}$$
$$R=\frac{TP}{TP+FN}$$

很明显,查准率与查全率是一对相互矛盾的度量。一般来说,查准率高的时候,查全率往往会偏低;查全率高的时候,查准率往往偏低。追求查准率和查全率都没有错,但是大部分时候只能选一个,这个要取决于具体的问题,比如上面的问题中,我们宁愿把没病的人诊断成有病,也不要错过一个真是有病的人被诊断为没病(这不是耽搁人嘛),所以我们应该追求的是查全率。但另一方面,我们又不希望给没有病的人造成没有必要的麻烦,这个时候应该去追求较高的查准率。对于看病这个问题,很多时候我们更倾向于查全,尽管会造成查准率降低。

PR图

但是并不是所有的问题都像看病问题这个特殊,大部分时候我们需要同时考虑查准率与查全率,根据查准率与查全率可以绘制出来P-R曲线和P-R图:

PR-曲线图

如果一个学习器的PR曲线被另一个学习器的PC曲线完全包住,则后者的性能优于前者。上图中A明显优于C。

BEP

如果两个学习器的PR曲线相交,就不能着急下结论了,这个时候一般回家算两条曲线下面包裹的面积,面积大的很明显取得PR双高的概率要更高。但是这个不太容易估算。对此,有人设计了BEP,平衡点(Break-Even Point)。

BEP是指查准率=查全率时候的取值,也就是画一条直线$f(x)=x$,曲线和这条直线的交点就是BEP。比如上图中A的BEP为0.8,B的BEP为0.72, 按照BEP来比较,学习器A优于B。但是,这也并不是绝对的,毕竟BEP还是过于简化了些。,更常用的方法是F1度量.

**F1

在一些应用中,对查准率和查全率的重视程度是不同的,比如上面看病的例子,更加追求查全率,以避免错过真正有病的人。但是在用户分类系统中,为了避免打扰到用户,把人家不喜欢的东西推给人家真的很烦啦。。。。,这个时候更侧重于查准率。F1度量可以帮助我们很好的去找到适合我们的点。

$$F_\beta=\frac{(1+\beta^2)×P×R}{(\beta^2×P)+R} $$

其中$\beta>$0度量了查全率对查准率的相对重要性。

  • $\beta=1$时退化为标准的F1;
  • $\beta>1$的时候查全率有更大影响;
  • $\beta<1$的时候查准率有更大影响;

对于多分类问题的多个混淆矩阵,或者二分类问题的多次训练得出的多个混淆矩阵。这个时候要综合考虑其查准率,查全率。

一种直接的做法是现在各个混淆矩阵上计算出来各自的查准率与查全率,在计算平均值,得到宏查准率(macro-P)、宏查全率(macro-R),以及对应的宏F1(macro-F1):

$$macro-P=\frac{1}{n}\sum_{i=1}^nP_i$$
$$macro-R=\frac{1}{n}\sum_{i=1}^nR_i$$
$$macro-F1=\frac{2×macro-P×macro-R}{macro-P+macro-R}$$

还可以现将各个混淆矩阵对应的元素进行平均,得到TP、FP、TN、FN的平均值记做$\overline{TP}$、$\overline{FP}$、$\overline{TN}$、$\overline{FN}$,在基于这些平均值计算微查准率(micro-P)、微查全率(micro-R)以及微F
1(micro-F1):

$$micro-P=\frac{\overline{TP}}{\overline{TP}+\overline{FP}}$$
$$micro-R=\frac{\overline{TP}}{\overline{TP}+\overline{FN}}$$
$$micro-F1=\frac{2×micro-P×micro-R}{micro-P+micro-R}$$

总结和后续

这篇笔记首先总结了模型评估中的三种评估方法,然后介绍了分类任务中常用的模型性能度量的方法,其中错误率与精度描述了模型在分类任务中的错误率与精确程度,一定程度上描述了模型的能力,但是在特定问题中还需要对更多具体的进行评估,错误率与精度并不能反映具体的分类情况。查准率与查全率很好的反映了模型在不同情况下的情况,但是到底选择P还是R,应该具体问题具体对待,有时候可以取BEP,让P与R相等。有时候对查准率与查全率有不同比例的侧重,这个时候则可以根据F1来进行度量,根据需求扩展F1到$F_\beta$.

写一篇文章,将会继续总结机器学习中的性能测量方法。有了性能测量方法,测量得到学习器性能之后,还会需要比较检验,以及使用方差偏差分解去解释算法的泛化性能。

文章目录
  1. 1. 经验误差与过拟合
  2. 2. 评估方法
    1. 2.1. 留出法(hold-out)
    2. 2.2. 交叉验证法
    3. 2.3. 自助法
  3. 3. 性能度量
    1. 3.1. 回归问题的性能度量: 均方误差(mean squared error)
    2. 3.2. 分类问题的粗略度量:错误率与精度
    3. 3.3. 分类任务的精确度量:查准率、查全率与F1
  4. 4. 总结和后续