2.4机器学习应用流程我们已经了解了机器学习的方法,以及这些方法是如何识别模式的。这一节里,我们会学习使用机器学习挖掘数据时该选择或者必须选择哪一套学习流程。每一种机器学习方法都会依据模型参数设置决策边界(Decision Boundary),但是我们不能只关心模型参数。还有另一个非常麻烦的问题,实际上,它也是机器学习长久以来的死穴之一:特征工程(Feature Engineering)。判断从原始数据中可以创建哪些特性,又即分析的主题,是创建一个恰当分类器必须经历的步骤。这一步的过程,与模型参数的调整大同小异,也需要经历大量的试错。某些情况下,特征工程甚至比设定一个参数更加耗费时间精力。因此,在我们简单地提起“机器学习”,准备构建一个分类器处理实际问题时,还需要提前准备完成几个任务。一般而言,这些任务可以概括如下: 确定哪一种机器学习方法适用于你的问题。 确定该采用什么特征进行分析。 确定分析模型的参数设置是什么。只有你完成了这些任务,机器学习才能有实际的用武之地。那么,你怎样才能确定合适的特征和参数呢?怎样才能让机器开始学习?让我们首先看看下图,通过它也许你能够比较容易地了解机器学习的全貌。这是机器学习流程的一个总结:
正如你从前面这幅图中所能看到的,机器学习的学习过程可以粗略划分为两个步骤: 训练 测试实际上,模型的参数在训练阶段中会不断地被修改和调整,机器需要在测试阶段检测模型的效果。我们都知道研究或者实验几乎不可能仅凭一次训练或者一个测试集就能取得成功。我们需要一遍又一遍地重复训练→测试,训练→测试……这样的过程,直到找到正确的模型。让我们依次看下前面的流程图。首先,你需要将原始数据划分为两部分:训练数据集和测试数据集。这里,你需要特别注意的一点是,训练数据集和测试数据集是分离的。让我们举一个例子,这样你能更容易地理解这到底是什么意思:你希望使用历史价格数据,通过机器学习预测S&P 500的每日价格(实际上,使用机器学习作为预测金融证券价格的工具是最吸引人的研究领域之一)。假设你有2001年到2015年的历史股价数据作为原始数据,如果你使用这些数据进行训练,并且也使用同一时段的这些数据同样地进行测试,将会发生什么情况呢?你会发现,即使仅仅使用简单的机器学习,或者特征工程,获得正确预测的概率依旧高达70%,甚至会到80%或者90%。这样一来,你可能会想:这是多么伟大的发现啊!市场实际上就这么简单!现在我就可以成为一个亿万富翁了!不过,这只是个昙花一现的欢喜。现实并不会一帆风顺。如果你在实际投资时也采用这样的模型,不太可能获得预期的收益,并可能因此一头雾水。如果你仔细地思考,稍微留意一下,就会发现其实这很明显。如果训练数据集和测试数据集是完全一样的,你实际上是在使用已经知道答案的数据进行测试。因此,这种测试能获得很高准确率是必然的事,因为你是用正确的答案去预测正确的问题。不过,对测试而言,这没有任何意义。如果你想要对模型进行恰当的评估,请确保使用不同时间区段的数据,譬如,你可以用2001年到2010年之间的数据作为训练数据集,使用2011年到2015年的数据进行测试。这样一来,你使用的就是答案未知的数据,从而能对模型预测准确率有一个恰当的评估。现在,你就能避免在破产的道路上一往无前了,因为你知道并非每笔投资都能赚得盆满钵满。所以,很明显地,你应该将训练数据集和测试数据集分开,不过你也有可能认为这并非一个严重的问题。然而,在数据挖掘的实际场景里,我们经常会在无意识中使用了同样的数据进行试验,所以,请给予这个问题足够的重视。我们在机器学习时就谈论到这一问题,它同样也适用于深度学习。如果你将整个数据集划分为两部分,第一部分数据集应该作为训练数据集。为了得到更为精确的预测率,我们需要为这部分训练数据集创建恰当的特征。这种特征工程一定程度上取决于人的经验或者直觉。为了让选择的特征取得最好的效果,你可能需要花费很长的时间和大量的精力。此外,每一种机器学习方法都有各自的特征数据类型格式,因为每一种方法其模型的理论和公式也各不相同。举个例子,我们有一个模型只接受一个整数,有的模型只接受非负数字/值,还有的模型只接受介于0与1之间的实数。我们再回到前面那个股票价格的例子。由于股票价格会在一个比较大的区间变化,我们很难用一个只接受整数的模型获得比较准确的预测。另外,我们还需要在数据与模型的兼容性方面多下工夫。我们并不是说如果你选择使用股票价格作为特征,就不能采用接受从0开始的所有实数的模型。譬如,如果你将所有股票的价格数据除以一定期间的最高股价,那么其数据区间就介于0到1之间,这样一来,你就可以使用只接受从0到1实数的模型了。所以,如果你稍微调整下数据的格式,还是有机会使用这种模型的。当你考虑特征工程时,请牢记这一点。一旦你创建了特征,决定了选择应用哪一种机器学习方法,就需要对这些进行检查。很显然,机器学习中决定模型精度的重要因素是特征,不过模型自身,或者说算法中的公式也带有一系列的参数,这些参数也对模型精度有影响。调整学习的速度,或者调整机器学习中,可允许的误差数目都是这方面很好的例子。学习的速度越快,它完成计算所花的时间越短,因此我们希望机器学习尽可能地快。然而,学习速度越快,得到的最终解就越粗糙。因此,我们需要留意的是,提高学习速度会导致模型的准确率降低。如果数据中混杂了噪声,调整允许的误差范围也可以提高学习速度。机器判断“数据是否看起来古怪”的标准是人为决定的。当然,每一个方法都有一套独特的参数集。众多的参数中,一个很不错例子是神经网络中应该有多少神经元。另外,当我们谈起支持向量机中的核函数,选择什么类型的核函数是支持向量机特有的参数之一。如上所述,机器学习需要确定很多参数,但是事先很难做到最优。至于如何预先定义模型参数,这有一块专门的研究领域,专注于参数的研究。因此,为了验证哪些组合能返回最佳精度,我们需要测试大量的参数组合。由于一个个的单项测试会消耗大量的时间,标准流程是用不同的参数组合以并行的方式同时对多个模型进行测试,并对测试的结果进行比较。通常情况下,参数应该设置在哪一个区间是确定的,因此在一个合理的时间范围内解决问题就不是一个大问题了。一旦模型通过训练数据集的训练能取得好的准确率,下一步就可以进行测试。测试的大致流程是使用训练数据集上同样的特征、同样的模型参数,检查其准确率到底如何。测试中并没有特别困难的步骤。计算也不会花费大量的时间。这是因为从数据中寻找模式,或者换句话说,优化公式的参数就会带来计算量。然而,一旦参数调整完毕,就可以将公式直接应用于新的数据集。简单而言,执行测试的目的就是为了检查模型是否受训练数据集的影响变得过度优化。这到底是什么意思呢?使用机器学习时,训练集下预测效果很好,但是测试集中表现不佳的模式有两种。第一种情况是由于将无意义的干扰数据混到训练数据集引发了不正确的优化。这可能源于本章前面提到的误差允许范围的调整。我们周遭的数据并不总是干净的。甚至可以这么说,几乎没有任何数据可以被恰当地划分到纯净的模式(Clean Pattern)中。我们再一次提起股票价格的那个例子,它就是一个很好的证明。股票价格通常都在前期股价附近重复式地适度波动,不过,某些时候它们也会突然暴涨或暴跌。这种非常规的变化是没有,或者说是不可能有任何规律的。再举个例子,如果你想要预测一个国家的粮食产量,受异常气候影响的年份的数据与正常年份的数据比起来一定存在很大的差别。虽然刚才所举的都是一些极端的情况,比较容易理解,不过现实世界中的大多数数据都存在着噪声,想要将数据划分到恰当的模式比较困难。如果你仅仅做了训练而没有调整机器学习过程中模型的参数,那么模型就会强行将噪音数据也划分到一个模式中。这种情况下,训练数据集中的数据也许进行了正确的分类,不过由于训练数据集中存在着噪音,它们也进行了分类,而在测试数据集中这些噪音可能并不存在,从而影响测试的预测准确率。第二种情况是只依据训练数据集中特有的数据进行分类而导致的无效优化(Incorrect Optimizing)。譬如,我们考虑设计一款接受英文语音输入的移动应用。为了构建你的移动应用,你应该准备各种词汇的发音数据作为训练数据集。现在,我们假设你已经准备了足够数量的英式英语语音数据,搭建了可以正确分类发音的模型,并且达到了很高的精确度。下一步就是测试。由于是测试,为了采用不同的数据,我们使用美式英语的语音数据。那么,结果如何呢?你可能不会得到比较好的准确率。更进一步,如果你试图让你的应用去识别非英语母语国家人的发音,最终的预测精度可能更低。如你所知,不同地区的人有不同的英文发音。如果你不把这一点考虑在内,只对英式英语训练数据集的模型进行调整,即使你在训练数据集上能达到很好的效果,面对测试数据集时也不会有好的成绩,也无法在实际应用中发挥作用。出现这两个问题的原因是机器学习模型是从训练数据集中学习而来,它过度拟合于数据集了。这一问题应该被称为“过拟合问题(Overfitting Problem)”,你对此应该非常小心,避免出现这种问题。机器学习的困境在于你既要考虑如何避免过拟合问题,与此同时还要完成特征工程。这两个问题——过拟合和特征工程,在一定程度上都是相关的,因为糟糕的特征工程就会落入过拟合的陷阱。要避免过拟合问题,除了增加训练数据和测试数据并没有太多的方法。通常而言,训练数据的数量都是有限的,所以常用的方法是增加测试的数量。一个典型的例子是“K折交叉验证(KFold CrossValidation)”。K折交叉验证中,所有的数据一开始就被划分到K个集合中。接着,其中的一个集合被选为测试数据集,其他K-1个集合作为训练数据集。交叉验证对划分的K个数据集分别做验证,总共进行K次,预测的精确度由这K次验证的结果取平均值确定。最让人担心的事情是训练数据集和测试数据集碰巧都有很好的预测精度,然而发生这种事件的概率在K折交叉验证中减小了,因为测试会进行多次。对过度拟合再怎么谨慎也不算过分,因此仔细验证测试的结果是非常有必要的。现在你已经了解了训练的流程、什么是训练集,以及需要牢记在心的要点。以上两点主要关注于数据分析。那么,举个例子来说,如果你的目的是从已有数据中找出有价值的信息,那你就可以按照这个流程进行操作。另一方面,如果你需要应用可以处理将来的新数据,你还需要额外的流程,使用训练中获取的模型参数以及测试数据集进行预测。譬如,如果你希望从股票价格数据集中找出某些信息进行分析,并据此编写市场报告的话,下一步要做的是进行训练和测试集合。或者,如果你想要依据数据对未来的股票价格进行预测,将其作为一种投资系统的话,你的目标就变成了构建一个应用,其使用由训练获取的模型和测试数据集,基于已有的数据对股价进行预测,并且这些数据每天,或者每隔设置的固定时段都会更新。第二个例子中,如果你想要依据新增的数据更新模型,需要特别的小心,模型的构建需要在下一批数据到来之前完成。