提升学习算法性能
在解决一个机器学习问题时,如果算法效果不理想,要怎么办呢?直觉上,我们可以有一些解决方法:
- 增加训练数据
- 减小特征集
- 增加特征
- 增加多项式特征
- 减小\(\lambda\)
- 变大\(\lambda\)
- …
然而,这些方法并不是在所有情况下都适用的,有时候,花很多时间增加训练数据也许根本不能使分类结果变得更好。因此,我们需要使用一些简单的技巧来选择使用哪些方法,这样的技巧被称为机器学习诊断(machine learning diagnostics)
。
评估假设函数
在解决一个机器学习问题时,我们往往会选择不同的模型来训练学习算法,然后评估比较其效果。那么怎样的评估是正确有效的呢?一个常用的方法是,将数据集分为三部分:
- 训练集(60%):使用训练集计算每一个模型的优化参数\(\Theta\);
- 交叉验证集(20%):使用验证集计算每个模型的误差,选出误差最小的模型;
- 测试集(20%):使用测试集计算误差最小模型的
通用误差(generalization error)
。
注意:设置交叉验证集的目的是将验证集误差与测试集误差区分开来,使得测试集误差可以作为通用误差的评估依据。我们在选择模型时针对验证集做了优化(因为选的是最小误差的验证集),因此验证集误差是会小于测试集误差的。
机器学习诊断
诊断高偏差和高方差
- 高偏差(欠拟合):\(J_{train}(\Theta)\)和\(J_{CV}(\Theta)\)都会很大,且\(J_{CV}(\Theta) \approx J_{train}(\Theta)\);
- 高方差(过拟合)::\(J_{train}(\Theta)\)会很小,\(J_{CV}(\Theta)\)会远大于\(J_{train}(\Theta)\)。
例如下图:
正则化系数\(\lambda\)选择不合理也可能导致欠拟合或者过拟合,因此\(\lambda\)可以和不同模型组合在一起进行实验选择:
- 创建一组\(\lambda\);
- 创建一组假设函数;
- 迭代学习每个\(\lambda\)与假设函数组合的\(\Theta\);
- 对每一个\(\Theta\)计算验证集上的错误率(计算错误率不加入正则项);
- 选择误差最小的组合;
- 计算测试集误差来评估它是否有好的通用性。
学习曲线(Learning Curves)
学习曲线是错误率随训练集大小的变化而变化的曲线,可以用来诊断欠拟合和过拟合问题。
在高偏差的时候
- 训练集小:\(J_{train}(\Theta)\)小,\(J_{CV}(\Theta)\)大;
- 训练集大:\(J_{train}(\Theta)\)和\(J_{CV}(\Theta)\)都很大,且\(J_{CV}(\Theta) \approx J_{train}(\Theta)\)。
当出现高偏差的时候,加大训练集并不能带来多大的帮助:
在高方差的时候
- 训练集小:\(J_{train}(\Theta)\)小,\(J_{CV}(\Theta)\)大;
- 训练集大:\(J_{train}(\Theta)\)随着训练集增大而变大,\(J_{CV}(\Theta)\)随着训练增大而变小,但不会趋于平缓,且\(J_{CV}(\Theta) < J_{train}(\Theta)\)并差距依旧明显。
当出现高方差的时候,加大训练集可能会提高性能:
处理方法小结
- 增加训练数据 <– 高方差
- 减小特征集 <– 高方差
- 增加特征 <– 高偏差
- 增加多项式特征 <– 高偏差
- 减小\(\lambda\) <– 高偏差
- 变大\(\lambda\) <– 高方差
特别的,对于神经网络:
- 较低阶的多项式(模型复杂度低)可能导致高偏差和低方差。在这种情况下,模型拟合结果差;
- 较高阶的多项式(模型复杂度高)拟合训练集非常好,拟合测试集非常不好,导致训练数据上的低偏差和高方差。
- 实际上,我们希望达到两者之间的状态,即在拟合数据好的情况下也保证通用性好。
一般化流程
一般来说,解决机器学习问题的推荐方法是:
- 从一个简单的算法开始,快速实现,尽早在验证集上测试看一下效果;
- 画出学习曲线来决定是否要增加数据、特征等;
- 进行实验,计算验证集误差,尝试找出大部分错误的来源趋势。
在选择使用的特征和模型时,始终要考虑两个问题:
Q1. 如果是人类专家来根据这些给出的特征进行预测,Ta能不能做出有效判断?即,使用的特征是否含有足够的有效信息;
Q2. 使用的模型是否具有足够的复杂度来解决这个问题?多参数的复杂算法和大的训练数据集相结合可以有效解决高偏差问题,同时不至于带来高方差。
偏态数据(skewed data)
当训练数据中正负例数量非常不均衡时,比如正例远远少于负例(检测癌症患者的实验中,患病者的数目远远少于未患病者的数目),这样的数据就叫做偏态数据(skewed data)
。
在遇到偏态数据时,只使用正确率(accuracy)
作为误差评估指标(error metrics)
是不合适的,因为这可能会导致明显错误的选择。比如,在诊断是否患该症的问题中始终得到不患病的结果可以得到很高的正确率,但这样的诊断方式是显然不对的。
所以,需要有新的指标来衡量算法效果。常用的有精确度(Precision)
和查全率(Recall)
。
定义混淆矩阵如下:
实际值1 | 实际值0 | |
---|---|---|
分类值1 | Ture Positive | False Positive |
分类值0 | False Negative | Ture Negative |
$$\begin{align} Precision = \frac{True Positive}{Ture Positive + False Positive} \newline \newline Recall = \frac{True Positive}{Ture Positive + False Negative}\end{align}$$
使用精确度和查全率可以有效消除单独使用正确率带来的偏态数据处理不当问题。
但是,这样带来的另一个问题是,有了多个衡量性能的标准。而我们知道,有一个单独的实数作为误差评估指标
(A single real number evaluation metric)是非常重要且必要的。同时,为了权衡精确度和查全率(设置分类阈值),可以使用F1 Score
来作为误差评估指标:
$$\begin{align} F_1 Score = 2\frac{Precision\times Recall}{Precision+ Recall}\end{align}$$