
1.4 预测分析流程概览
希望前面几节的内容已经激发了你对预测分析的兴趣,也让你了解了预测分析与人工智能、机器学习这些流行术语的关系。本节将对预测分析的技术流程及流程中每一步的连接进行一个高层次的概述。之后的章节会根据这个流程,一步步更详细地展开。
第一步,定义项目问题。之前提到,不同的问题定义会直接导致不同的预测输出,同时也需要不同的训练数据。“我们期待算法回答什么样的问题?”是开始项目前要制订的关键目标。在预测分析中,这个目标的制订格式往往是我们想要预测下个月某件事情发生的可能性,或是想要预测下一周内某个数值的趋势。以下是一些反面的问题定义:“如何能解决供应过剩”“如何推送用户最感兴趣的内容”,我们需要把这些过于笼统的问题分解。例如,与其把“如何能解决供应过剩”这个定义模糊的问题丢给计算机,不如先询问领域专家是什么导致了供应过剩。他们可能会回答,供应量是根据企业预测的需求量增减的,那么问题就出在了企业预测需求量的准确性。我们的问题就变成了“未来一个月内某产品的销量如何?”这是一个预测分析可以回答的、定义清晰的问题,算法只需根据输入的数据输出一个预估值。
想要解决“如何推送用户最感兴趣的内容”这一问题,我们可以改变发问的方式,“从0%~100%,预测某个用户对某个内容感兴趣的程度。”这就变成了一个预测分析可以回答的问题。根据平台内用户数据和内容数据的输入,算法可以输出一个代表“感兴趣可能性”的数值。而后只要对这个数值进行简单的排行,就可以回答原先定义模糊的“如何推送用户最感兴趣的内容”。
问题定义就像是地基,开始接下来的步骤后,重新定义问题的成本会非常大,因此,我们需要在建筑高层之前打下一个经得起推敲的地基。问题定义的诀窍在于,把定义模糊的概念性问题转化成可以用数字回答的具体问题。大多数情况下,用“如何”开头的问题定义都过于模糊。数字是计算机的母语,因此,定义成“下一阶段某数值会有什么样的变化”的问题更容易被计算机解答。预测分析这一学术领域提供给我们大量强大的工具,但就如日常的工具一般,它们只能对特定的问题做工,而我们的工作便是开发创意,把问题定义成可以用到这些强大工具的模样。
为了让本章的内容更具像化,笔者会“回收利用”之前方便面销量的例子。在这个例子中,我们把问题定义成“下一个月方便面的销量会是多少”,就完美符合了这个模板。大多数问题可以被这个模板或其变化式定义,因此在阅读下面步骤时,也可以稍做转变代入其他的例子解读。
当清晰地定义问题后,第二步就可以开始思考:什么样的数据可能对想要预测的数值产生影响?同时也要考虑,在这些可能产生影响的数据中,哪些数据是便于获得的。也许企业本身记录了大量此类数据,如过往交易记录;又也许这些数据存在公开数据库中,例如地区天气记录、节日日期等。如果数据本身不存在而且难以获得,我们就需要衡量这一数据的收益。例如“每一时期方便面购买人群对方便面的满意程度”。想要获得这一信息,可能需要定期发送大量调查问卷,这会花费时间和资金。再例如,有些数据只存在于付费数据库中。对数据成本和收益的衡量也在很大程度上决定了最后输入模型的数据组合。不同于问题定义,我们可能会反反复复地回到数据收集这一步,因此,没有必要把大量的资源花在试图第一次就决定最终的数据组合——花大量资金获取非现有数据,或花大量时间筛掉认为无价值的数据。把筛选和决定是否需要更多数据的任务留给下面的步骤。第一次经过这一步的重点在于,收集所有预估含金量较高、较易获得的数据。
拥有初步数据后,第三步需要对收集到的数据进行初步分析。这个阶段的分析有两个目的:第一,清理数据,去除明显的噪声;第二,了解数据分布和每类数据与预测目标之间的大致关系。
信息缺失属于常见的一类噪声来源。大多数的继续学习模型无法解读存在空缺的数据。在实际应用中,由于收集到的数据不一定完整,我们需要填补空缺数据或放弃某类数据。举个例子,在第二步中,也许我们认为局部温度对预测目标有所影响,因此从公开数据库中下载了某地区的局部温度。我们希望用过去一年的历史数据作为机器学习的训练集,但可惜的是,已知的数据库只能提供过去一个月的温度记录。在这种情况下,局部温度就是一个不完整的信息。由于其空缺量远远大于已知量,往往最好的决定是放弃这一数据。还有一种可能,数据库拥有过去一年的温度记录,但是记录中出现少量空缺。取决于数据保管的方式,这些空缺也许有特殊的含义,也可能完全随机。我们可以查找数据收集方是否对这些空缺做出公开记录,或联系保管方,询问空缺缘由。如果有可以量化的空缺缘由,我们就可以根据这个缘由填补空缺。例如在存储数据时,数据收集方决定删除与前日一样的温度记录,了解到这一细节后,我们可以将空白的数据填补为上一个非空白数值,但如果数据空缺并无可量化缘由,而空缺比例较小,也许收集者每周日休息,因此所有周日的信息都是空缺的,我们可以取每周六的数值填补,或周六与周一的平均值。后面的章节将详细讲解各类噪声,以及如何处理。
初步清理了明显的数据噪声后,下一步就是统计分析。之前提到,为了获取“起决定性因素”的数据,我们可以与领域专家沟通,借助他们的直觉确定收集的数据内容。在机器学习中,不同类型的数据称为不同的特征(feature)。单个特征可能与预测对象有直接的函数关联,也可能需要与其他特征结合才能看出与预测对象之间的关联。通过与专家的初步沟通,我们可以有根据地猜测出一套有效特征。
尽管人为对数据价值的预估可以帮助我们确定有效方向,但这个预估往往或多或少存在误差。回到预测下个月方便面销量的例子,也许人们会认为去年同一时期的销量会起决定性作用,但数据可能会表示,年与年之间的关联并没有我们想象得那么强。在统计分析这一步,预想被完全推翻是一件平常事。人为的直觉推导可能会参考许多领域经验和社会经验,但人脑无法直接从大量的数据中提取信息,因此估算的价值产生了这些误差。换个角度想,如果行业专家可以准确地告诉我们所有有效数据和其应有的权重,那么一定存在一个可以用硬代码写出的逻辑,可以不通过任何机器学习或其他模型进行预测,因此我们用统计分析来量化每个特征与预测对象之间的关系,从而证实或推翻最初的猜测。
这一步的目的在于提取最有效益的特征。在商业应用中,计算力和时间都是宝贵的资源,而企业所用到的数据规模往往需要巨大的计算量和存储。低效益的特征会增加数据纬度、加长计算时间、加大占用存储,从而增加项目成本。同时,低效益的特征对于机器学习的目标来讲相当于噪声。增加低效益特征大多数时候产生的效果不是增加微量的边际收益,而是降低整体收益。你可能会觉得奇怪,这难道不可以用1+0.01=1.01,而1.01>1来类比吗?确实,低效益的定义是正收益低,而不是负收益低。单独看每个低效益特征与预测对象的关联,我们的确可以用某种衡量指标把它们的效益量化作0.01,而把高效益特征的效益量化作1。只不过,在机器学习模型结合这两项信息时,效益之间的运算符并不等价于加法。低效益特征会分散模型的“注意力”,因此降低整体的预测准确度。就像你正在听一节理论物理课,推导公式的同时,教授饶有兴致地讲起了这段公式的相关历史故事。分开来看,公式推导的讲解对于精准掌握这个理论起到高效益,历史故事的讲解可以提升你的兴趣,从而少量地提高你对这个理论的接受能力,但是人脑学习时同时注入这两种讲解,大概率只会令大脑困惑。当然,一个十分优秀的教授和一个适合这种学习方式的大脑也许可以提取微小的收益,这在机器学习中对应着十分合适的输入格式和适合这种格式的模型。在商业应用中,为了提取低效益特征中的微小收益而去开发这样的模型,大多数情况下是不划算的。
经过初步的统计分析和数据清理后,可以开始基础建模了。商业应用不同于学术研究,大多数时候会调用现有的模型包。sklearn(全称scikit-learn)就是一个建立于Python上的丰富的机器学习包,其中包含监督学习(Supervised learning)和无监督学习(Unsupervised learning)中大多可能用到的模型。用户指南如图1.4所示。

