1.4 搭建 Python 与 Jupyter 环境
前三节建立了分析的推理层:从决策定义问题,在生命周期中保留证据链,并声明数据集粒度与模式。现在需要一个不会隐藏结果产生过程的工作环境。
本课程使用 Python 和 JupyterLab。Notebook(交互式笔记本)把可执行代码单元、运行结果和说明性 Markdown 单元放在一个文档中,非常适合学习和探索;但它的实时内存也可能让不可复现的分析看起来一切正常。
创建隔离环境
Python 虚拟环境(virtual environment)可以让本课程使用的软件包与其他项目隔离。在新的项目目录中运行:
python -m venv .venv在 Windows PowerShell 中激活环境:
.\.venv\Scripts\Activate.ps1在 macOS 或 Linux 中激活:
source .venv/bin/activate然后安装本课程最初需要的工具:
python -m pip install --upgrade pip
python -m pip install jupyterlab numpy pandas matplotlib scikit-learn使用 python -m pip 可以让安装操作明确对应当前选择的 Python 解释器。安装后要验证解释器和版本,不要仅凭终端外观猜测环境是否正确:
python --version
python -m pip show numpy pandas matplotlib scikit-learn jupyterlab从项目根目录启动 JupyterLab:
python -m jupyter lab不要在 Notebook 中放入密钥、顾客数据或访问令牌。分享 Notebook 时,运行输出可能仍嵌在文件里。本课程应使用去敏数据;需要配置时使用环境变量。
理解内核与隐藏状态
内核(kernel)是 Notebook 运行时保存变量和已导入模块的 Python 进程。编辑代码单元只会改变屏幕上的文字;执行该单元以后,内核内存才会改变。
考虑以下两个单元:
discount = 0.20total = 100 * (1 - discount)
total依次运行后,total 是 80。如果把第一个单元改成 discount = 0.10 却不重新运行,屏幕上显示的是 10%,内核仍然保存 20%。此时只运行第二个单元,结果仍是 80。这种不一致就是隐藏状态(hidden state)。
让 Notebook 能够从头运行到底
可信的 Notebook 应通过一项简单测试:重启内核、清空旧内存,然后按顺序运行全部单元,不需要人工补救。组织单元时应让依赖关系清晰可见:
- 导入语句靠近开头。
- 配置与路径只声明一次。
- 数据读取位于配置之后。
- 验证发生在分析以前。
- 派生结果位于所需输入之后。
- 最终输出由代码生成,不依赖手工修改。
使用项目内相对路径,不要把路径绑定到某个人的桌面:
from pathlib import Path
PROJECT_ROOT = Path.cwd()
DATA_PATH = PROJECT_ROOT / "data" / "raw" / "deliveries.csv"Path.cwd() 表示当前工作目录。这个例子假设从项目根目录启动 JupyterLab,因此 README 里也要写明这一假设。以后编写可复用的生产代码时,还可以把路径定位到软件包或配置文件。
当输入违反假设时应尽早失败:
import pandas as pd
deliveries = pd.read_csv(DATA_PATH)
required_columns = {"order_id", "zone", "delivery_minutes"}
assert len(deliveries) > 0, "The dataset is empty"
assert required_columns <= set(deliveries.columns), "Required columns are missing"断言不是完整的数据验证系统,却好过画完三张图后才发现读取了错误文件。
可复现性控制的不只是代码
可复现性(reproducibility)是指另一个人,或未来的你,能够使用记录好的输入和流程获得相同结果;如果允许一定误差,也要明确写出误差范围。四类条件经常破坏可复现性:
| 条件 | 不加控制时的故障 | 控制方法 |
|---|---|---|
| 环境 | 软件包行为改变 | 记录 Python 与依赖版本 |
| 输入 | 来源文件被悄悄替换 | 为数据快照记录版本或校验值 |
| 随机性 | 抽样或模型每次变化 | 设置并记录随机种子 |
| 执行 | Notebook 隐藏状态影响输出 | 重启内核并运行全部单元 |
随机种子(random seed)控制伪随机序列,能够帮助重复数据拆分或模拟,却不能修复有偏数据,也不能保证所有软件和硬件组合都得到完全相同的行为。它只是一个需要记录的条件,不是正确性的魔法印章。
制作交接包,而不是私人作品
一个小型分析项目至少应该说明:
- 要支持的决策和分析问题。
- 数据来源、提取日期、范围和使用限制。
- Python 与直接依赖的版本。
- 从干净状态运行分析的命令或顺序。
- 将生成哪些文件,以及用什么检查判断运行成功。
如果真实数据不能分享,应提供经过适当去敏的小型样例和清晰的获取说明。绝不能用编造的信息代替缺失的来源记录。
第 1 章为后续课程建立了一份契约:每项计算都回答明确问题,每行数据都有声明好的含义,每条结论都不越过证据边界,每个输出都可以追踪并重新运行。第 2 章将在这份契约上介绍 NumPy 数组、形状、轴、数据类型和向量化计算。