机器学习-如何有效使用机器学习算法

怎么改进算法

当使用训练好的模型时,新样本输出的数据产生了巨大的误差,如何改进算法的性能。

  • 使用更多的训练样本,但通常来讲并没有什么卵用
  • 尝试选用更少的特征集,来防止过拟合
  • 或许也需要更多的特征集,当目前的特征集对你没有多大用处时,可以从更多的特征角度去收集更多的特征
  • 增加多项式特征
  • 减小正则化中的 $\lambda$ 的值
  • 增大正则化中的 $\lambda$ 的值

我们不应该随机选择上面的某种方法来改进我们的算法,而是运用一些机器学习诊断法来帮助我们知道上面哪些方法对我们的算法是有效的。

怎么评估算法的性能(机器学习诊断法[machine learning diagnostics])

“诊断法”的意思是:这是一种测试法,你通过执行这种测试,能够深入了解某种算法到底是否有用。这通常也能够告诉你,要想改进一种算法的效果,什么样的尝试,才是有意义的。

标准方法

  1. 将所有数据按照 7:3 的比例分成训练集和测试集,使用 $(x_{test}^{(i)},y_{test}^{(i)})$ 表示测试集数据。

    如果所有的数据存在规律或顺序,最好先打乱顺序再按比例分割。

  2. 测试集评估在通过训练集让我们的模型学习得出其参数后,对测试集运用该模型,我们有两种方式计算测试集误差:

    1. 对于线性回归模型,我们利用测试集数据计算代价函数$J_{test}(\theta)$

    2. 对于逻辑回归模型,我们除了可以利用测试数据集来计算代价函数外:
      $$
      J_{test}{(\theta)} = -\frac{1}{m}{test}\sum{i=1}^{m_{test}}\log{h_{\theta}(x^{(i)}{test})}+(1-{y^{(i)}{test}})\log{h_{\theta}(x^{(i)}_{test})}
      $$

误分类的比率,对于每一个测试集样本,计算:

​ 然后对计算结果求平均。

怎么选择模型

通过交叉验证,选择能最好的拟合数据的多项式次数的模型

  1. 定义多个模型,每个模型的次数不同,使用 $d$ 表示模型的多项式最高次数。

  2. 将所有数据按照 6:2:2 的比例分成训练集、交叉验证集和测试集,使用 $(x_{cv}^{(i)},y_{cv}^{(i)})$ 表示验证集数据,使用 $(x_{test}^{(i)},y_{test}^{(i)})$ 表示测试集数据。

    如果所有的数据存在规律或顺序,最好先打乱顺序再按比例分割。

    $m_{cv}$ 表示验证集总数,$m_{test}$ 表示测试集总数。

    同样的,我们能够定义训练集误差 $J_{train}{(\theta)}$、验证集误差 $J_{cv}{(\theta)}$、测试集误差 $J_{test}{(\theta)}$

  3. 使用训练集代入所有模型并通过训练使得最终代价函数 $J(\theta)$ 最小,再使用验证集代入训练后的所有模型来算出$J_{cv}{(\theta)}$,选出能最好的对交叉验证集进行预测的模型($J_{cv}{(\theta)}$ 最小的模型),确定最终模型的最高次数 $d$。

  4. 使用测试集,预测或估计,通过学习算法得出的模型的泛化误差。

最好按比例分出三份不一样的数据,如果只分为两份,让其中一份既作为验证集又作为测试集,并不好。

模型出现问题,是欠拟合还是过拟合

  • 偏差比较大(欠拟合)
  • 方差比较大(过拟合)

高偏差(欠拟合):训练集数据验证集数据 出现的误差都很大时,且两个误差可能很接近或者可能验证误差稍大一点。

高方差(过拟合):训练集数据 出现的误差很小, 验证集数据 出现的误差很大时,且 $J_{cv}{(\theta)} > > J_{train}{(\theta)}$

误差即 $J(\theta)$ $>>$ 远大于

如何选取正则化参数 $\lambda$

之前通过交叉验证后我们已经选择了一个合适的模型,但是我们还没有正则化项。

这次我们仍然通过交叉验证,来进行选择一个合适的正则化参数 $\lambda$ 。

  1. 定义多个正则化参数 $\lambda$,每个模型的$\lambda$不同。

  2. 将所有数据按照 6:2:2 的比例分成训练集、交叉验证集和测试集,使用 $(x_{cv}^{(i)},y_{cv}^{(i)})$ 表示验证集数据,使用 $(x_{test}^{(i)},y_{test}^{(i)})J_{cv}{(\theta)}$ 表示测试集数据。

    如果所有的数据存在规律或顺序,最好先打乱顺序再按比例分割。

    $m_{cv}$ 表示验证集总数,$m_{test}$ 表示测试集总数。

    同样的,我们能够定义训练集误差 $J_{train}{(\theta)}$、验证集误差 $J_{cv}{(\theta)}$、测试集误差 $J_{test}{(\theta)}$

  3. 使用训练集代入所有模型并通过训练使得最终代价函数 $J(\theta)$ 最小,再使用验证集代入训练后的所有模型来算出$J_{cv}{(\theta)}$,选出能最好的对交叉验证集进行预测的模型($J_{cv}{(\theta)}$ 最小的模型),确定最终正则化参数 $\lambda$ 。

  4. 使用测试集,预测或估计,通过学习算法得出的模型的对新样本的泛化能力。

