摘要: 一份机器学习过来人的经验清单分享, 主要是包含一些关于构建机器学习工作流以及 Apache Spark 应该注意的一些事项, 希望这个清单能够帮助那些正在学习机器学习的相关人员少走一些弯路, 节约一些时间
当我们学习任何一个新的内容或遇到新的事情时, 随着时间的推移, 可能回过头来会发现, 当时要是怎样结果又会怎样身边很多人包括我自己在读完大学后, 发现如果高中再努力一些或重新把大学时间利用好, 人生的路途是不是能更顺利些曾经听一位老师说过青春就像这样, 不管你怎样过都会过得一团糟事实上, 大多数学生没有利用好时间是由于没有明确的方向同理, 对于新入职的员工而言, 有一个师父在平时的工作中以他过来人的经验引导一下, 新员工的发展也会更顺利些那么对于学习机器学习而言, 这里有一份过来人的经验分享清单, 希望这个清单能够帮助那些正在学习机器学习的相关人员少走一些弯路, 节约一些时间
这份清单主要是包含一些关于构建机器学习工作流以及 Apache Spark 相关的具体内容
预测是困难的
对于任何未知的事情, 很难对其做出一个准确的时间预测, 但我们会朝着目标前进然而随着时间的推移, 在努力的过程中逐渐会出现错误, 这是由于我们无法预测采用哪种方法就能够得出好的结果, 能够做的只有确保项目组可以快速地迭代更新
项目有很大的未知数, 请确保团队能够进行快速迭代更新
在开始之前验证数据是否完整
当开始使用机器学习管道时, 我们已经收集了大约 3 年时间的原始数据但没有对原始数据做任何处理, 只是将其存储以防万一原始数据采用 CSV 文件形式, 此时没有注意到这些数据存在问题, 另外编写这些文件的代码会随着时间的推移而导致一些错误因此在构建机器学习管道的同时, 还需要修复造成错误的数据问题, 最终在 Apache Spark 中编写相关的代码来清理历史数据在进行到中间时刻才发现问题, 而不是在最初, 这无疑增加了项目的难度
在开展工作之前, 请确保数据正确
对数据进行一次预处理, 对构建模型进行一百万次训练
在最初训练机器学习模型时, 我们尝试加载所有的数据而采用的数据大小是 TB 级别, 如果每次训练都加载所有数据会导致训练速度很慢因此, 每次训练时不需要加载所有的数据, 可以对其做一些预处理, 创建一个新的小数据集此外, 并没有删掉原始数据集, 将其作为备份以防后续过程中出现新的错误
不要将 ETL 和模型训练混淆如果你正在训练 1000 个模型且不想执行 1000 次预处理, 可以只做一次预处理并保存, 然后将其用于所有的模型训练需求
为不同的团队成员提供轻易的访问途径
在上文说过, 我们将原始数据存储在 AWS S3 中备份当开始使用机器学习开展工作时, 发现为每个人提供轻松地访问途径显得至关重要只给予读取权限是不够的, 科研人员不会通过笔记本下载 TB 级的数据, 且不会随身携带笔记本电脑来处理 TB 级的数据, 这只会浪费每个人的时间我们发现使用支持像 Apache Spark 这样环境的 Notebook 可以达到这个目的, 比如 Jupyterzeepelin 等, 读者可以根据自己的平台选择合适的 Notebook
为小组人员提供访问 TB 级数据的途径, 此外必须提供合适的工具使其能够从中很好的理解这些数据, 比如 Jupyterzeppelin 等这些基于 spark 集群的 Notebook
对于大数据而言, 监控是必须的
当处理大数据时, 传统的软件工程方法是不起作用的一般的程序可能花费几分钟就可以运行完毕, 但大数据可能需要几小时到几天的时间与传统软件编程相比, 如何在大数据情况下减少批量处理作业的完成时间这一问题更为复杂使用云计算可以水平降低机器要求以及缩短运行时间但是, 我们应该增加机器的数量还是完全改变机器的类型? 分布式环境中的瓶颈在哪里? 等等这些问题都是减少执行时间时需要解决的问题
对于 Apache Spark 而言, 很难弄清楚需要的机器类型 Amazon EMR 带有 Ganglia, 这让我们一眼就可以监视集群内存 / CPU 但有时候也不得不去检查底层的 EC2 实例监测, 因为 Ganglia 并不完美, 将二者结合起来使用是很不错的方法此外, 与训练机器学习模型的作业相比, ETL 作业具有不同的执行配置文件 ETL 占用了大量的网络和内存, 机器学习需要更多的计算, 可以为这两种类型的作业选择不同的实例类型
需要从 CPU / 内存 / 网络 / IO 监控方面优化成本, 此外发现不同的工作 (ETL 机器学习) 有不同的机器要求
在一开始就需要对机器学习预测进行基准测试
对机器学习模型的预测有没有延迟要求? 如果有的话, 在选择任何具体框架之前, 请确定该框架的训练模型是否可以满足你的延迟要求对于基础模型而言, 很容易就能掌握其中包含的数学基本理论, 并理所当然的认为它会运行得很快但事实证明, 还有一些其它因素可能会导致预测的速度不如理论上预期的那样快建立一个简单的模型并进行基准测试如果在建立管道后才发现问题, 这可能会浪费大量的时间当发现 Spark 不能满足延迟要求时, 可以使用 mleap 库提升预测延迟
如果有延迟需求, 请从要使用的框架中制作出一个简单模型, 精度准确率或其它指标都无关紧要, 只需要以预测延迟为基准点
无论 AWS 如何显示, S3 都不是一个文件系统
使用 AWS 的 GUI 或 CLI 很容易忘记 S3 不是一个文件系统, S3 是一个对象存储库, 存储的对象是 json 图片等内容这个区别很重要, 因为在 S3 中重命名内容并不像在真正的文件系统中那样快如果在一个文件系统中移动一个对象, 它可能会很快地移动, 但这在 S3 中是无法实现的为什么这个显得很重要呢? 因为当通过 Apache 将数据写入 S3 时, Apache Spark 会产生临时文件, 然后将其移动到新的秘钥中基于以上原因, Apache Spark 有一个设置, 可以告诉它不写入临时文件, 而是写入最终输出我们使用了这种设置, 在写入 AWS s3 上节约了大量的时间
Apache Spark 主要是基于 Scala
如果使用的是 Apache Spark, 你应该知道它主要是基于 Scala 的 Java 和 Python 等应用接口也可以工作, 但是网上的例子大多是基于 Scala 的而我们使用的是 Java, 这是由于之前的技术栈使用的是 Java 在刚开始时, 对于机器学习和 Scala 等方面都没有任何专业知识, 我们简单地认为机器学习对于项目而言至关重要, 而 Scala 不是因此, 无法让团队像处理机器学习问题那样处理 Scala 曲线将 Scala 翻译成 Java 并不难, 但将 Spark Scala 翻译为 Spark Java 很困难, 因为这些应用接口在 Java 中难以使用
如果你不了解 Scala 并且还想使用 Spark Mllib, 那么可能需要在选择语言方面考虑妥协这种解决方案不是理想的工程解决方案, 而是一个实用的解决方案
知识分享对于团队合作而言很重要
如果将机器学习与现有系统集成在一起, 那么将不得不与其他开发人员打交道此外, 还需要与业务操作营销等人员进行交流但是这些人员中的大多数人不会对机器学习有很好的理解, 因此他们需要这方面的知识, 但是他们又不能坐下来学习机器学习相关课程这个时候就应该做一些机器学习方面的知识分享, 只需要解释一些涉及外行常见的术语即可, 比如训练集 / 测试集 / 验证集模型等, 而不必教他们相关算法等深奥的内容
对于专业人员来说, 很容易忘记机器学习中充满了术语, 虽然你可能完全熟悉这些术语, 但对于团队中的其他人而言, 这些可能会是完全陌生的词语, 因为不是所有人都参加过机器学习课程
对数据库构建版本控制可能是一个好的想法
可能需要对数据库构建版本控制方案, 并且可以在不重新部署整个软件的情况下切换不同的模型训练代码以使用不同的数据集我们创建了一些模型, 并用一些数据对其进行了尝试, 结果发现数据量不够, 模型工作得不够好因此, 为数据库建立版本控制方案, 以便可以在 V1 版本上训练模型并继续生成下一个版本新版本中足够的数据后, 就可以切换模型训练代码以使用新数据集此外, 还制作了一个 UI 界面, 以便控制机器学习的参数指定用于训练的数据量等基本上可以通过 UI 可以轻松地配置一些参数, 以确保对用于训练的数据进行更改时不需要重新部署相关参数
来源: http://geek.csdn.net/news/detail/257547