误差分析可以更系统地做出决定。如果你准备研究机器学习的东西或者构造机器学习应用程序,最好的实践方法不是建立一个非常复杂的系统、拥有多么复杂的变量,而是构建一个简单的算法。这样你可以很快地实现它。研究机器学习的问题时,会花一天的时间试图很快的把结果搞出来。即便效果不好,运行得不完美,通过交叉验证来检验数据,一旦做完,就可以画出学习曲线。通过画出学习曲线以及检验误差来找出算法是否有高偏差和高方差的问题,或者别的问题。在这样分析之后,再来决定用更多的数据训练,或者加入更多的特征变量。这么做的原因是刚接触机器学习问题时,这是一个很好的方法。因为我们并不能提前知道是否需要复杂的特征变量、或者更多的数据,还是其他。提前知道做什么是非常难的,因为缺少证据,缺少学习曲线。因此,如果不这么做,我们很难知道,应该把时间花在什么地方来提高算法的表现。但是当我们实践一个非常简单即便不完美的方法时,我们可以通过画出学习曲线来做出进一步的选择。我们可以用这种方式来避免一种,电脑编程里的过早优化问题。这种理念是我们必须用证据来领导我们的决策,怎样分配自己的时间来优化算法,而不是仅仅凭直觉,凭直觉得出的东西一般总是错误的。除了画出学习曲线之外,还有一件非常有用的指标是误差分析。当我们在构造分类器时,比如垃圾邮件分类器,通常会看一看交叉验证数据集,以及哪些邮件被算法错误地分类。因此,通过这些被算法错误分类的垃圾邮件与非垃圾邮件,可以发现某些系统性的规律,比如什么类型的邮件总是被错误分类。这个过程能启发我们构造新的特征变量或者告诉我们现在这个系统的短处,然后启发我们如何去提高它。
这里有一个构造垃圾邮件分类器的例子。假设在这个例子在交叉验证集中,该算法有非常高的误差率。它错误分类了一百个交叉验证实例。我们要做的是人工检查这100个错误,然后手工为它们分类。基于例如这些是什么类型的邮件,哪些变量能帮助这个算法来正确分类它们。通过检查这一百封错误分类的邮件,会发现最容易被误分类的邮件。可能是有关药物的邮件,或者卖仿品的,或者一些骗子邮件,又叫做钓鱼邮件等等。数一数被错误分类的邮件,比如,在这100封错误归类的邮件中,有12封错误归类的邮件是和卖药有关,4封是推销仿品的,推销假表或者别的东西,有53封邮件是钓鱼邮件,诱骗你告诉他们密码,剩下的31封别的类型的邮件。通过算出每个类别中不同的邮件数,可能会发现该算法在区分钓鱼邮件的时候,总是表现得很差,这说明我们应该花更多的时间,来研究这种类型的邮件,然后看一看是否能通过构造更好的特征变量,来正确区分这种类型的邮件。同时我们要做的是,看一看哪些特征变量,可能会帮助算法正确地分类邮件。假设能帮助我们提高邮件分类表现的方法是检查有意的拼写错误、不寻常的邮件路由来源,以及垃圾邮件特有的标点符号方式,比如很多感叹号。与之前一样,手动地浏览这些邮件。假如交叉验证中,有意地拼写错误出现频率较少,说明这并不值得我们花费时间去编写算法来检测这种类型的邮件。但是如果我们发现很多的垃圾邮件,都有不一般的标点符号规律,那么这是一个很强的特征,说明我们应该花费时间去构造基于标点符号的更加复杂的特征变量。因此,这种类型的误差分析,是一种手动检测的过程。检测算法可能会犯的错误,这经常能够帮助我们找到更为有效的手段。这也解释了为什么推荐先实践一种快速即便不完美的算法。我们真正想要的是找出什么类型的邮件是算法最难分类出来的。对于不同的算法,不同的机器学习算法,它们所遇到的问题一般总是相同的,通过实践一些快速即便不完美的算法,能够更快地找到错误的所在,并且快速找出算法难以处理的例子,这样就能集中精力在这些真正的问题上。
最后,在构造机器学习算法时,另一个有用的小窍门是保证有一种数值计算的方式来评估机器学习算法。数值化能准确的告诉你,算法到底表现有多好。比如下面的例子。假设我们试图决定是否应该把像"discount""discounts""discounter""discountring”, 这样的单词都视为等同。一种方法是检查这些单词开头几个字母。比如当你在检查这些单词开头几个字母的时候,你发现这几个单词可能有着相同的意思。在自然语言处理中,这种方法是通过一种叫做词干提取的软件实现的,可以在网上搜索一下”Porter Stemmer(波特词干提取法)”。 这是在词干提取方面,一个比较不错的软件,这个软件会将单词"discount""discounts"以及等等都视为同一个单词。但是这种词干提取软件,只会检查单词的头几个字母。这样也可能会造成一些问题。举个例子,这个软件会把单词"universe(宇宙)” 和"university(大学)” 也视为同一个单词。因为这两个单词开头的字母是一样的。因此当你决定是否使用词干提取软件用来分类,是很难说清楚。特别地,误差分析并不能帮助你决定词干提取是不是一个好的方法。与之相对地,最好的方法来发现词干提取软件,对你的分类器到底有没有用。为了这么做,通过数值来评估算法,是非常有用的。具体地说,通过交叉验证,来验证不用词干提取与用词干提取的算法的错误率。假设,如果不在算法中使用词干提取,得到5%的分类错误率,然后你再使用词干提取来运行算法,得到3%的分类错误,那么这很大的减少了错误发生。说明词干提取是一个好的办法。就这个特定的问题而言,这里有一个数量的评估数字,即交差验证错误率。再说一个例子,假设你在想是否应该区分单词的大小写,比如单词"mom” 大写的"M” 和小写的"m”,它们应该被视作相同的特征变量还是不同的特征变量。如果我们有一种能够评估我们算法的方法,比如不区分大小写最后得到3.2%的错误率。然后我们发现这个表现的较差些。因此当我们在构造学习算法的时候,要尝试很多新的想法,实现出很多版本的学习算法。如果每一次实践新想法的时候,都手动地检测这些例子,去看看是表现差还是表现好,那么这很难让你做出决定到底是否使用词干提取,是否区分大小写。但是通过一个量化的数值评估,你可以看看这个数字,误差是变大还是变小了。你可以通过它,更快地实践你的新想法,它基本上非常直观地告诉你,你的想法是提高了算法表现,这会大大提高你实践算法时的速度。所以强烈推荐在交叉验证集上来实施误差分析,而不是在测试集上。但是还是有一些人会在测试集上来做误差分析。即使这从数学上讲是不合适的。
总结一下,当我们在研究一个新的机器学习问题时,推荐先实现一个较为简单快速,即便不是那么完美的算法。不要担心算法太简单,或者太不完美。尽快地实现算法,当有了初始的实现之后,它会变成一个非常有力的工具来帮助你决定下一步的做法,因为我们可以看算法造成的错误。通过误差分析,看犯了什么错然后来决定优化的方式。另一件是假设有了一个快速而不完美的算法实现,又有一个数值的评估数据。这会帮助我们尝试新的想法。