图1.4 sklearn用户指南概览
图1.4列举了sklearn现阶段支持的所有与监督学习有关的模块。大多数情况下,经过适合的调参与特征优化,这些包在商业应用中足够提供令人满意的准确率。也可以从左栏方框圈出的部分看到,sklearn不止包含了监督学习,同样也可以被用来做无监督学习、模型选择与评估(Model selection and evaluation)、可视化数据(Visualization)等,其中数据转换(Dataset transformations)模块可以帮助我们清理数据。
作为一个广度较大的库,sklearn对某类模型的优化程度可能不如一些更精专的包。例如XGBoost,就是一个专注优化梯度回升(Gradient boosting)的包。经过初步模型选择后,如果基于树的算法在解决问题中表现优异,可以考虑调用XGBoost进行更深一步的定制和调试。同样,TensorFlow也属于一种精专于神经网络模型的包。比起基于树的算法,神经网络中有更多的调试空间,因此,在TensorFlow的调用中需要手动搭建的结构更多。
第一次进行基础建模时,可以选用少量、有代表性的数据输入模型,加入少量模型调试,然后对几种预选模型进行评估。模型的预选需要对模型优劣有大致了解,这些将在第4章模型选择里深入讲解。取少量数据是为了提高计算速度,在确定较合适的模型前,应该尽量避免在某个模型上花费过量的时间和计算力。而衡量代表性需要回答以下两个问题:当提取部分数据后,用部分数据所分割出来的训练集、评估集和测试集的训练评估结果,是否能大致映射出全部数据分割后得到的训练评估结果?部分数据的分布又是否与整体数据分布相似?例如我们知道,神经网络相比概率模型或基于树的模型来讲,需要更多数据才能发挥它的优势,因此,如果想要通过部分数据对比神经网络模型和概率模型,需要保证筛选的数据量与总集的数据量属于同一个数量级。又或者数据与时间相关,这时可以在总集的所有时间段中各随机选择些许,确保筛选数据不过分集中在某个时间段。
基础建模的目的在于筛选最合适的模型,以低成本广泛搜寻最值得深入调试的模型。这一步也可以提供初步的结果预期,让我们大致了解现有数据对于预测对象的决定性。如果每种预选模型的结果都差强人意,则需要深一步探究我们选择数据的合理性,或问题本身的可预测性。
完成基础建模后,可以在选择出来的最优模型上投入更多的时间和计算力,进行优化。优化这一步包括数据优化和模型优化。数据和模型架构相辅相成,因此,模型优化的过程其实是寻找最优的数据格式与模型架构的配合。优化模型架构的核心是超参数调试(Hyperparameter tuning):在同一架构下尝试不同的模型规格、损失函数等。第5章将详细讲解如何进行模型优化。数据优化包括特征工程、数据规范化、平滑数据等。第6章将详细讲解如何优化数据。
优化的过程中可能会重复之前的步骤,收集新的数据、尝试不同的数据清理方式、重新选择模型等,直到获得满意的结果。
接下来便可以部署一个完整的流程,把模型应用到企业日常中。这个流程需要考虑谁、什么时候、如何触发新的预测,流程维护是否可以长期低成本运营,以及预测接受者是否能轻松理解模型预测的结果。自动化越高的流程维护成本越低。许多时候,随着企业运行,我们需要结合新的数据重新训练模型。在这种情况下,理想的流程应该能够自动获取新数据、重新训练,而后做出相应预测。
部署和维护是预测分析在企业应用中的最后两个步骤。这两步需要结合企业与项目实情操作,其技术点也不在于机器学习,因此将不会在本书中具体讲解。虽然如此,但在搭建模型的时候同时建立起一个模拟流程也是有帮助的:一个模拟的流程部署可以让我们确定项目的可行性,保证每一步所需要的资源都可及时到位。第3章讲解数据泄漏时,可以更清楚地体会到这一帮助。