一.机器学习诊断
在设计机器学习系统或者进行改进时如果遇到问题,下一步应该怎么办呢?
除了掌握一些学习算法之外,我们还需要知道如何调试一个算法。
例如我们已经实现了一个正则化线性回归来预测房价,
J(θ)=12m[∑mi=1(hθ(x(i))−y(i))2+λ∑mj=1θ2j]
然而在将假设函数测试一个新的数据集时,发现预测误差很大。接下来该怎么办?有以下一些方法可供选择。
★
获取更多训练样本
★
尝试使用更少的特征
★
尝试增加特征
★
尝试加入多项式特征
★
尝试减小
λ
★
尝试增大
λ
问题在于大多数人只是凭感觉选择其中的一种或几种方法,最后发现浪费了大量时间做了无用功。
使用机器学习诊断法可以帮我们评估算法,排除掉一些无用的方法,节省大量时间。
机器学习诊断(diagnostic):它本身是一种测试法,执行它可以深入了解某种算法是否有用,并可以从中获得信息,即如何才能最大化改进这种算法的效果。虽然它的执行和实现是需要时间的,但是使用它能让我们更高效地利用时间。
二.评估假设函数
首先我们要知道一个事实,仅仅因为假设函数具有较小的训练误差并不能说明它是一个好的假设函数。前面已经讲过了过拟合,它不能泛化到新的输入上。如何判断过拟合呢?前面提到过画图的方法,但是对于特征变量很多的情况,画图会变得十分困难。
<1>下面介绍一种评估假设函数的标准方法:把一个数据集按70%的训练集和30%的测试集的比例分为两个部分。(如果数据集的分布有规律,则要随机取70%作为训练集,剩下30%作为测试集;如果数据集已经是随机分布,则可以取前70%作为训练集,后30%作为测试集)
①评估线性回归假设函数:
—用那占70%的训练数据通过
minθJtrain(θ)=minθ12mtrain∑i=1mtrain(hθ(x(i)train)−y(i)train)2
学习出参数
θ
;
—计算测试集的误差:
Jtest(θ)=12mtest∑i=1mtest(hθ(x(i)test)−y(i)test)2
②评估逻辑回归假设函数:
—用那占70%的训练数据通过
minθJtrain(θ)=minθ{−1mtrain∑i=1mtrainy(i)trainloghθ(x(i)train)+(1−y(i)train)loghθ(x(i)train)}
学习出参数
θ
;
—计算测试集的误差:
Jtest(θ)=−1mtest∑i=1mtesty(i)testloghθ(x(i)test)+(1−y(i)test)loghθ(x(i)test)
<2>0/1误分类率
首先定义
err(hθ(x),y)={10如果hθ(x)≥0.5,y=0;如果hθ(x)<0.5,y=1其他情况
则误分类率
Testerror=1mtest∑i=1mtesterr(hθ(xtest)(i),y(i)test)
三.模型选择
令假设函数的次数为
d
,假设现在有
d=1,2,3,⋯,10
的假设函数可以选择。
①首先利用
minθJ(θ)
求出每一个假设函数的参数
θ
,用上标区分其假设函数的次数,即得到
θ(1),θ(2),⋯,θ(10)
②利用这些参数计算不同次数的假设函数在测试集上的误差,即
Jtest(θ(1)),Jtest(θ(2)),⋯,Jtest(θ(10))
。
③选择其中最小的一个
Jtest
对应的假设函数(例如:
d=5
)作为选择。
需要注意的是,上述方法只能说明假设函数的次数
d=5
(其实也算一个参数)是最适合测试集的,相当于我们用测试集拟合了参数
d
,但这个假设函数适不适合新的数据就不知道了。
为了解决上述问题,我们要将数据集分为三个部分:训练集(
mtest
),交叉验证集(
mcv
),测试集(
mtest
)。三者的典型分配比例是60%,20%,20%。
之前使用测试集来选择模型,现在要根据交叉验证集来选择模型:
①首先利用
minθJ(θ)
求出每一个假设函数的参数
θ
,用上标区分其假设函数的次数,即得到
θ(1),θ(2),⋯,θ(10)
②利用这些参数计算不同次数的假设函数在交叉验证集上的误差,即
Jcv(θ(1)),Jcv(θ(2)),⋯,Jcv(θ(10))
。
③选择其中最小的一个
Jcv
对应的假设函数(例如:
d=4
),即
hθ(x)=θ0+θ1x+⋯+θ4x4
作为选择。
④用测试集评估泛化误差
Jtest(θ(4))
,避开用测试集拟合多项式次数
d
的嫌疑。
四.偏差和方差
假设函数的多项式次数
d
的选择会影响拟合效果,
d
太小会欠拟合(高偏差),太大会过拟合(高方差),如下图:
训练集的误差
Jtrain(θ)
以及交叉验证集的误差
Jcv(θ)
随多项式次数
d
的变化曲线如下图:
曲线左边多项式的次数过小,欠拟合,导致无论在训练集还是交叉验证集上拟合效果都不好,即,高偏差。
曲线右边多项式的次数太大,过拟合,虽然在训练集上拟合得很好,但在交叉验证集上的误差则很大,即高方差。
由此可知:
高偏差(欠拟合):
Jtrain(θ)
较大,
Jcv(θ)≈Jtrain(θ)
高方差(过拟合):
Jtrain(θ)
较小,
Jcv(θ)>>Jtrain(θ)
1.正则化对偏差/方差的影响
我们已经知道正则化可以防止过拟合。但正则化参数
λ
的选择至关重要,
λ
太小则没有起到正则化的效果,会过拟合(高方差);
λ
太大则正则化过度,会导致欠拟合(高偏差),如下图:
那实际使用时应该如何选择正则化参数
λ
呢?
首先我们要注意的一点是
Jcv(θ),Jtest(θ)
的定义,切记切记它们都没有正则化项。而使用正则化时,
Jtrain(θ)
是用来拟合
θ
的,故它的定义要包含正则化项以控制拟合出的
θ
的值都较小。
例如给定了一个假设函数模型:
hθ(x)=θ0+θ1x+θ2x2+θ3x3+θ4x4
且代价函数
Jtrain(θ)=12mtrain∑mtraini=1(hθ(x(i))−y(i))2+λ2mtrain∑mtrainj=1θ2j
①首先定义我们要尝试的一系列
λ
值。例如:我们要尝试
λ=0,0.01,0.02,0.04,0.08,⋯,10.24
,共12个选择。
②接着利用
minθJtrain(θ)
求出每一个不同
λ
值的假设函数的参数
θ
,用上标区分它们,即得到
θ(1),θ(2),⋯,θ(12)
③利用这些参数计算不同
λ
值的假设函数在交叉验证集上的误差,即
Jcv(θ(1)),Jcv(θ(2)),⋯,Jcv(θ(12))
④选择其中最小的一个
Jcv
对应的
λ
作为正则化参数的选择。
下面给出
Jtrain(θ)和Jcv(θ)随λ
的变化曲线:
该图的左边对应着高方差的情况,即
λ
小,拟合出的
θ
参数较大,可能会过拟合,
Jtrain(θ)
小,
Jcv(θ)
大;
右边对应着高偏差的情况,即
λ
大,拟合出的
θ
参数很小,可能会欠拟合,
Jtrain(θ)和Jcv(θ)
都较大。
2.学习曲线
上面我们使用画曲线图的方法研究了是否存在高方差/高偏差问题,以及正则化对偏差/方差的影响,这种曲线图我们称为学习曲线。
学习曲线可以用来判断某个算法是否处于偏差、方差问题或者二者都有。
★
训练集大小在一般情况下的影响
假设用
hθ(x)=θ0+θ1x+θ2x2
进行拟合,
Jtrain(θ)和Jcv(θ)随训练集的大小m
变化的学习曲线如下:
即在不考虑正则化时,
当训练集大小
m
很小时,拟合出的假设函数泛化到新样本的能力很差,交叉验证误差
Jcv(θ)
很大,但因为训练集很小,对于每个样本的拟合效果会非常好,训练误差
Jtrain(θ)
几乎为0;
随着训练集不断增大,可能会拟合出更好的假设函数,泛化到新样本的能力增强,交叉验证误差
Jcv(θ)
逐渐减小,但因为对于训练样本不能做到之前那样完美拟合了,故训练误差
Jtrain(θ)
会逐渐增大。
★
训练集大小在高偏差时的影响
假设用
hθ(x)=θ0+θ1x
(高偏差)进行拟合,
Jtrain(θ)和Jcv(θ)随训练集的大小m
变化的学习曲线如下:
当训练集大小
m
很小时,拟合出的直线泛化到新样本的能力很差,交叉验证误差
Jcv(θ)
很大,但因为训练集很小,对于每个样本的拟合效果较好,训练误差
Jtrain(θ)
也较小;
随着训练集不断增大,训练出的直线更好的适应训练集,泛化到新样本的能力略有增强,交叉验证误差
Jcv(θ)
稍有减小,
m
大到一定值之后,训练出的还是一条差不多的直线,交叉验证误差
Jcv(θ)
将不再变化,成为水平的。训练集不断增大,对于训练样本的拟合就没那么准确了,故训练误差
Jtrain(θ)
会持续增大直到接近交叉验证误差
Jcv(θ)
。
由此可以看出,高偏差时,随着训练集不断增大,最终
Jtrain(θ)
和
Jcv(θ)
都较大。
意义:高偏差(欠拟合)时,增加训练数据是没有用的,因为
Jcv(θ)
稍微降低后就变为水平。
★
训练集大小在高偏差时的影响
假设用
hθ(x)=θ0+θ1x+⋯+θ100x100
(且
λ
较小,过拟合,高方差)进行拟合,
Jtrain(θ)和Jcv(θ)随训练集的大小m
变化的学习曲线如下:
当训练集大小
m
很小时,因为存在过拟合,训练误差
Jtrain(θ)
会非常小,同时过拟合的存在使假设函数泛化到新样本的能力不足,交叉验证误差
Jcv(θ)
很大 ;
随着训练集不断增大,想要完美拟合所有训练数据变得没那么容易,训练误差
Jtrain(θ)
会稍微增大,但因为
hθ(x)
的阶次很高,仍然存在过拟合,总体来说
Jtrain(θ)
还是很小的。训练集增大让交叉验证误差
Jcv(θ)
有减小的趋势,但因为过拟合依然存在,故
Jcv(θ)
只是稍微减小,仍然较大,
Jcv(θ)
与
Jtrain(θ)
间还是有很大差距。
意义:高方差(过拟合)时,增加训练数据可能会有用,因为随着训练数据增多
Jcv(θ)
与
Jtrain(θ)
越来越接近。
总而言之,学习曲线能让我们发现是否存在高方差/高偏差问题,以及采取某些手段(如:增加训练样本数)是否有意义,避免我们在调试学习算法时浪费时间。
五.总结
现在回到第一部分机器学习诊断那里提出的问题。在将假设函数测试一个新的数据集时,发现预测误差很大。接下来该怎么办?
当时提到很多人会从那些方法中凭感觉选择一种或者几种。通过一系列的研究以及学习曲线给出的启示,可知:
★
获取更多训练样本(对高方差有效,对高偏差无效)
★
尝试使用更少的特征(对高方差有效,对高偏差无效)
★
尝试增加特征(对高偏差有效,对高方差无效)
★
尝试加入多项式特征(对高偏差有效,对高方差无效)
★
尝试减小
λ
(对高偏差有效,对高方差无效)
★
尝试增大
λ
(对高方差有效,对高偏差无效)
另外如果打算用神经网络解决问题,还要选择是使用简单的神经网络还是使用复杂的神经网络。
简单的神经网络参数少,容易欠拟合,但优势是计算量小;
复杂的神经网络参数多,容易过拟合(可以通过正则化修正),计算量大,即使选择了使用复杂的神经网络还要继续选择是使用一个隐藏层还是多个隐藏层等等。
通常使用正则化的复杂神经网络的效果比使用简单神经网络的效果更好,具体实现时要靠考虑时间代价和计算复杂度代价等等。