数据科学项目涉及许多不同类型的文件,比如:

  • 原始数据文件(CSV,JSON等)
  • 清理和预处理后的数据文件
  • 训练和测试数据集
  • 模型文件(保存的机器学习模型等)
    = 代码文件(Python,R,Java等)
  • 可视化和报告文件(Jupyter notebook,R markdown等)

所以数据科学项目的文件结构易乱,允许混杂各种类型的文件。这容易导致一些问题:

  • 文件难以查找。没有规范的目录结构,相关文件的位置散乱,不利于查找和管理。
  • 依赖关系不清晰。训练数据、代码和模型等之间的依赖关系变得模棱两可,不利于项目的持续和重用。
  • 复制粘贴代码。没有清晰的项目结构,不同任务之间的共用代码容易通过复制粘贴的方式重复出现,不利于维护。
  • 难以重构和重用。文件的混乱会使项目难以进行大规模重构,也难以重用现有的组件在其他项目中。

**所以,对数据科学项目来说制定一个标准的文件结构和目录约定是非常重要的。**标准化的项目结构可以大大增强数据科学项目的可管理性、重用性和可扩展性。这里推荐一个灵活标准的项目结构工具————Cookiecutter Data Science。它为可以Python项目创建一个数据科学cookiecutter模板,当然你不一定要用Python,可以自行删除其中Python相关的模板。

Requirements

  • Python 2.7 or 3.5
  • cookiecutter Python package >= 1.4.0: pip install cookiecutter

项目初始化

只需要在命令行里输入以下命令,并按提示填写项目名称等信息,就可以在当前目录下创建一个数据科学项目的完整目录结构。

1
cookiecutter https://github.com/drivendata/cookiecutter-data-science

文件结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
├── LICENSE
├── Makefile <- Makefile,包含 "make data "或 "make train "等命令。
├── README.md <- 顶层的README,供开发者使用。
├── data
│ ├── external <- 来自第三方的数据。
│ ├── interim <- 经过转换的中间数据。
│ ├── processed <- 最终的、规范的数据集,用于建模。
│ └── raw <- 原始的、不可改变的数据转储。

├── docs <- 默认的Sphinx项目;详见sphinx-doc.org,sphinx是一个python文档生成库。

├── models <- 训练过的和序列化的模型,模型预测,或模型摘要。
├── notebooks <- Jupyter notebooks。命名规则是一个数字(用于排序)、创作者的首字母,
│ 以及简短的"-"分隔符描述,例如`1.0-jqp-initial-data-exploration`。

├── references <- 数据字典、手册和所有其他解释材料。

├── reports <- 以HTML、PDF、LaTeX等方式生成的分析报告。
│ └── figures <- 生成的用于报告的图形和图表。

├── requirements.txt <- 用于复制分析环境的requirement文件,例如:
│ 用 "pip freeze > requirements.txt "生成。

├── setup.py <- 让这个项目可以用 "pip install -e "进行pipeline安装。
├── src <- 在本项目中使用的源代码。
│ ├── __init__.py
│ │
│ ├── data <- 用于下载或生成数据的脚本
│ │ └── make_dataset.py
│ │
│ ├── features <- 将原始数据转化为建模用的特征的脚本
│ │ └── build_features.py
│ │
│ ├── models <- 训练模型的脚本,然后用训练好的模型来做
│ │ ├── predict_model.py
│ │ └── train_model.py
│ │
│ └── visualization <- 创建探索性和面向结果的可视化的脚本
│ └── visualize.py

└── tox.ini <- tox文件,包含了运行tox的设置;见tox.readthedocs.io

一些建议

  • 永远不要编辑你的原始数据,尤其不要手动编辑,不要保存多个版本的原始数据。你应该通过一个Pipeline把数据转换成你想要的结果。
  • 默认情况下把数据路径包含在.gitignore文件中。
  • notebook是用来进行探索和交流的,不适合生产分析。可以将notebook细分,notebooks/exploratory包含最初的探索,而notebooks/reports则是更精炼的工作,可以作为html导出到报告目录。
  • notebook遵循一个命名惯例,显示所有者和分析的顺序。
  • 对notebook中好的部分进行重构。不要在多个notebook中写代码来做同样的任务。
    • 如果它是一个数据预处理任务,把它放在 src/data/make_dataset.py 的管道中,并从 data/interim 中加载数据。
    • 如果是有用的实用程序组件,就把它重构到src中。
  • 分析是一个DAG,在一个分析中,经常有长期运行的步骤来预处理数据或训练模型。如果这些步骤已经运行过了(并且你已经把输出存储在某个地方,比如data/interim目录),就不想每次都等待重新运行它们。用make来管理那些相互依赖的步骤,特别是那些长期运行的步骤。
  • 重现一个分析的第一步是重现运行环境,推荐用virtualenv做环境管理。
  • 让密码和配置远离版本控制库。在项目根目录下创建一个.env文件。由于.gitignore的存在,这个文件应该永远不会被提交到版本控制库中。然后编写一个package来自动加载这些变量,推荐使用python-dotenv。

后话

网上有许多建议的数据科学文件夹结构的例子,目前看最好的可能是Cookiecutter模板。但是不同的数据科学团队的文件夹结构差异很大,所使用的具体工具、技术和任务严重影响了对标准结构的要求。所以建议使用类似Cookiecutter的模板,但要调整让它适应你的团队。