机器学习笔记|第六周

运用机器学习建议

决定下一步做什么?

当你的模型运用于新的样本时,如果产生巨大的误差该怎么办?

一般来说,有以下几种处理方式:

  • 获得更多的训练样本——通常是有效的,但代价较大,下面的方法也可能有效,可考虑先采用下面的几种方法。
  • 尝试减少特征的数量
  • 尝试获得更多的特征
  • 尝试增加多项式特征
  • 尝试减少正则化程度$\lambda$
  • 尝试增加正则化程度$\lambda$

当然我们不可能随机去一个个方法尝试,所以需要一点手段来预测。

评估假设函数

首先,如果你计算出的误差(代价函数值)非常大,那么选取的假设函数就可能存在问题;即便误差小,也有可能引起过拟合。

那么如何来判断过拟合问题?

可以将数据集按比例划分成,训练集(Training set):测试集(Test set)=70:30。

AqXOCq.md.png

然后将训练集得到的模型运用于测试集,用来计算误差:

1.对于线性回归模型,我们直接计算ALnxt1.png

2.对于逻辑回归模型,除了计算代价函数AL18fA.png

更常见的方法是计算误分类的比例(0/1错误分类度量)AqjGxf.png

模型选择和交叉验证集

当模型确定的时候可以使用上一节的方法来验证,但是如何确定一个模型呢?首先需要知道,正则化惩罚项系数$\lambda$的选择;增加多项式特征时,多项式的次数等这类问题,称为模型选择问题。

假设我们的输入特征只有一个时,拟合效果是非常不理想的。因此,我们通常会增加特征项,那么问题又来了,多项式特征的次数应该怎么选取,即到底选取什么样的模型(假设)?

我们可以罗列出多种情况

AqvWX8.md.png

这时再将数据集划分成训练集和测试集,对这些假设分别在训练集上训练,通过最小化训练集的代价,求出最优参数$\Theta_{1}$~$\Theta_{10}$。将其代入测试集,计算每个模型的误差,选择误差最小的那组作为假设,并把这组的误差值作为泛化误差。

然而其中存在一个问题:通过测试集来选取模型,又用测试集来求泛化误差,显然是不是坠吼滴。

因此,我们重新划分数据集的比例,训练集:交叉验证集(Cross Validation set):测试集=60:20:20

Aqzdde.md.png

然后计算选择出模型:

1.用训练集训练出$\Theta_{1}$~$\Theta_{10}$;

2.用交叉验证集计算出最小误差,选择误差最小的模型;

3.用第2步中选择的模型计算测试集得出泛化误差。

Train/validation/test error

Training error:

EVNxVs.png

Cross Validation error:

EVUS5q.png

Test error:

EVUCGV.png

上面说到的,是关于如何改变特征来减小误差,而接下来的内容则和正则化$\lambda$有关

诊断偏差和方差

当运行结果不理想时,多半有两种情况:过拟合或者欠拟合。而这两种情况,哪种和高偏差有关?哪种和高方差有关?还是都有关系?

ALkcV0.md.png

从图中可以看出,欠拟合时高偏差,过拟合时高方差。那么在没法画图的情况下(基本都是这种情况)如何来确定是高偏差还是高方差呢?

方法如下:

ALAvkV.png

将训练集误差和验证集误差绘制在图中,其中横坐标为多项式次数。

Training error: EVUP2T.png

Cross Validation error: EVUkMF.png

可以明显看出

  • 对于训练集,d越大,误差越小
  • 对于验证集,随着d增长,误差会先减小后增大,其中的最低点就是开始过拟合的情况。

那么当我们在没有图像的情况下,得出验证集误差较大时,只需要根据训练集误差的大小就能得出是高偏差还是高方差了。

ALE10I.md.png

具体来说,就是:

  • 训练集误差和交叉验证集误差近似时:偏差/欠拟合
  • 交叉验证集误差远大于训练集误差时:方差/过拟合

正则化和偏差、方差

正则化常常用来解决过拟合问题,但是对于正则化项参数$\lambda$,如下图所示不同的选取可能会导致不同的偏差问题,那么应该如何选择合适的值呢?

AL8954.md.png

我们先选择一系列想要测试的$\lambda$,通常是0~12之间呈现2倍的关系,例如:$0,0.01,0.02,0.04,0.08,0.15,0.32,0.64,1.28,2.56,5.12,10$(共12个)。

再像之前那样,把数据集划分为训练集、验证集和测试集。但是因为之前我们都是不带正则化,所以$J(\theta)$和$J_{train}(\theta)$是一样的,但是这里就要如下图中的那样分开。

