目录
- 1.1决定下一步做什么(构建机器学习的实用建议)
- 1.2模型评估
- 1.3模型选择&交叉验证测试集的训练方法
- 模型选择总结举例
- 2.1通过偏差与方法进行诊断
- 2.2正则化、偏差、方差
1.1决定下一步做什么(构建机器学习的实用建议)
从一个例子开始:
假设你已经实现了正则化线性回归来预测房价,所以你有了学习算法的普通代价函数,平方误差加上这个正则化项,如下图:
但如果你训练模型时发现它的预测结果出现了太大的误差,接下来你要做什么?
当你构建一个机器学习算法时,你可以尝试很多不同的方法来解决误差大的问题。例如,1.你可以选择获得更多的训练样本,因为有更多的数据应该会有所帮助;2.你可能认为特征太多了,此时你可以尝试一组更小的特征集;3.你可能想添加的特征到数据里,例如房子的附加财产,此时预测效果可能更好;4.你可以找出已有的特征x1, x2等等,然后试着给它们加上多项式特征x1²,x2²,x1,x2等等;5.你可能会想lanbuda的值(正则化参数)选的好不好,太大了给它减小一点,太小了给它加大一点。如下图:
在如何的机器学习应用场景中,我们往往会发现有些算法会产生效果,而有些则没有;有效构建机器学习算法的关键在于你是否能够正确的投资你的时间在正确的地方上。接下来将学习如何进行一系列的测试,你可以运行它来深入了解算法中哪些是有效的,哪些是无效的,从而明白应该怎样提升性能。测试算法要一定的时间,但这个时间花的值。
1.2模型评估
让我们以房价预测为例,其中预测函数的输入是房子大小,假设你训练这个模型来预测房价 ,对于这个模型,它是一个四阶多项式,特征是x,x^ 2,x ^ 3,和x^4
因为我们将一个四阶多项式拟合到一个有五个数据点的训练集上,所以结果与训练数据非常吻合(显然过拟合)
但我们不太喜欢这个模型,因为即使该模型与训练数据吻合良好,我们认为它不能推广到新的不在训练集中的新示例。当你预测价格时,仅仅是房子大小的一个特征,你可以这样画出模型,可以看到曲线非常弱,所以我们知道这不是一个好的模型。
但如果你使用更多的特征去拟合模型,假设x1是房子的大小,x2是卧室的数量,x3是房子的层数,x4是房子的年代,那么绘制函数f更困难了,因为f现在是x1到x4的函数,有四个特征
如何绘制一个思维函数呢?
为了判断你的模型是否运行良好,尤其是在应用中你有不止一个或两个特征,这时绘制f比较困难,我们需要一些更系统的方法来评估你的模型运行情况,这里有一个你可以使用的技巧:
如果你有一个训练集,这是一个只有10个样本的小训练集,我们不会使用所有数据来训练模型的参数w和b,而是将训练集分为两个子集。把70%的数据放在第一部分称其为训练集,把剩下30%的数据放入测试集;我们要做的就是利用训练集上的70%左右的数据去训练模型的参数,然后我们会在这个测试集测试模型的表现。
在表示法上,我们将使用(x^1,y ^ 1),和之前一样,用(x^m,y ^ m)表示一个训练样本。只是在这个例子中我们要明确我们有七个训练样本,并引入一个新的符号 我们用m_train表示训练样本的数量,在这个小数据集中m_train=7,下标强调我们看的是数据的训练集部分。
对于测试集,我们用(x_test^1, y_test ^ 1)表示第一个测试示例 一直到(x_test ^ m, y_test ^m),m_test是测试样本的数量看,在这个例子中是3。
根据70/30,80/20来划分数据集并不罕见,大部分数据都进入训练集,然后一小部分进入测试集。
为了训练一个模型并对它进行评估,如果你使用误差为平方的线性回归,那么看起来会是这样:
首先通过最小化代价函数J(w,b)来拟合参数,这是一般的关于w和b的代价函数,最小化均方误差加上正则化项除以2m_train再乘以w_j ^ 2的和。
然后为了说明这个模型的表现如何,你要计算J_test(w,b)去检验,也就是测试集中的均方误差,这是1/(2m_test) m_test是测试样本的数量,然后是从i=1到这个数m_test的所有测试样本和均方误差的和,所以下边这个是第i个测试样本的预测值减去对应第i个测试样本的真实值。
注意检验误差公式J_test 不包括正则化项,这样你就能知道你的算法学习的怎么样了。
其中一个对计算机很有用的度量是训练误差,这是一个衡量学习算法在训练集上表现的指标。
定义J_train(w,b)等于1/2m_train所有训练集误差平方项的和。同样,和需要最小化参数的代价函数不同,这里不包括正则化项。
关于平方误差成本的回归的总结:
一开始的示例中J_trsin w,b会很低,因为你训练样本的平均误差将是零或者非常接近零,所以J_train非常接近于0。
但如果你有一些额外的样本,这些样本并没有被你的算法训练过,那么这些测试样本看起来就像下图一样:
算法预测的房价和真实值有较大的出入,因此J_test会很高。看到模型J_test很高,你就能意识到尽管它在训练集上表现很好,但实际上当推广到非数据集上的数据点时,模型的效果较差,这 就是误差代价平方的回归。
1.3模型选择&交叉验证测试集的训练方法
(可以使用1.2中的技巧为你的机器学习算法自动选择一个好的模型)
1.2中一旦模型的参数w和b适合于训练集,训练误差可能不能很好地反映算法的性能以及它的泛化能力(推广到训练集之外的新例子)。
我们该如何使用测试集,为给定的机器学习应用场景选择模型?
如果拟合一个函数来预测房价或其他回归问题,你可以考虑的一个模型是拟合这样一个线性模型,一阶多项式,这里用d=1表示,如果你想用这样的模型拟合训练集,你得到一些参数w和b,然后你可以计算J_test来估计它推广到新数据的效果如何。以此类推,如下:
以上方法不建议用,建议用下边的:
我们修改程序的方式是不再把数据分成两个子集:训练集和测试集;而是把数据分成三个不同的子集,我们称之为训练集,交叉验证集还有测试集。用我们之前举的10个训练的例子,我们可以取60%的数据放入训练集,使用的符号和之前在训练集部分讲的一样,取20%的数据放入交叉训练集,取20%的数据放入测试集中:
交叉验证集是一个额外的数据集,我们将使用它来检查或信任检查不同模型的有效性或准确性 。
在数据训练集,交叉验证集和测试集的这三个子集上,我们可以使用一下三个公式来计算训练误差、交叉验证误差和测试误差,然而通常这些项都不包括正则化项,它包含在训练对象中。这个中间的新项,交叉验证误差就是m_cv交叉验证样本的平均平方误差
和前边一样的模型d=1,d=2…d=10,然后拟合参数w1 b1,但我们不用在测试集中求参数,我们会在交叉验证集中计算这些参数并计算J_cv(w1,b1),类似地,去观察交叉验错误最低的
假如J_test(w4,b4)交叉验错误最低。最后,如果你想展示泛化误差估计这个模型会在新数据上表现的有多好,你就用数据的第三个子集求出J_test(w4,b4)。
在整个过程中,你使用训练集拟合了这些参数。然后选择参数d或使用交叉验证集选择多项式的次数,所以到目前为止,你还没有把任何参数w b d放到测试集中。这就是为什么在这个例子中J_test (w4.,b4) 将是这个模型泛化误差的公平估计。这样模型选择的流程就更完善了,它可以自动做出决定,比如为你的线性回归模型选择什么样的多项式阶。这个模型选择的流程也适用于在其他类型模型中作选择。例如,选择神经网络架构。
模型选择总结举例
如果你正在拟合个手写数字识别模型,你可以考虑这样的三种模型,甚至可能比这三个模型更大。但这里有一些不同的神经网络,小的,稍大一些,甚至更大。为了帮助你决定神经网络有多少层,以及每层应该有多少隐藏单元,然后,你可以训练所有这三个模型最后得到第一个模型的参数w1 b1 ,第种模型的参 数是w2 b2,第三种模型的参数是w3 b3。然后可以使用Jcv (交叉验证集)来评估神经网络的性能关于分类问题,Jcv可以是样本的百分比。因为这是一个分类问题,Jcv最常见的选择是,计算算法错误分类的交叉验证样本的比例。你可以使用所有的这三个模型来计算这个值,然后选择交叉验证误差最低的模型。如果在这个例子中,Jcv(W2,B2)的交叉验证误差最小,然后你将选择第二个神经网络,使用在这个模型上训练的参数。最后,如果你想计算出泛化误差的估计,你就用测试集来估计刚刚选择的神经网络的性能。在机器学习实践中,它被认为是做出所有关于学习算法决定的最佳方法,比如何选择参数,使用何种程度的多项式,但做决定只看训练集和交叉验证集,不用测试集。并只有在你做了所有这些决定之后,你才勾选你在测试集中设计和评估的所有选项。这样你的测试集就变得很公平,而不是对泛化误差的过度乐观估计。
2.1通过偏差与方法进行诊断
典型的机器学习系统开发流程就是你有一个想法,然后训练模型,建立机器学习系统的关键过程,就是如何决定下一步做什么,以及提高它的表现。在许多运用场景下,观察算法的偏差和方差(Bias and Variance) 能够很好的指导下一步改做什么。
还是前面的例子,如果用一条直线来拟合它,效果就不太好了。我们说这个算法有很高的偏差,或者说欠拟合。
如果拟合一个四阶多项式, 那么它会有高方差或过拟合。
如果你拟合中间这个二次多项式,那它拟合得挺好,也就是我说的"just right"。
因为这个问题只有个特征x,我们可以把函数f画成这样。但如果你有更多特征,你画不出f,也无法直观地看到它是否表现得那么好。
一个更系统的诊断或判断算法是否有高偏差或高方差的方法是,看你的算法在训练集和交叉验证集上的表现。 具体些,让我们看看下边的例子。
如果你要计算J_train,即算法在训练集上的表现如何?J_cv如何?
- 当高偏差算法的一个特点是欠拟合。 当J_train很高时, 就表明了该算法具有很高的偏差。
- 算法有当高方差的特征是,方差J_cv 比J_train高得多。换句话说,它在见过的数据上要比没见过的表现得更好。
J_train 不是太高意味着没有高偏差问题,J_cV并不比J _train差太多,这表明它也没有高方差问题。
下面展示J_train 和, J_cv 如何作为拟合多项式次数的函数。横轴是d,是我们拟合数据的多项式次数。左边对应的是d的一个小值,比如d =1,对应的是直线拟合。在右边,我们对应的是,d=4,更高的值,我们拟合的这个高阶多项式。如果你要画出J_train或者说J_train(w,b),你会发现当你拟合一个越来越高次的多项式时,这里我假设我们没有使用正则化,但当你拟合一个越来越高阶的多项式时,训练误差会趋于下降。因为当你有个非常简单的线性 函数时,它并不能很好地拟合训练数据,当你拟合二次函数或三阶多项式或四阶多项式时,对训练数据的拟合越来越好。随着多项式次数的增加,J_train通常会下降。
接下来看J_cv,也就是它在处理那些尚未拟合的数据时表现如何?
当d = 1时,当多项式的次数很低时,J_cv非常高,因为它欠拟合,所以它在交叉验证集上做得不好。右边也一样。但是如果d取中间值,一个二阶多项式,那么它实际上做得更好。如果你改变多项式的次数,你会得到一条像下边绿色这样的曲线,下降, 然后又上升。
总而言之,如何诊断学习算法中的偏差和方差?
- 如果你的学习算法有很高的偏差,或者它欠拟合,评判的关键指标是J_train
是否高。这对应于曲线最左边的部分,也就是J_train高的部分。通常J_train和J_cv会很接近。 - 高方差的关键指标是,如果J_cv远远大于J_train,图的最右边是J_cv远大于J_train。通常J_train会很低,但关键指标是J_cv是否远远大于J_train,这就是当我们用一个非常高阶的多项式来拟合这个小数据集时发生的情况。
- 事实证明,在某些情况下,可能会高偏差和高方差同时存在。这种情况在线性回归中并不常见,一种识别出这种情况的方法是,如果J_train高,并且交叉验证的误差,甚至比训练集还大。高偏差和高方差通常不会发生在深度神经网络的线性模型上。对于大多数学习算法的应用,你可能有高偏差或高方差问题,不是同时有两个。
高偏差意味着算法在训练集上表现不好。高方差意味着,算法在交叉验证集的表现比训练集上的差得多。