到目前为止,我们已经一同学习了许多不同的学习算法。然而在懂机器学习的人当中,依然存在着很大的差距。一部分人确实掌握了怎样高效有力地运用这些学习算法,而另一些人可能没有完全理解怎样运用这些算法,因此总是把时间浪费在毫无意义的尝试上,接下来我们就来看看如何让确保你在设计机器学习的系统时走的是一条最合适最正确的道路。
接下来该干什么?
为了确保我们不会在无意义的调整上浪费时间,我们需要重点关注的问题是,假如我们在开发一个机器学习系统或者想试着改进一个机器学习系统的性能,我们应如何决定接下来应该干什么?
为了解释这一问题我们仍然使用预测房价的学习例子。假如我们已经完成了正则化线性回归,也就是已经最小化代价函数 J 的值:
接着如果我们要将得到的假设函数放到一组新的房屋样本上进行测试,发现在预测房价时产生了巨大的误差,接下来我们就要改进这个算法,具体应该怎么办?
实际上我们可以想出很多种方法来改进这个算法的性能。其中一种很通用的办法就是使用更多的训练样本,具体来讲我们可以通过电话调查或上门调查来获取更多的不同的房屋出售数据。但遗憾的是有时候获得更多的训练数据实际上并没有作用。另一个方法也很容易想到就是尝试选用更少的特征集,因此如果你有一系列特征x1 x2 x3等等,我们可以花一点时间从这些特征中仔细挑选一小部分来防止过拟合。或者也许我们需要用更多的特征,因为也许目前的特征集对我们来讲并不是很有帮助,我们希望从获取更多特征的角度来收集更多的数据。我们也可以尝试增加多项式特征的方法比如x1^2 x2^2 x1x2……我们还可以考虑其他方法,比如减小或增大正则化参数λ的值…………
因此改进算法的性能是一个很复杂很耗费时间的问题,我们非常希望在花费大量时间完成以上某一方面的工作之前就能知道其效果如何。上面的很多方法都可以扩展开来扩展成一个六个月或更长时间的项目,但遗憾的是大多数人都是凭感觉用来选择这些方法的标准,他们大多数最后都遗憾地发现自己选择的是一条不归路。幸运的是有一系列简单的方法能让我们选择好方向,事半功倍。
接下来我们将一同学习怎样评估机器学习算法的性能,其也被称为"机器学习诊断法" 。这些诊断法的执行和实现是需要花些时间的,但磨刀不误砍柴工,这样做的确是更有效率地节省了我们之后四处碰壁的时间,所以请好好学习并运用它。
评估假设函数
接下来怎样用你学过的算法来评估假设函数。为了确定学习算法的参数 θ 的时候,我们是使用梯度下降法或其他高级算法来让代价函数 J(θ) 最小化。有人认为得到一个非常小的训练误差一定是一件好事,但我们已经知道仅仅是因为这个假设具有很小的训练误差并不能说明它就一定是一个好的假设函数,而且我们也学习了过拟合假设函数的例子,所以训练误差 J(θ) 的值小不一定代表我们的假设函数是好的,换句话说我们无法确定其是否过拟合。
那么,我们该如何判断一个假设函数是否过拟合的呢,对于一个简单的例子,比如说我们之前卖房子的例子,我们可以对假设函数 h(x) 进行画图,然后观察图形趋势:
但对于特征变量不止一个的这种一般情况,想要通过画出假设函数来进行观察就会变得很难甚至是不可能实现:
因此我们需要另一种方法来评估我们的假设函数,如下给出了一种评估假设函数的标准方法。
假设我们有下图这样一组数据组,一共有 10 个训练样本。为了确保我们可以评估我们的假设函数我们要做的是将这些数据分成两部分:第一部分将成为我们的常用训练集,而第二部分将成为我们的测试集,其中一种典型的分割方法是将70%的数据作为训练集,30%的数据作为测试集:
接着我们仍然用 m 表示训练样本的总数,而剩下的那部分数据将被用作测试集;在这里我们使用 mtest 来表示测试样本的总数。最后再提醒一点,在这里我是选择了前70%的数据作为训练集,后30%的数据作为测试集,但如果这组数据有某种规律或顺序的话,那么最好是随机选择70%作为训练集剩下的30%作为测试集。当然如果你的数据已经随机分布了,那我们大可以直接选择前70%和后30%。
在划分了数据之后,我们来看看如何测试我们的学习算法,比如线性回归算法首先。首先我们需要将那 70% 的训练集喂给我们的学习算法以得到参数 θ,即通过训练集最小化训练误差J(θ):
在确定了我们的参数 θ 后,我们就得到了我们的模型函数,接下来我们再通过后计算出测试误差。我们所要做的就是取出你之前从训练集中学习得到的参数 θ 所构成的假设函数 y ,仍然用上面的代价函数计算公式去计算我们的假设函数对于测试集的误差。我们便可以用得出的误差来评估我们的假设函数。
我们之前讨论的是线性回归问题。如果是考虑分类问题,比如说使用逻辑回归的时候,我们的做法也是类似的。首先我们要从训练数据也就是所有数据的70%中学习得到参数 θ ,然后用如下的方式计算测试误差:
目标函数和我们平常做逻辑回归的一样,唯一的区别是现在我们使用的是 mtest 个测试样本,这里的测试误差Jtest(θ) 其实不难理解,和平常的代价函数也是类似的。
但在分类问题上,还有一种计算误差函数的方法,叫误分类率也被称为0/1错分率,0/1表示了你预测到的正确或错误样本的情况:
比如说我们可以这样定义一次预测的误差,关于假设h(x) 和标签y的误差等于 1 时,当且仅当我们的假设函数h(x)的值大于等于0.5,并且y的值等于0;或者当h(x)小于0.5,并且y的值等于1。而这两种情况都表明我们的假设对样本进行了误判。然后我们就能应用错分率误差来定义测试误差,即求出测试集中的平均误差率。
到这为止,我们一同学习了对模型的评估方法,那如果我们发现了模型有问题,该怎么改进呢?我们通过下一部分再一同探寻。
系数次数的确定
假如通过上面的方法,我们发现了我们的假设函数是过拟合或欠拟合的,那么我们就想去探寻最合适我们数据的多项式次数到底应该是几次的? 或者我们的正则化参数 λ 到底应该开多大呢?这些问题我们称之为模型选择问题,下面我们就来学习这种问题的解决方法。
我们已经多次接触到过拟合现, 在过拟合的情况中,学习算法在适用于训练集时表现非常完美但这并不代表此时的假设也很完美。更一般地说这也是为什么训练集误差通常不能正确预测出该假设是否能很好地拟合新样本的原因:
处于这种问题的存在,下面我们来考虑模型选择问题。假如说我们现在要选择能最好地拟合你数据的多项式次数,换句话说,假设函数可以是一次函数、二次函数、三次函数一直到十次函数,哪一个能更好地代表我们数据的特征呢?
如果我们想从这十个模型中选择一个最适当的多项式次数并且用这个模型进行估计,并预测我们的的假设能否很好地推广到新的样本上,那么很容易想到的一个做法是我们仿照之前的做法,将数据集划分为两部分——训练集和测试集。然后我们将训练集喂给我们的学习算法,这样我们就分别得到了这十个假设函数的代价函数最小时的参数 θ。接下来我们运用测试集求出这十个函数的误差误差 Jtest(θ(1)) Jtest(θ(2)) Jtest(θ(3)) ……:
为了确定选择哪一个模型最好,我们做的就是看看这些模型中哪一个对应的测试集计算出来误差最小,比如我们假设最终选择了五次多项式模型,这看起来很有道理对吧。 但其实这样做是错误的。
这里有一个问题是,我们这样做不能公平地说明我的假设推广到一般时的效果。其原因在于我们刚才是以测试集为评判标准去选择我们的函数模型,也就是说我们只是选择了一个能够最好地拟合测试集的函数模型,获取在得到这个“最佳的五次函数模型”系数的时候,尽管我们的已经尽力将代价函数最小化了,但它的值仍非常大,我们选择出来的有可能只是较好地反映了测试集而已。同样地,选择了模型以后,我们也不知道这个模型在其他数据上表现如何。换句话说,我们做的实际上是用测试集来拟合假设函数的次数,仅仅通过用测试集来拟合这个参数,同样也意味着这并不能较为公平地预测出假设函数的在遇到新样本时的表现。我们在选择完后无法确保我们选择的模型不是过拟合或欠拟合的。
为了解决这一问题,在模型选择中如果我们想要评价某个假设,我们通常采用以下的方法:给定某个数据集和之前将数据分为训练和测试集不同,我们要将其分为三段:
第一部分还是叫训练集,第二部分我把它叫做交叉验证集(cross validation set),简写为CV,最后一部分依然和以前一样是测试集。同时一种典型的分割比例是将60%的数据分给训练集,大约20%的数据给交叉验证集,最后20%给测试集。这个比例可以稍微调整,但这种分法是最典型的。
现在我们就定义了训练集、交叉验证集以及测试集,我们随之也可以定义训练误差,交叉验证误差和测试误差,它们都是类似的:
和之前使用使用测试集来选择模型不同,我们现在要使用交叉验证集来选择模型。具体来讲,首先我们还是将训练集喂给我们的学习算法,这样我们就分别得到了这十个假设函数的代价函数最小时的参数 θ。然后我要做的是跟之前用测试集来预测这些假设不同,我们要在交叉验证集中测试这些假设的表现,然后我要选择的是交叉验证集误差最小的那个假设:
这样一来我们模型的多项式的次数就没有跟测试集进行拟合,这样我们就回避了测试集的嫌疑,就可以光明正大地使用测试集来估计所选模型的泛化误差了。
这就巧妙地解决了我们之前所遇到的问题。
结语
通过这篇BLOG,相信你已经对模型评估有所了解了,希望能对你日后的科研学习起到帮助。最后希望你喜欢这篇BLOG!