AL8MPH.md.png

先在训练集上用最小化代价函数,求得最优的一组参数。然后再用该参数在训练/验证/测试集上根据公式计算相应误差。

(这里存疑?关于$J(\theta)$和$J_{train}(\theta)$什么时候使用)

ALJn9H.md.png

具体步骤如下:

1.先对每个$\lambda$值,求对应最小化代价函数的参数

ALJ0uq.png

2.将上述求得的参数,代入交叉验证集计算代价函数$J_{cv}(\theta)$,选择对应最小代价函数的$\theta$作为最优模型参数。

3.代入测试集$J_{test}(\theta)$计算泛化误差。

还可以把验证集误差和训练集误差绘制成图,横坐标为$\lambda$。

ALw9I0.md.png

可以看出:

  • 当$\lambda$较小时,$J_{train}(\theta)$值较小,$J_{cv}(\theta)$值较大,过拟合
  • 当$\lambda$较大时,$J_{train}(\theta)$值较大,$J_{cv}(\theta)$值较大,欠拟合

学习曲线

学习曲线是一个非常好的工具,用于判断模型偏差、方差问题。它是一个以样本个数为横坐标,以误差为纵坐标绘制的图像。

1.如何利用学习曲线识别高偏差?

AL2J9s.md.png

从图中可以看出,对于欠拟合而言,增加样本个数没有意义,因为模型拟合能力差,没有能力去关注”细节“。

AL2wHU.png

从这张图中也可以看出,当样本到达一定数量时,训练集合测试集的误差会非常接近且不再变化,但高于我们期望的误差。

如何利用学习曲线识别高方差?

ALfbvR.md.png

可以看出在过拟合情况下,增加数据,可能可以提高算法效果。

ALh3q0.png

增加样本个数会小幅度提高训练集误差,但是始终维持在一个相对较低的水平。而验证集个数增加为增进模型对数据的了解,因此会验证集误差会减小

上面的test error和cross validation error用哪个效果都一样。

决定下一步做什么?

如何通过这些诊断法来帮助我们选择改进模型的方法呢?回到最初的问题上

  1. 获得更多的训练样本——解决高方差
  2. 尝试减少特征的数量——解决高方差
  3. 尝试获得更多的特征——解决高偏差
  4. 尝试增加多项式特征——解决高偏差
  5. 尝试减少正则化程度λ——解决高偏差
  6. 尝试增加正则化程度λ——解决高方差

神经网络

AOn2b4.md.png

使用神经元较少的神经网络(左图)跟参数较少时情况类似,容易导致高偏差和欠拟合;同理,神经元较多(右图)这容易导致高方差,可以使用正则化手段来解决。

一般使用神经元较多的情况比较好处理。当然你也可以同样把数据集划分为训练集、交叉验证集和测试集。然后从一层隐藏层开始逐一尝试。找到验证集误差最小的作为模型。

机器学习系统设计

确定执行的优先级

以建立一个垃圾邮件分类器为例

step1.用向量表示邮件

输入变量x为邮件的特征;y表示邮件的标签,1代表垃圾邮件,0代表不是。

我们可以人工选择100个单词作为词典,然后比对邮件中单词是否出现,出现则记为1,未出现记为0(注意不是记录出现个数),因此能够得到下图中的100维向量,这个向量作为输入。

EV3bgH.md.png

实际上,我们不会人工选择单词构成字典,而是在训练集中自动选择出现频率最高的n(10000-50000)个单词构成字典,然后用一个n维的特征向量来表示邮件。

step2.想办法降低分类的错误率

1.收集更多的训练数据,但这种要视情况而定。

2.为每个邮件设计更复杂的特征,比如把邮件正文标题也考虑进去

3.为邮件的正文设计更复杂的特征,比如单词的单复数,discount和discounts是否应该看成一个单词;首字母大小、后缀,deal和Dealer是否应该看作一个单词;是否应该考虑标点符号,可能垃圾邮件中叹号会比较多。

4.构建更复杂的算法来检测邮件中的错误拼写,比如垃圾邮件发送者经常把一些容易被检测到的单词写错,如m0rtgage,med1cine,w4tches等,从而避免被检测到。

当然上述方法如何选择,同样也是个问题。

误差分析

当你准备好构建一个机器学习系统时,最好的方式是先用简单的方法快速实现。具体来说:

1.从一个简单的能快速实现的算法开始,实现该算法并用交叉验证集数据测试。

