电子说
想必每个人都有这样的经历:当你在学习新事物时,万事开头难,你总会遇到许多未知的因素,并花大量时间去学习、适应新的领域。而随着时间的推移,你在这个领域越来越熟练,也积累了一大堆技巧,想送给当初那个四处碰壁的自己。近日,medium博主Aseem Bansal撰文讲述了自己在构建机器学习管道和使用Apache Spark时的一些经验,希望能帮助入门者节约时间。
谨慎制定预期
和其他任务量巨大、未知的事物一样,我们很难对机器学习项目进展作出时间预估。我们知道自己需要做哪些事来达成目标,但随着工作进行,一些想法会逐渐暴露出缺陷。这时,我们必须接受这个现实,并马上灵活更换方法保证工作计划快速迭代。
项目中会有大量未知数,你需要确保团队能够快速迭代。
在开始前检验数据是否整齐
在我们第一次构建机器学习管道时,团队已经花了大约3年的时间收集原始数据。为了防止中途因为某些意外需要重建数据的分析存储,我们没有对数据做任何调整,只是以.csv的格式把它们放在那里。一开始我们并没有发现这有什么不妥,但随着时间的推移,编写这些文件的代码发生了变化,也出现了不少错误。所以我们不得不一边构建管道,一遍修修补补。直到最后,我们还是在Apache Spark中写代码,清除了所有历史数据。如果我们事先检查了数据整齐与否,不是直到项目进行才发现问题,也许这个过程就不会那么复杂。
在项目开始前,请确保自己的数据是正确的。
对数据进行预处理,对模型进行预训练
为了训练我们的机器学习模型,我们一开始试着加载了所有数据。由于文件大小是TB级的,每次加载完,模型的训练速度就会变得非常慢,这也影响了它的迭代。后来,我们逐渐意识到似乎不用每次都加载所有数据,于是就对数据做了一些预处理并创建了一个更小的数据集,它允许模型调用我们需要的列来进行训练。同时,我们也没有删除原来的数据源,而是把它作为检测的备份资源。
不要混淆ETL和模型训练。如果你需要训练1000个模型,你并不需要做1000次预处理。你只要做一次,然后把数据保存到一个地方,然后把它用来训练模型。
选择权限共享的工具
如前所述,我们把原始数据放在AWS S3中备份,这看起来好像没什么问题,但从数据科学角度来看,这并没有做到真正的共享,因为当需要从S3中提取数据时,只有少数人有访问权。
给一个只读权是远远不够的。人们能不能在笔记本电脑上下载TB级别的数据?强行来说,这是可以的,但在下完数据后笔记本电脑能用它们干什么?不是每个人都会随身携带32核电脑的。要他们未雨绸缪,随时为处理TB级的数据做好准备,这简直是浪费时间。
这时候,我们发现一些支持Apache Spark环境的notebook可以满足基础需求,比如jupyter和zeppelin。如果是一些长期的集群的任务,jupyter的优势更大一些,但由于AWS EMR内置集成,zeppelin可以凭借Amazon EMR群集进行机器学习、流处理和图形分析,所以对于一般用户,zeppelin更甚一筹。
只给人们开放TB级数据的只读权限,并期望他们能做出点什么的想法是荒诞的。你必须先提供正确的工具,别人才能更上一层楼。 对于这个问题,jupyter、zeppelin等笔记本都是我们的明智之选。
大数据必须进行监控
当你处理大数据时,你会发现传统的软件工程方法有时不顶用。普通程序跑一跑也许只要几分钟,但大数据可能要几小时甚至是几天,具体取决于你在做什么以及你是怎么做的。幸运的是,现在不是十年前,我们不再需要等任务全部结束再来思考怎么提高效率。
和传统的软件编程相比,如何减少大数据背景下的批量作业是一个更复杂的问题。通过云,现在我们可以等量减少使用机器的数量,或是缩短训练的总时长,但是面对这些选择,哪一个才是真正的首选?我们可以增加机器数量,可以改变使用的机型,可以采用CPU bound、RAM bound,也可以是network bound、disk bound……在这个分布式环境里,我们的瓶颈在哪里?这些都是我们必须要回答的问题,它们影响项目用时的长短。
对Apache Spark来说,它很难弄清楚需要的机器类型。Amazon EMR带有神经节,让我们一眼就可以监控集群内存/ CPU。但有时我们也不得不去检查底层的EC2实例监测,因为神经节并不完美。只有结合两者,我们才能对比着发现问题。我们发现,执行ETL和训练机器学习模型的任务有不同的配置文件。ETL需要占用大量的网络和内存,而机器学习训练对算力要求更高,所以我们为两者选择了不同类型的方案。
可以通过监控CPU /内存/网络/ IO监控来优化成本。我们找到了EHL和ML对硬件的不同需求。
一开始就对机器学习模型预测实行基准测试
想一想,你对机器学习模型的预测响应时间有没有特殊要求。如果有要求,那你在选择框架前应该先确定该框架能满足你的预期。要知道,基础模型的数学理论是很容易把握的,但如果你向当然地认为模型能按着数学方程迅速给你一个预测结果,那你就错了。
有时候影响预测速度的除了数学模型,还有其他一些奇奇怪怪的因素。而这些坑都需要你先做基准测试进行排查。如果你是在构建完机器学习管道后再做基准测试,你可能会浪费大量时间。
如果你对响应时间有要求,请先利用选择的框架制作一个简单模型,它可以在精度等方面表现不佳,但你可以基于它测试延迟情况。
无论AWS如何显示,S3都不是一个文件系统
当你在使用AWS的GUI或CLI时,你很容易忘记S3不是个文件系统,它只是一个对象存储。如果你不知道什么是对象存储,可以联系Key-value存储类比一下,把里面的value替换成对象,而这个对象可以是json和图像等。
区分这一点很重要,因为在S3中重命名内容并不像在文件系统中那么快。如果你在文件系统中移动了一个对象,它可能很快就好了,这主要取决于你正在调用的内容。但如果是在S3里,你最好不要抱有同样的幻想。
用map、reduce处理数据时,传统的hadoop会产生临时文件,而Apache Spark在把数据写入S3时,会先写入一个临时文件,再把它们移至对象存储,简而言之,就是速度很慢。所以你可以选择存本地,也可以用Apache Spark把临时数据塞内存处理完后直接输出最终结果。
Apache Spark主要是基于Scala的
如果你要用Apache Spark,首先你该知道它主要是基于Scala的。虽然它支持Java和Python API,但它的大多数示例还是围绕scala展开的。
在还没接触过机器学习和scala前,我们用的一直是Java,并且觉得机器学习对我们的项目可能有很大的用处,但是学习scala是不必要的。事实上,我们中也没人想处理scala的学习曲线。这样的考虑主要是为了防止项目出错。但有一次,我们遇到了一个Apache Spark问题,找到解决方案不麻烦,把scala翻译成Java也不麻烦,麻烦的是我们得把Spark Scala翻译成Spark Java,因为Java的API不太好用。
如果你完全不懂scala但又想用Spark Mllib,你可能得向scala妥协。这不是理想的解决方案,但却是实际的解决方案。让它运作,然后把它变得更好。相比找到一种不变的、看似完美的解决方案,学会新的东西并让它发挥作用才更令人开心。
如果这是团队作业,分享知识就十分重要
如果你要把机器学习和现有的其他系统集成在一起,你就不得不需要和其他开发人员打交道。你要联系的对象除了开发者,还有业务人员、操作人员、市场营销人员等。除非你正在从事人工智能方向的产品研发,否则这些人中的大部分不会对AI有太多太深的了解。而因为机器学习是整个解决方案中的一部分,他们也没有时间去进行系统学习,所以知识分享就变得尤为重要了。
你不必教给他们算法和其他专业的东西,但你确实需要向他们解释一些常用的术语,如训练、测试、模型、算法等。
机器学习领域充满大量术语,你可能会忽略这个现实,但对于团队中的其他人来说,这些陌生的词汇会让他们感到困惑。并不是每个人都上过ML课程。
为数据构建版本是个好主意
你可能需要为您的数据构建不同版本的控制方案,让它能在不重新部署整个软件的情况下,切换不同的数据集供模型进行训练。我们之前创建过一个模型,把它放在数据集上训练后,可能是数据不够,它的性能不尽如人意。
为此,我们为数据构建了几个版本的控制方案,当在v1上训练模型时,它会自动生成下一版数据。当有足够数据后,我们就能直接靠切换代码来进行训练。我们还制作了一个UI,能利用它控制机器学习算法的参数,并对某些特定参数进行基本过滤,指定我们想要用于训练的数据量。
全部0条评论
快来发表一下你的评论吧 !