假设我们需要用一个线性回归模型来预测房价,当我们用训练好了的模型来预测未知数据的时候,发现有较大的误差,我们下一步可以做什么?
我们不应该随机选择上面的方法来改进我们的算法,而是运用一些机器学习诊断法来帮助我们知道上面哪些方法有效。
“诊断法”:这是一种测试法,通过执行这种测试,能够深入了解这种算法到底是否有用。也能告诉你,要改进算法的效果,什么样的尝试,才有意义。
评价假设函数是否过拟合,可以通过画图,然后观察图形趋势,但对于特征变量不止一个的情况,想通过画图来观察,就变得很难甚至不可能。
为了检验算法是否过拟合,通常将数据分成训练集(70%)和测试集(30%),分之前需要对数据进行“洗牌”,使其均含有各种类型的数据。
接下来,一般分为两个步骤:
有两种方式计算误差:
显然越高次数的多项式模型越能够适应我们的训练数据集,但是适应训练数据集并不代表着能推广至一般情况,我们应该选择一个更能适应一般情况的模型。我们需要使用交叉验证集来帮助我们选择模型。
即:使用60% 的数据作为训练集,20%的数据作为交叉验证集,20%的数据作为测试集。
模型选择的方法为:
如果一个算法表现不好,一般分两种情况:偏差比较大(欠拟合),或方差比较大(过拟合)。
将训练集和交叉验证集的代价函数误差与多项式的次数绘制在同一张图表上来帮助分析:
对于训练集,当d 较小时,模型拟合程度更低,误差较大;随着d 的增加,拟合程度提高,误差减小。
对于交叉验证集,当d 较小时,模型拟合程度低,误差较大;但随着d 的增加,误差呈现先减小,后增大的趋势,转折点是模型开始过拟合训练集的时候。
如果我们的交叉验证集误差较大,我们如何判断是方差还是偏差呢?
训练集误差和交叉验证集误差接近时:偏差(欠拟合)
交叉验证集误差远大于训练集误差时:方差(过拟合)
在训练模型时,一般会使用一些正则化方法来防止过拟合。但我们可能会正则化的程度太高或太小,即我们选择的 λ 的值太多或太小。我们在选择 λ 值的时候也需要思考与刚才选择多项式模型次数类似的问题。
我们选择一系列的想要测试的 λ 值,通常是 0-10之间的呈现 2 倍关系的值(如:0,0.01,0.02,0.04,0.08,0.16,0.32,0.64,1.28,2.56,5.12,10,共12个)。我们同样把数据分成训练集、交叉验证集、和测试集。
选择 λ 的方法为:
我们也可以同时将 训练集 和 交叉验证集 模型的 代价函数误差 与 λ的值绘制在一张图上:
学习曲线 判断某一个学习算法是否处于偏差、方差问题。
学习曲线是学习算法的一个很好的合理检验(sanity check)。
学习曲线是将 训练集误差 和 交叉验证集误差 作为 训练集实例数量(m) 的函数绘制的图表。
1、如果是 高偏差(欠拟合)
作为例子,尝试用一条直线来适应下面的数据,可以看出,无论训练集有多么大误差都不会有太大改观:
少量训练数据的时候, Jtrain(Θ) 很低, JCV(Θ) 很高
增加训练数据后, Jtrain(Θ) 和 JCV(Θ) 都较高,且 Jtrain(Θ) ≈ JCV(Θ)
所以,如果算法存在高偏差(欠拟合),增加数据到训练集不会有太大帮助。
2、如果是 高方差(过拟合)
作为例子,我们使用一个非常高次的多项式模型,且正则化非常小,可以看出,当交叉验证集误差远大于训练集误差时,往训练集增加更多数据可以提高模型的效果。
所以,在高方差(过拟合)的情况下,增加更多数据到训练集可以提高算法效果。
在一中,可选的下一步:
1. 获得更多的训练实例 –> 解决高方差(过拟合)
2. 尝试减少特征的数量 –> 解决高方差(过拟合)
3. 尝试获得更多的特征 –> 解决高偏差(欠拟合)
4. 尝试增加多项式特征 –> 解决高偏差(欠拟合)
5. 尝试减少正则化程度λ –> 解决高偏差(欠拟合)
6. 尝试增加正则化程度λ –> 解决高方差(过拟合)
神经网络的方差和偏差:
使用较小的神经网络,类似于参数较少的情况,容易导致高偏差和欠拟合,但计算代价较小使用较大的神经网络,类似于参数较多的情况,容易导致高方差和过拟合,虽然计算代价比较大,但是可以通过正则化手段来调整而更加适应数据。
通常选择较大的神经网络并采用正则化处理会比采用较小的神经网络效果要好。
对于神经网络中的隐藏层的层数的选择,通常从一层开始逐渐增加层数,为了更好地作选择,可以把数据分为训练集、交叉验证集和测试集,针对不同隐藏层层数的神经网络训练神经网络, 然后选择交叉验证集代价最小的神经网络。
这几节中提到的一些技巧,关于方差、偏差,以及学习曲线为代表的诊断法能够真正帮助你更有效率地应用机器学习,让它们高效地工作。
以一个垃圾邮件分类器算法为例进行讨论。如何巧妙构建一个复杂的机器学习系统。
为了解决这样一个问题,我们首先要做的决定是如何选择并表达特征向量 x。我们可以选择一个由 100 个最常出现在垃圾邮件中的词所构成的列表,根据这些词是否有在邮件中出现,来获得我们的特征向量(出现为 1,不出现为 0),尺寸为 100×1。
为了构建这个分类器算法,我们可以做很多事,例如:
我们将在随后的课程中讲误差分析,学习怎样用一个更加系统性的方法,从一堆不同的方法中,选取合适的那一个。
构造一个机器学习应用程序,最好的实践方法不是建立一个非常复杂的系统,拥有多少复杂的变量,而是构造一个简单的算法,这样可以很快地实现它。
构建一个学习算法的推荐方法为:
以我们的垃圾邮件过滤器为例,误差分析要做的既是检验交叉验证集中我们的算法产生错误预测的所有邮件,看:是否能将这些邮件按照类分组。例如医药品垃圾邮件,仿冒品垃圾邮件或者密码窃取邮件等。然后看分类器对哪一组邮件的预测误差最大,并着手优化。
思考怎样能改进分类器。例如,发现是否缺少某些特征,记下这些特征出现的次数。
例如记录下错误拼写出现了多少次,异常的邮件路由情况出现了多少次等等,然后从 出现次数最多的情况开始着手优化。
误差分析并不总能帮助我们判断应该采取怎样的行动。有时我们需要尝试不同的模型,然后进行比较,在模型比较时,用数值来判断哪一个模型更好更有效,通常我们是看交叉验证集的误差。
强烈推荐在交叉验证集上来实施误差分析,而不是在测试集上。
误差度量值,设定某个实数来评估你的学习算法,并衡量它的表现。
类偏斜(skewed classes)表现为我们的训练集中有非常多的同一类的实例,只有很少或没有其他类的实例。
例如我们希望用算法来预测癌症是否是恶性的,在我们的训练集中,只有 0.5%的实例是恶性肿瘤。假设我们编写一个非学习而来的算法,在所有情况下都预测肿瘤是良性的,那么误差只有 0.5%,比我们通过训练而得到的神经网络算法却有 1%的误差还小,这显然是不合理的。这时,误差的大小是不能视为评判算法效果的依据的。
精确率(Precision)和召回率(Recall) 我们将算法预测的结果分成四种情况:
则:
精确率=TP/(TP+FP) ,例,在所有我们预测有恶性肿瘤的病人中,实际上有恶性肿瘤的病人的百分比,越高越好。
召回率=TP/(TP+FN),例,在所有实际上有恶性肿瘤的病人中,成功预测有恶性肿瘤的病人的百分比,越高越好。
这样,对于我们刚才那个总是预测病人肿瘤为良性的算法,其查全率是 0。
Precision=True positives# predicted as positive=True positivesTrue positives + False positives
Recall=True positives# actual positives=True positivesTrue positives + False negatives
Accuracy = (true positives + true negatives) / (total examples)
在很多应用中,我们系统能够保证精确率和召回率的相对平衡。
继续沿用刚才预测肿瘤性质的例子。假使,我们的算法输出的结果在 0-1 之间,我们使用阀值 0.5 来预测真和假。
精确率(Precision)=TP/(TP+FP) 例,在所有我们预测有恶性肿瘤的病人中,实际上有恶性肿瘤的病人的百分比,越高越好。
召回率(Recall)=TP/(TP+FN)例,在所有实际上有恶性肿瘤的病人中,成功预测有恶性肿瘤的病人的百分比,越高越好。
如果我们希望只在非常确信的情况下为真(肿瘤为恶性),即我们希望更高的准确率,可以将使用比 0.5 更大的阈值,如 0.7 ,0.9 。这样做我们会减少错误预测病人为恶性肿瘤的情况,同时却会增加为能成功预测恶性肿瘤为恶性的情况。
如果我们希望提高召回率,尽可能地让所有可能是恶性肿瘤的病人得到进一步地检查,诊断,我们可以使用比 0.5 更小的阈值,如 0.3。
我们可以将不同阀值情况下,精确率与召回率的关系绘制成图表,曲线的形状根据数据的不同而不同:
我们希望有一个帮助我们选择这个阀值的方法。一种方法是计算 F1 值(F1 Score),其计算公式为:
F1Score=2PRP+R
我们选择使得 F1 值最高的阀值。
2001年,两位研究人员 Michele Banko 和 Eric Brill 进行了一项有趣的研究,他们尝试通过机器学习算法来区分常见的易混淆的单词(当做有监督),他们尝试了许多种不同的方法,并发现数据量非常大时,这些不同类型的算法效果都很好。
“劣等的”算法,如果有更多的数据,很有可能会比其他算法更好,甚至会比”优等算法”更好。
像这样的结果,引起了一种在机器学习中的普遍共识:”取得成功的人不是拥有最好算法的人,而是拥有最多数据的人”。
It’s not who has the best algorithm that wins. It’s who has the most data.”
那么这种说法在什么时候是真,什么时候是假呢?什么时候我们会希望获得更多数据,而非修改算法。
大量数据有帮助的情况:
假设特征 x 有足够信息来准确预测 y
例子: For breakfast I ate ____eggs.
上下文有足够的信息可以预测 y
反例:只从面积预测房价。
有用的测试:给出x ,人(领域专家)能自信的预测出 y 吗
即:
学习算法有很多的参数(逻辑回归、线性回归有很多特征,神经网络有很多隐藏层)
使用大量训练集合(不太会过拟合) 训练集误差≈测试集误差,且都较低
有多参数,保证不欠拟合(高偏差)
有大训练集,来保证不过拟合(高方差)