关于学习曲线

从学习曲线,我们能够看出模型面临的是什么问题。

当模型处于高偏差时,误差会趋于水平不会再降,哪怕添加再多的训练集数据模型产生的误差也不会有所改善。

当模型处于高方差时,训练集误差会始终很小,验证集误差会始终很大,但是如果继续增大训练集数据,是能够改进模型的泛化能力的。

因此,画出模型的学习曲线,搞清楚当前算法是否存在高偏差或是高方差,对于改善算法来讲是非常有意义的,我们能够选择是否添加更多的训练及数据来应对问题。

应该采用哪种方法改进算法

  1. 获得更多的训练样本——解决高方差
  2. 尝试减少特征的数量——解决高方差
  3. 尝试获得更多的特征——解决高偏差
  4. 尝试增加多项式特征——解决高偏差
  5. 尝试减少正则化程度λ——解决高偏差
  6. 尝试增加正则化程度λ——解决高方差
1
2
3
4
5
6
7
使用较小的神经网络,类似于参数较少的情况,容易导致高偏差和欠拟合,但计算代价较小使用较大的神经网络,类似于参数较多的情况,容易导致高方差和过拟合,虽然计算代价比较大,但是可以通过正则化手段来调整而更加适应数据。

通常选择较大的神经网络并采用正则化处理会比采用较小的神经网络效果要好。

对于神经网络中的隐藏层的层数的选择,通常从一层开始逐渐增加层数,为了更好地作选择,可以把数据分为训练集、交叉验证集和测试集,针对不同隐藏层层数的神经网络训练神经网络,

然后选择交叉验证集代价最小的神经网络。

误差分析

构建一个学习算法的推荐方法为:

  1. 首先使用简单快速的方式实现算法,然后使用交叉验证集数据验证这个算法。
  2. 绘制学习曲线,决定是增加更多数据,或者添加更多特征,还是其他方式完善算法。
  3. 进行误差分析:人工检查交叉验证集在我们算法中产生预测误差的样本,看看这些样本是否有某种系统化的趋势。

数值评估

误差分析并不总能帮助我们判断应该采取怎样的行动。有时我们需要尝试不同的模型,然后进行比较,在模型比较时,用数值来判断哪一个模型更好更有效,通常我们是看交叉验证集的误差。

通过一个量化的数值评估,我们可以看看这个数字,误差是变大还是变小了,它可以直观地告诉我们:你的想法是提高了算法表现,还是让它变得更坏,这会大大提高我们实践算法时的速度。

类偏斜

类偏斜情况表现为在训练集中同一种类的样本特别多,其他类的样本特别少。

在类偏斜的情况下,模型的准确率的提升并不能说明我们的模型质量得到了提升,比如当我们的模型准确率为98时,我们完善了模型后,把准确率提升到了99%,但是训练集中的99%的数据是属于同一类的,我们并不知道我们的算法究竟是得到了完善还是变成了碰到数据就把它归为99%那一类的撒比算法。

所以我们需要一个不同寻常的评估度量值:查准率召回率。

查准率:预测出的实际结果数量 占 预测结果总数量 的百分比

召回率:预测出的实际结果数量 占 实际结果总数量 的百分比

这两个数字越高,就说明模型质量越好。

查准率和召回率之间的权衡

我们选取的阈值决定了我们最终预测结果的走向是0还是1,所以阈值是影响查准率和召回率的重要因素,那么我们应该选取 $0-1$ 之间哪个数为阈值呢?

不同的阈值对应着不同的查准率和召回率,查准率和召回率都是越高越好,但是我们无法判断究竟查准率 $0.7$ 召回率 $0.3$ 好 ,还是查准率 $0.4$ 召回率 $0.6$ 好 。

这时我们就需要一个评估度量值来综合的考虑两个因素给定一个结果:阈值设为多少合适。

这个评估度量值的计算公式有很多个,我们现在看在机器学习中经常用到的一个:
$$
{F}_{1} = \frac{PR}{P+R}
$$

P 查准率 R 召回率

机器学习的数据

1
2
3
事实上,如果你选择任意一个算法,可能是选择了一个"劣等的"算法,如果你给这个劣等算法更多的数据,那么从这些例子中看起来的话,它看上去很有可能会其他算法更好,甚至会比"优等算法"更好。由于这项原始的研究非常具有影响力,因此已经有一系列许多不同的研究显示了类似的结果。这些结果表明,许多不同的学习算法有时倾向于表现出非常相似的表现,这还取决于一些细节,但是真正能提高性能的,是你能够给一个算法大量的训练数据。像这样的结果,引起了一种在机器学习中的普遍共识:"取得成功的人不是拥有最好算法的人,而是拥有最多数据的人"。

现在假设我们使用了非常非常大的训练集,在这种情况下,尽管我们希望有很多参数,但是如果训练集比参数的数量还大,甚至是更多,那么这些算法就不太可能会过度拟合。也就是说训练误差有希望接近测试误差。
本文结束 感谢您的阅读
坚持原创技术分享,您的支持将鼓励我继续创作!