2.绘制学习曲线,判断是高偏差或是高方差,决定是增加更多的数据还是添加更多的特征。

3.误差分析:人工观察交叉验证集,看看被分错的样本是否具有某些规律。

  • 举个误差分析的例子:

假设验证集有500个样本,$m_{cv}=500$,分类器分错了100个样本,此时可以人工检查这100个错误:首先分析这100个样本的错分类型和数量。如下所示:

EVYC8O.png

卖药的邮件12封,卖假货的邮件4封,钓鱼的邮件53封,其他的31封;那么我们就可以把关注点放在钓鱼邮件上。

然会继续对钓鱼邮件分析,是否可以发现一些新的特征。能够提高分类器的的性能,比如这些钓鱼邮件存在以下几个问题:

EVYArd.png

我们又可以把关注点放在“不常用的标点”这一项上,毕竟有32封邮件都存在该问题,进而设计一些包含标点的更复杂的特征,以此提高性能。

  • 数值评估:

在做垃圾邮件分类时,可能会遇到这种问题:

应不应该把discount,discounts,discounted,discounting看作是同一个单词,即是否看成一个特征。

在自然语言处理中会使用词干提取,在这种情况下,上述单词会被看作是同一个。但是词干提取有利有弊,这种方法通常指关注前几个字母,比如它可能会把universe/university看作一个单词,这显然不合理。

那么我们到底要不要使用词干提取?这时我们可以使用数值评估的方法:

首先使用词干提取,训练一个分类器,在验证集上计算它的错误率;然后不使用词干提取,训练一个分类器,在验证集上计算它的错误率。二者进行比较,哪个错误率低,就使用哪种方法。

类似的这种问题,还包括是否应该区分单词大小写,如mom和Mom是否应该看作一个单词,都可以使用上述数值评估的方法,选择一个合理的做法。

不对称分类的误差评估

我们通常用错误率/正确率来评估一个算法,但有时这种方法是不合适的,比如偏斜类问题。

EEHJrF.md.png

以这个判断肿瘤恶性/良性的分类器为例,如果分类器错误率为1%,而实际只有0.5%的病人肿瘤为恶性。这种情况下,尽管错误率看起来非常低,也可能造成严重后果。此时哪怕直接把所有病人都认为良性,也只有0.5%的错误率,高于分类器。

这就是偏斜类问题,情况表现为训练集中同一种类样本非常多,而其他类样本样本比较少。

那么如何解决偏斜类问题?换句话说,如何知道算法把所有病人都认为良性而没有做出真正的分类?

可以使用查准率(Precision)和召回率(Recall)。

召回率又可以叫做查全率,事实上叫查全率显然更符合其含义

我的理解,查准率指预测正确的样本个数占样本总数的多少;查全率指预测正确的样本个数占实际正确的样本个数。

还是以上面肿瘤的例子

EELpE4.png

准确率等于True positive除以一行;

召回率等于True positive除以一列;

由此可以看出,当使用y=0(把所有病人判断为良性)的方法预测时,召回率为0,由此可以排除。

查准率和召回率的均衡

在肿瘤例子中,我们一般情况下设置分类的阈值为0.5。

EEzys1.png

  • 我们可能需要在非常准确的情况下,才去预测肿瘤为恶性,否则让良性肿瘤的病人去接受治疗,那肯定要被骂,因此这时候我们需要高查准率,因此可以调高阈值为0.7或0.9,可以更准确的预测出恶性肿瘤。但此时明显,召回率就被降低了
  • 但召回率的降低可能导致更多恶性肿瘤的情况被归类为良性肿瘤,这种情况也是我们不愿见到的,因此我们也可能想调高召回率。

由此可以画出查准率和召回率的图像:

EVPm4K.png

综上,我们需要向办法设置合适的阈值,以达到查准率和召回率的平衡。

通常使用$F_{1}score$来权衡,计算公式为${ {F}_{1} }Score:2\frac{PR}{P+R}$,$F_{1}score$值越高,模型的性能越好。

机器学习数据

之前曾经说过,不要盲目的收集大量训练数据。

但是有些时候,收集大量数据会得到一个性能良好的学习算法。

即当你的算法有很多参数,数据特征充足(当一个人类专家拿到输入x时,能做出良好的判断,证明特征充足)时,更多的训练数据会带来更好的性能。

参考资料

[1] 机器学习 | 吴恩达机器学习第六周学习笔记

[2] 机器学习笔记(3)—— 优化,偏差和方差,偏斜数据 - 关右的文章 - 知乎

-------------End-------------
梦想总是要有的,万一有人有钱呢?