为什么要使用项目结构?
结构曾经是偏爱,但在一天结束时,您应该愿意四处走动并编写代码。
当我们考虑数据科学/分析时,我们经常认为这只是结果,图表,数字,见解或可视化。尽管这些最终产品通常是主要事件,但很容易专注于使产品看起来不错,而忘记了代码质量和可重复使用 能够与其他项目结构合作的能力很重要。
说没有正确的方法来构建您的项目,但是您至少应该拥有一些我们可以遵循的标准化项目的结构。您可能会在想为什么应该使用项目结构!这是背后的一些原因:
快乐的团队成员
在创建一个新的Rails项目之前,没有人坐在周围,以弄清他们想在哪里提出自己的看法。他们只是运行
rails new
,像其他所有人一样获得标准的项目骨骼。
定义明确的标准项目结构意味着新来者可以开始理解分析而无需挖掘大量文档。这也意味着他们不一定要在知道在哪里寻找非常具体的内容之前必须阅读100%的代码。
组织良好的代码往往是自我示例的,因为组织本身为您的代码提供了上下文,而没有太多开销。人们会为此感谢您,因为他们可以:
- 在此分析上更容易与您合作
- 从您对过程和域的分析中学习
- 对分析的结论充满信心
幸福的未来你
曾经尝试过复制几个月前甚至几年前进行的分析?您可能已经编写了代码,但是现在不可能破译是否应该使用make_figures.py.old
,make_figures_working.py
或new_make_figures01.py
,try_figre.py
来完成工作。然后,您开始质疑自己的存在,这在某个时候发生在我们所有人身上。这是我们开设旧数据科学项目时问的一些问题。
- 我在哪里存储了数据文件?
- 地块在哪里保存了?
- 我在哪里保存了ML模型?
这些类型的问题很痛苦,是一个混乱的项目的症状。一个良好的项目结构鼓励实践,从而更容易回到旧工作。
入门
项目中的一致性更为重要。一个模块或功能中的一致性是最重要的……但是,知道何时不一致 - 有时样式指南建议不适用。如有疑问,请使用最佳判断。查看其他示例,并确定看起来最好的示例。不要犹豫问问!
要求
- Python 3.5+
开始一个新项目
启动一个新项目就像在命令行中运行此命令一样容易。
- 创建一个文件夹。
- 复制粘贴
setup.py
。 - 使用
python setup.py
运行python文件
# setup.py
import os
folders = [
"data",
"data/processed",
"data/raw",
"data/external",
"data/transformed",
"docs",
"models",
"notebooks",
"references",
"reports",
"reports/figures",
"src",
"src/data",
"src/features",
"src/models",
"src/visualization",
]
for folder in folders:
os.makedirs(folder, exist_ok=True)
with open(os.path.join(folder, ".gitkeep"), "w") as f:
pass
files = [
"src/__init__.py",
"src/data/make_dataset.py",
"src/features/build_features.py",
"src/models/train_model.py",
"src/models/predict_model.py",
"src/visualization/visualize.py",
"requirements.txt"
]
for file in files:
with open(file, "w") as f:
pass
目录结构
├── data
│ ├── external <- Data from third party sources.
│ ├── transformed <- Intermediate data that has been transformed.
│ ├── processed <- The final, canonical data sets for modeling.
│ └── raw <- The original, immutable data dump.
│
├── docs <- A default Sphinx project; see sphinx-doc.org for details
│
├── models <- Trained and serialized models, model predictions, or model summaries
│
├── notebooks <- Jupyter notebooks. Naming convention is a number (for ordering),
│ the creator's initials, and a short `-` delimited description, e.g.
│ `1.0-jqp-initial-data-exploration`.
│
├── references <- Data dictionaries, manuals, and all other explanatory materials.
│
├── reports <- Generated analysis as HTML, PDF, LaTeX, etc.
│ └── figures <- Generated graphics and figures to be used in reporting
│
├── requirements.txt <- The requirements file for reproducing the analysis environment, e.g.
│ generated with `pip freeze > requirements.txt`
│
├── setup.py <- Make this project pip installable with `pip install -e`
├── src <- Source code for use in this project.
│ ├── __init__.py <- Makes src a Python module
│ │
│ ├── data <- Scripts to download or generate data
│ │ └── make_dataset.py
│ │
│ ├── features <- Scripts to turn raw data into features for modeling
│ │ └── build_features.py
│ │
│ ├── models <- Scripts to train models and then use trained models to make
│ │ │ predictions
│ │ ├── predict_model.py
│ │ └── train_model.py
│ │
│ └── visualization <- Scripts to create exploratory and results oriented visualizations
│ └── visualize.py
└─
意见
这绝不是最好的项目结构,而是起点。这种结构提供了一个起点,您可以迭代它以使其拥有。一些意见是关于工作流的,其中一些意见是关于使生活更轻松的工具。
数据是不变的
永远不要编辑您的原始数据,尤其是手动,尤其是在Excel中。不要覆盖原始数据。不要保存多个版本的原始数据。将数据(及其格式)视为不可变的。您编写的代码应通过管道将原始数据移至最终分析。您不必每次要制作一个新数字时都必须运行所有步骤,但是任何人都应该能够仅使用src
中的代码和data/raw
中的数据来复制最终产品。另外,如果数据是不可变的,则它不需要像代码一样需要源控制。因此,默认情况下,数据文件夹包含在.gitignore
文件中。 –如果您有少量的数据很少更改,则可能需要包括数据在存储库中。
笔记本是用于探索和尝试的
笔记本对于探索性数据分析非常有效。但是,这些工具对于重现分析的有效性较小。我们应该将notebooks
的文件夹细分。例如,notebooks/exploratory
包含初始探索,而notebooks/reports
是更精致的作品,可以将其作为HTML导出到reports
目录。