共计 5392 个字符,预计需要花费 14 分钟才能阅读完成。
摘要:在一个新的数据科学项目,你应该如何组织你的项目流程?数据和代码要放在那里?应该使用什么工具?在对数据处理之前,需要考虑哪些方面?读完本文,会让你拥有一个更加科学的工作流程。
假如你想要开始一个新的数据科学项目,比如对数据集进行简单的分析,或者是一个复杂的项目。你应该如何组织你的项目流程?数据和代码要放在那里?应该使用什么工具?在对数据处理之前,需要考虑哪些方面?
数据科学是当前一个不太成熟的行业,每个人都各成一家。虽然我们可以在网上参照各种模板项目、文章、博客等创建一个数据科学项目,但是目前也没有教科书对这些知识做一个统一的回答。每个数据科学家都是从经验和错误中不断的探索和学习。现在,我逐渐了解到什么是典型的“数据科学项目”,应该如何构建项目?需要使用什么工具?在这篇文章中,我希望把我的经验分享给你。
工作流程
尽管数据科学项目的目标、规模及技术所涉及的范围很广,但其基本流程大致如下:
如上图所示,项目不同,其侧重点也会有所不同:有些项目的某个过程可能特别复杂,而另一些项目可能就不需要某一过程。举个例子来说,数据科学分析项目通常就不需要“部署”(Deployment)和“监控”(Monitoring)这两个过程。现在,我们逐一来细说各个过程。
源数据访问
不管是你接触到人类基因组还是 iris.csv,通常都会有“原始源数据”这一概念。数据有很多种形式,可以是固定的,也可以是动态变化的,可以存储在本地或云端。其第一步都是对源数据访问,如下所示:
源数据是 *.csv 文件集合。使用 Cookiecutter 工具在项目的根文件夹中创建一个 data/raw/ 子目录,并将所有的文件存储在这里;创建 docs/data.rst 文件描述源数据的含义。
源数据是 *.csv 文件集合。启动 SQL 服务器,创建一个 raw 表,将所有的 CSV 文件作为单独的表导入。创建 docs/data.rst 文件描述源数据及 SQL Server 位置。
源数据是基因组序列文件、患者记录、excel 及 word 文档组合等,后续还会以不可预测的方式增长。这样可以在云服务器中创建 SQL 数据库,将表导入。你可以在 data/raw/ 目录存储特别大的基因组序列,在 data/raw/unprocessed 目录存储 excel 和 word 文件;还可以使用 DVC 创建 Amazon S3 存储器,并将 data/raw/ 目录推送过去;也可以创建一个 Python 包来访问外部网站;创建 docs/data.rst 目录,指定 SQL 服务器、S3 存储器和外部网站。
源数据中包含不断更新的网站日志。可以使用 ELK stack 并配置网站以流式传输新日志。
源数据包含 10 万张大小为 128128 像素的彩色图像,所有图像的大小则为 100,0001281283,将其保存在 HDF5 文件 images.h5 中。创建一个 Quilt 数据包并将其推送给自己的私人 Quilt 存储库;创建 /docs/data.rst 文件,为了使用数据,必须首先使用 quilt install mypkg/images 导入工作区,然后再使用 from quilt.data.mypkg import images 导入到代码中。
源数据是模拟数据集。将数据集生成实现为 Python 类,并在 README.txt 文件中记录其使用。
通常来说,在设置数据源的时候可以遵循以下规则:
存储数据的方式有意义,另外还要方便查询、索引。
保证数据易于共享,可以使用 NFS 分区、Amazon S3 存储器、Git-LFS 存储器、Quilt 包等。
确保源数据是只读状态,且要备份副本。
花一定的时间,记录下所有数据的含义、位置及访问过程。
上面这个步骤很重要。后续项目会你可能会犯任何错误,比如源文件无效、误用方法等等,如果没有记住数据的含义、位置及访问过程,那将很麻烦。
数据处理
数据处理的目的是将数据转化为“干净”的数据,以便建模。在多数情况下,这种“干净”的形式就是一个特征表,因此,“数据处理”通常归结为各种形式的特征工程(feature engineering),其核心要求是:确保特征工程的逻辑可维护,目标数据集可重现,整个管道可以追溯到源数据表述。计算图(computation graph)即满足以上要求。具体例子如下:
根据 cookiecutter-data-science 规则,使用 Makefile 来描述计算图。通过脚本实现每个步骤,该脚本将一些数据文件作为输入,然后输出一个新的数据文件并存储在项目的 data/interim 或 data/processed 目录中。可以使用 make -j <njobs> 命令进行并行运算。
使用 DVC 来描述和执行计算图,其过程与上面类似,此外还有共享生成文件等功能。
还可以使用 Luigi、Airflow 或其他专用工作流管理系统来描述和执行计算图。除此之外,还可以在基于 web 的精美仪表板上查看计算进度。
所有源数据都以表的形式存储在 SQL 数据库中,在 SQL 视图中实现所有的特征提取逻辑。此外,还可以使用 SQL 视图来描述对象的样本。然后,你可以根据这些特征和样本视图创建最终的模型数据集。
首先,允许用户轻松的跟踪当前所定义的特征,而不用存储在大型数据表中。特征定义仅在代码运行期间有效;其次,模型从部署到生产非常简单,假设实时数据库使用相同的模式,你就只需要复制相应的视图。此外,还可以使用 CTE 语句将所有的特征定义编译为模型最终预测的单个查询语句。
在进行数据处理时,请注意一下问题:
1. 重复以计算图的形式处理数据。
2. 考虑计算基础架构。是否进行长时间计算?是否需要并行计算还是聚类?是否可以从具有跟踪任务执行的管理 UI 作业中获益?
3. 如果想要将模型部署到生产环境中,请确保系统支持该用例。如果正在开发一个包含 JAVA Android 应用程序模型,但是还是想用 Python 开发,为了避免不必要的麻烦,就可以使用一个专门设计的 DSL,然后将这个 DSL 转换为 Java 或 PMML 之类的中间格式。
4. 考虑存储特征或临时计算的元数据。可以将每个特征列保存在单独的文件中,或使用 Python 函数注释。
建模
完成数据处理和特征设计后即可开始进行建模。在一些数据科学项目中,建模可以归结为单个 m.fit(X,y)或某个按钮;而在其他项目中则可能会涉及数周的迭代和实验。通常来说,你可以从“特征工程”建模开始,当模型的输出构成了很多特征时,数据处理和建模这两个过程并没有明确的界限,它们都涉及到计算。尽管如此,将建模单独列出来作为一个步骤,仍然很有意义,因为这往往会涉及到一个特殊的需求:实验管理(experiment management)。具体例子如下:
如果你正在训练一个模型,用于在 iris.csv 数据集中对 Irises 进行分类。你需要尝试十个左右的标准 sklearn 模型,每个模型都有多个不同的参数值,并且测试不同的特征子集。
如果你正在设计一个基于神经网络的图像分类模型。你可以使用 ModelDB(或其他实验管理工具,如 TensorBoard,Sacred,FGLab,Hyperdash,FloydHub,Comet.ML,DatMo,MLFlow,…)来记录学习曲线和实验结果,以便选择最佳的模型。
使用 Makefile(或 DVC、工作流引擎)实现整个管道。模型训练只是计算图中的一个步骤,它输出 model-<id>.pkl 文件,将模型最终 AUC 值附加到 CSV 文件,并创建 model-<id>.html 报告,还有一堆用于评估的模型性能报告。
实验管理 / 模型版本控制的 UI 外观如下:
模型部署
在实际应用中,模型最终都要部署到生产环境中,一定要有一个有效的计划,下面有些例子:
建模管道输出一个训练过模型的 pickle 文件。所有的数据访问和特征工程代码都是由一系列 Python 函数实现。你需要做的就是将模型部署到 Python 应用程序中,创建一个包含必要函数和模型 pickle 文件的 Python 包。
管建模道输出一个训练过的模型的 pickle 文件。部署模型需要使用 Flask 创建一个 REST 服务将其打包为一个 docker 容器,并通过公司的 Kubernetes 云服务器提供服务。
训练管道生成 TensorFlow 模型。可以将 TensorFlow 服务当做 REST 服务。每次更新模型时,都要创建测试并运行。
训练管道生成 PMML 文件。你可以用 Java 中的 JPMML 库来读取,一定要确保 PMML 导出器中要有模型测试。
训练管道将模型编译为 SQL 查询,将 SQL 查询编码到应用程序中。
我们对模型部署做一下总结:
1. 模型部署的方式有很多种。在部署之前一定要了解实际情况,并提前做计划:是否需要将模型部署到其他语言编写的代码库中?如果使用 REST 服务,服务的负载时多少?能否进行批量预测?如果打算购买服务,费用是多少?如果决定使用 PMML,那么就要确保它能够支持你的预期预处理逻辑。如果在训练期间使用第三方数据源,那么就要考虑是否在生产中能够与它们集成,以及如何在管道导出模型中对访问信息进行编码。
2. 模型一旦部署到生产环境,它就转变为一行行实际的代码,所以也要满足所有需求,因此,这就需要测试。在理想情况下,部署管道应该产生用于部署的模型包以及测试时需要的所有内容。
模型监控
将模型成功部署到生产环境,也许训练集中的输入分布与现实不同,模型需要重新练或重新校准;也许系统性能没有达到预期。因此,你需要收集模型性能的数据并对其进行监控。这就需要你设置一个可视化仪表板,具体事例如下:
将模型的输入和输出保存在 logstash 或数据表中,设置 Metabase(或 Tableau,MyDBR,Grafana 等)并创建可视化模型性能和校准指标报告。
进一步探索和报告
在整个数据科学项目中,你还需要尝试不同的假设,以生成图标和报告。这些任务与构建管道有所不同,主要体现在两个方面:
首先,大部分任务不需要可再现性,即不用包含在计算图中。另外,也没必要使用模型的可重复性,在 Jupyter 中手动绘制图即可。
其次,这些“进一步探索”的问题往往具有不可预测性:可能需要分析性能监控日志中的一个异常值;或者测试一个新的算法。这些探索会塞满你的笔记本中,团队中的其他人可能看不懂你的记录。因此按照日期排列子项目很重要。
在项目中创建 project 目录,子文件夹命名格式为:projects/YYYY-MM-DD - 项目名称。如下所示:
./2017-01-19 – Training prototype/ (README, unsorted files)./2017-01-25 – Planning slides/ (README, slides, images, notebook)./2017-02-03 – LTV estimates/ README tasks/ (another set of date-ordered subfolders)./2017-02-10 – Cleanup script/ README script.py./… 50 folders more …
注意,你可以根据需要自由组织每个子项目的内部目录,因为每个子项目很可能也是一个“数据科学项目”。在任何情况下,在每个子项目中都要有个 README 文件夹或 README.txt 文件,简要列出每个子项目目录的信息。
如果项目列表太长,你需要重新组织项目目录,比如压缩一部分文件移动到存档文件夹中。“探索性”的任务有两种形式,即一次性分析和可重复性使用的代码,这时候建立一些约定很有必要。
服务清单
数据科学项目可能会依赖一些服务,可以指定提供以下 9 个关键服务,来描述期望:
1. 文件存储。任何一个数据科学项目都必须有个存储项目的地方,且需要整个团队共享。它是网络驱动器上的一个文件夹?还是 Git 存储库中的一个文件夹?
2. 数据服务。如何存储和访问数据?这里的“数据”指的是计算机读取或输出的所有内容,包括源数据、中间结果及第三方数据集访问、元数据、模型及报告等。
3. 版本。代码、数据、模型、报告和文档都需要有版本控制,另外一定要备份!
4. 元数据和文档。如何记录项目及子项目?是否有任何机器都可读的特征、脚本、数据集或模型的元数据?
5. 交互式计算。在交互式计算中,你选择 JupyterLab、RStudio、ROOT、Octave 还是 Matlab?您是否为交互式并行计算设置了一个聚类(如 ipyparallel 或 dask)?
6. 作业队列和调度程序。代码如何运行?是否需要安排定期维护?
7. 计算图。如何描述计算图并建立可重复性?
8. 实验管理。如何收集、查看和分析模型培训进度和结果?使用 ModelDB、Hyperdash 还是 FloydHub?
9. 监控仪表板。如何收集和跟踪模型在生产环境中的具体表现?使用元数据库、Tableau、PowerBI 还是 Grafana?
最后,我总结了一个电子表格,包含了本文提到的所有工具,可自行下载使用。
本文作者:【方向】阅读原文
本文为云栖社区原创内容,未经允许不得转载。