此系列为 Coursera 网站机器学习课程个人学习笔记(仅供参考)
课程网址:https://www.coursera.org/learn/machine-learning
参考资料:http://blog.csdn.net/scut_arucee/article/details/50388530
一、机器学习诊断
在设计机器学习系统或者进行改进时如果遇到问题,下一步应该怎么办呢?除了掌握一些学习算法之外,我们还需要知道如何调试一个算法。
仍然以预测房价为例:假如你已经完成了正则化线性回归,即最小化代价函数:
但是在用新的数据集测试的时候发现误差很大,接下来应该怎么办?一般情况下,我们有下面几种方法可供选择:
- 获取更多的训练样本
- 尝试增加/减少特征
- 尝试加入多项式特征 (x21,x22,x1x2,etc.)
- 尝试减小/增大 λ
问题在于大多数人只是凭感觉选择其中的一种或几种方法,最后发现浪费了大量时间做了无用功。
使用机器学习诊断法可以帮我们评估算法,排除掉一些无用的方法,节省大量时间。
机器学习诊断(Diagnostic)是一种测试法,利用它可以深入了解某种算法是否有用,并可以从中获得最大化改进算法的指示。虽然执行和实现是需要时间的,但是使用它能让我们更高效地利用时间。
二、评估假设函数
首先我们要明白,训练误差小并不能说明一个假设函数是好是坏,因为可能会存在过拟合问题,即不能泛化到新的数据上。那么,我们如何判断过拟合?一个简单的方法就是画图,画出假设函数
h
关于特征变量
下面介绍一种评估假设函数的标准方法。
2.1 评估假设函数的标准方法
首先,我们把数据集按照 70% 和 30% 的比例分成训练集(Training Set)和测试集(Test Set)。
如果数据集的分布有规律,则要随机取 70% 作为训练集,剩下 30% 作为测试集;如果数据集已经是随机分布,则可以直接取前 70% 作为训练集,后 30% 作为测试集。
2.1.1 评估线性回归假设函数
步骤如下:
① 利用训练集的数据最小化代价函数
J(θ)
,学习参数
θ
② 计算测试集的误差:
2.2.2 评估逻辑回归假设函数
步骤如下:
① 利用训练集的数据最小化代价函数
J(θ)
,学习参数
θ
② 计算测试集的误差:
2.2 误分类率
首先定义:
误分类率:
三、模型选择
令假设函数的次数为
d
,
我们可以执行下列步骤选出合适的模型:
- 通过最小化代价函数,即 minθJ(θ) ,求出上述每一个模型的参数 θ ,即得到 θ(1),θ(2),⋯,θ(10)
- 利用这些参数计算不同次数的假设函数在测试集上的误差,即 Jtest(θ(1)),Jtest(θ(2)),⋯,Jtest(θ(10))
- 从中选择 Jtest 最小的假设函数(例如: d=5 )作为选择
上面只能说明 d=5 (其实也算一个参数)是最适合测试集的,对于新的数据集 d=5 是否合适我们无法判断,但我们并不能再用测试集去评估假设函数的泛化能力,因为这个参数就是按照最能拟合测试集标准来选择的。
为了解决这个问题,我们可以把数据集分为三个部分:训练集(Training Set)、交叉验证集(Cross Validation Set)、测试集(Test Set)。这三者的分配比例可以是: 60%,20%,20% 。
这三部分的误差计算公式如下:
之前使用测试集来选择模型,现在要根据交叉验证集来选择模型:
- 通过最小化代价函数,即 minθJ(θ) ,求出上述每一个模型的参数 θ ,即得到 θ(1),θ(2),⋯,θ(10)
- 利用这些参数计算不同次数的假设函数在交叉验证集上的误差,即 Jcv(θ(1)),Jcv(θ(2)),⋯,Jcv(θ(10))
- 从中选择 Jcv 最小的假设函数(例如: d=4 )作为选择
- 用测试集评估泛化误差 Jcv(θ(4)) ,避开用测试集拟合多项式次数d的嫌疑
四、偏差与方差
4.1 高偏差与高方差
当你运行一个算法结果不理想时,多半是出现两种情况:要么是高偏差(High Bias),要么是高方差(High Variance),换句话说就是欠拟合(Underfitting)或者过拟合(Overfitting)。当我们判断出是哪一种情况,就能够找到最有效的改进算法的方法。
例如上述假设函数的多项式次数
d
的选择会影响拟合效果,
训练集的误差 Jtrain(θ) 以及交叉验证集的误差 Jcv(θ) 随多项式次数 d 的变化曲线如下图:
曲线左边多项式的次数过小,欠拟合(Underfitting),导致无论在训练集还是交叉验证集上拟合效果都不好,即,高偏差(High Bias)。
曲线右边多项式的次数太大,过拟合(Overfitting),虽然在训练集上拟合得很好,但在交叉验证集上的误差则很大,即高方差(High Variance)。
由此可知:
- 高偏差(欠拟合):
Jtrain(θ) 较大, Jcv(θ)≈Jtrain(θ)
- 高方差(过拟合): Jtrain(θ) 较小, Jcv(θ)>>Jtrain(θ)
4.2 正则化线性回归
我们已经知道正则化可以防止过拟合。但正则化参数λ的选择至关重要, λ 太小则没有起到正则化的效果,会过拟合(高方差); λ 太大则正则化过度,会导致欠拟合(高偏差),如下图:
hθ(x)=θ0+θ1x+θ2x2+θ3x3+θ4x4J(θ)=12m∑mi=1(hθ(x(i))−y(i))2+λ2n∑nj=1θ2j![]()
那么我们应该如何选择参数 λ 呢?请注意, Jcv(θ),Jtest(θ) 的定义都不包含正则化项。
为了选择模型和正则化参数 λ ,我们可以执行以下步骤:
- 创建要尝试的 λ 值列表
i.e.λ∈{0,0.01,0.02,0.04,0.08,0.16,0.32,0.64,1.28,2.56,5.12,10.24}- 创建不同多项式次数或变量的模型
- 遍历 λ 值,对于每一个 λ 值,遍历不同的模型求出对应的参数 Θ
- 利用学到的参数 Θ 值,求出对应的 Jcv(Θ) (不包含正则化 或 λ=0 )
- 选出使交叉验证集误差最低的组合
- 将上一步中选出的最佳组合 Θ 和 λ ,应用于测试集,求出 Jtest(θ) (不包含正则化 或 λ=0 ),检验其泛化能力
下面给出 Jtrain(θ) 和 Jcv(θ) 随 λ 的变化曲线:
![]()
该图的左边对应着高方差的情况,即 λ 小,拟合出的 Θ 参数较大,可能会过拟合, Jtrain(θ) 小, Jcv(θ) 大;
右边对应着高偏差的情况,即 λ 大,拟合出的 Θ 参数很小,可能会欠拟合, Jtrain(θ) 和 Jcv(θ) 都较大。
4.3 学习曲线 Learning Curves
上面我们使用画曲线图的方法研究了是否存在高方差/高偏差问题,以及正则化对偏差/方差的影响,这种曲线图我们称为学习曲线。
学习曲线可以用来判断某个算法是否处于偏差、方差问题或者二者都有。
4.3.1 训练集大小对 Jtrain(θ) 和 Jcv(θ) 的影响
如下图所示例子:
![]()
对于训练误差 Jtrain(θ) ,当只有几个数据训练算法时(例如1、2、3),我们很容易就可以得到零误差,因为我们总能找到一条二次曲线与它们完美拟合。但是随着数据的增加,二次曲线的误差就会越大,经过一定的 m 值以后,误差就会趋于稳定。
对于交叉验证误差
Jcv(θ) ,当训练集大小 m 很小时,拟合出的假设函数泛化到新样本的能力很差,交叉验证误差就很大,随着训练集不断增大,可能会拟合出更好的假设函数,泛化到新样本的能力增强,交叉验证误差会逐渐减小。4.3.2 高偏差情况下的学习曲线
当训练集大小
m 很小时,拟合出的直线泛化到新样本的能力很差,交叉验证误差 Jcv(θ) 很大,但因为训练集很小,对于每个样本的拟合效果较好,训练误差 Jtrain(θ) 也较小;随着训练集不断增大,训练出的直线更好的适应训练集,泛化到新样本的能力略有增强,交叉验证误差 Jcv(θ) 稍有减小, m 大到一定值之后,训练出的还是一条差不多的直线,交叉验证误差
Jcv(θ) 将不再变化,成为水平的。训练集不断增大,对于训练样本的拟合就没那么准确了,故训练误差 Jtrain(θ) 会持续增大直到接近交叉验证误差 Jcv(θ) 。由此可以看出,高偏差时,随着训练集不断增大,最终 Jtrain(θ) 和 Jcv(θ) 都较大。
意义:高偏差(欠拟合)时,增加训练数据是没有用的,因为 Jcv(θ) 稍微降低后就变为水平。
4.3.3 高方差情况下的学习曲线
![]()
当训练集大小 m 很小时,因为存在过拟合,训练误差
Jtrain(θ) 会非常小,同时过拟合的存在使假设函数泛化到新样本的能力不足,交叉验证误差 Jcv(θ) 很大 ;随着训练集不断增大,想要完美拟合所有训练数据变得没那么容易,训练误差 Jtrain(θ) 会稍微增大,但因为 hθ(x) 的阶次很高,仍然存在过拟合,总体来说 Jtrain(θ) 还是很小的。训练集增大让交叉验证误差 Jcv(θ) 有减小的趋势,但因为过拟合依然存在,故 Jcv(θ) 只是稍微减小,仍然较大, Jcv(θ) 与 Jtrain(θ) 间还是有很大差距。
意义:高方差(过拟合)时,增加训练数据可能会有用,因为随着训练数据增多 Jcv(θ) 与 Jtrain(θ) 越来越接近。
总而言之,学习曲线能让我们发现是否存在高方差/高偏差问题,以及采取某些手段(如:增加训练样本数)是否有意义,避免我们在调试学习算法时浪费时间。
五、总结
我们再来看第一部分的问题,对于提出的一些改进算法的方法,我们应该能分析出它们适用的情况:
- 获取更多训练样本(高方差)
- 尝试使用更少的特征(高方差)
- 尝试增加特征(高偏差)
- 尝试加入多项式特征(高偏差)
- 尝试减小 λ (高偏差)
- 尝试增大 λ (高方差)
下面我们来分析一下神经网络
![]()
简单的神经网络参数少,容易欠拟合,但优势是计算量小;复杂的神经网络参数多,容易过拟合(可以通过正则化修正),计算量大,即使选择了使用复杂的神经网络还要继续选择是使用一个隐藏层还是多个隐藏层等等。
通常使用正则化的复杂神经网络的效果比使用简单神经网络的效果更好,具体实现时要靠考虑时间代价和计算复杂度代价等等。