对于一个学习算法,有着各种各样的调试手段,不同的调试手段可以解决不同的问题,需要根据实际情况进行选择。学习算法的问题大致可以分为两类:「高偏差/方差」问题以及「算法优化」问题。
我们先来进一步了解「方差与偏差的权衡问题」。以线性回归为例,我们通过计算测试集的最小二乘误差(MSE)来评价模型的好坏:
如果 MSE 过大,一般可以从以下三个方面进行解释:
假定训练集与测试集中的数据符合同一分布:
对于测试集中的每个样本
,我们对于
的预测为
。现在我们可以通过如下公式计算 MSE(
可以看做关于训练集的随机变量函数):
推导过程利用了
。公式中的第一项为误差项,我们无法预测;公式中的第二项为偏差项,表示平均来看,
没有正确预测
,对应为「欠拟合」;公式中的第三项为方差项,表示
过于接近训练集的输出导致在测试集上偏差较大,对应为「过拟合」。
大部分情况下,减少方差或偏差中的一项意味着增加另一项,因此我们需要考虑好两者之间的权衡。以贝叶斯逻辑回归为例,出现高偏差或高方差的可能解决措施有:
学习算法的另一个常见问题是算法是否收敛。对于这个问题,我们可以考虑如下方式进行调试:假定 SVM 比贝叶斯逻辑回归(BLR)更好,但是你仍然希望采用贝叶斯逻辑回归,令
表示 SVM 学习得到的参数,
表示 BLR 学习得到的参数。我们使用「加权准确率」来评估算法的好坏:
因为 SVM 的表现优于 BLR,所以
。而 BLR 尝试去最大化(即代价函数):
我们可以比较
和
的大小
,那么说明
并没有最大化
,问题出在「算法优化」上
,那么说明
成功地最大化了
,但 SVM 的表现却更好,这表示问题出在「目标函数」上
以贝叶斯逻辑回归为例,出现算法优化问题时的可能解决措施有:
的值」(解决优化目标的选择)
对于一个学习问题来说,通常是由一条流水线组成的,如果发生了误差,我们需要找到哪一部分导致了这一误差。下面通过一个面部识别流水线来介绍误差分析的方法,如下图所示:
该算法可以分为如下几个步骤:
我们可以通过将每一部分的输出替换为完美的结果,来观察哪一部分对结果的准确率贡献最大,如下表所示:
Component | Accuracy |
---|---|
Overall system | 85% |
Preprocess (remove background) | 85.1% |
Face detection | 91% |
Eyes segmentation | 95% |
Nose segmentation | 96% |
Mouth segmentation | 97% |
Logistic regression | 100% |
可以看出,对于面部识别流水线,去除背景的影响并不是很大,而面部识别与眼睛识别对准确率的贡献最大。除了帮助改善算法,误差分析在撰写论文时也很有帮助,它可以用于解释算法的哪一部分应该被提升。
误差分析尝试去解释算法当前的表现与完美表现的差别,而「消融分析」(Ablative analysis)尝试去解释一些基线表现(通常表现更差)与当前表现的差别。
以垃圾邮件分类器为例,你通过在逻辑回归中加入了以下这些有趣的特征获得了不错的结果:
我们可以通过消融分析了解究竟是哪些特征提升了算法性能。消融分析的方法是从最佳表现出发,逐步去除这些特征,观察算法的准确率变化,如下表所示:
Component | Accuracy |
---|---|
Overall system | 99.9% |
Spelling correction | 99.0% |
Sender host features | 98.9% |
Email header features | 98.9% |
Email text parser features | 95% |
Javascript parser | 94.5% |
Features from embedded images | 94.0% |
在论文撰写中,消融分析可以帮助发现那些真正重要的特征(或 trick)。
不要浪费时间在并不会减少你的错误率的部分,专注于真正重要的部分。以一个识别猫的图片为例,你发现数据集中有很多狗的照片,思考是不是应该构建一个专门识别狗的算法来防止误将狗识别成猫的结果出现。
你可以选取验证集中的100个错误分类的样本,看其中为狗图片的比例是多少,如果只有5%,那么即使你研究出了识别狗图片的算法,原来算法的性能也不会有多大提升。
一般开始一个新的学习问题有两种方法: