1. Snakemake 入门

1.1 Snakemake 是什么?

先说说我最早接触 Snakemake 时的感受——这玩意儿说白了就是一个工作流管理工具,但跟那些笨重的图形化工作流平台不一样,它轻巧、纯 Python 驱动,而且语法极度接近你熟悉的 Makefile。

Snakemake 的核心思路很简单:你定义一系列规则(rule),每个规则指定输入、输出和执行的命令或脚本。它自动解析依赖关系,按需执行,还能并行跑。我记得刚开始做特征工程时,动不动就是几十个脚本按顺序跑,中间出错整个重来,折腾得够呛。后来用 Snakemake 重构了流程,舒服多了。

一句话总结: Snakemake 不是帮你写代码,而是帮你管代码的执行顺序和依赖。

1.2 为什么在特征工程中选 Snakemake?

特征工程这种活,你想想看——原始数据 → 清洗 → 衍生 → 编码 → 归一化 ← 这里面每一步都可能依赖前面的输出。随便改一个环节,后面的所有结果都需要重新生成。手动维护?不现实。写个 shell 脚本?跑完一次就忘了哪些已经生成。这时候就需要一个懂依赖关系的执行管家。

具体原因

  • 自动化的依赖解析: 你只需要声明每个步骤的输入输出,Snakemake 自动判断哪些需要重新执行。
  • 可重复性: 所有步骤通过 Snakefile 定义,环境通过 conda 锁定。我团队里曾经因为某同事手动改了一个参数导致全组结果不一致,后来换成 Snakemake + conda 环境锁定,再没出过这种问题。
  • 并行执行: 特征工程中经常要对多个分片或特征组做同样的操作,Snakemake 原生支持多核并行和集群调度。
  • 增量构建: 改了一处逻辑,它只重跑受影响的部分,而不是全量执行。这在实际项目中节省的时间非常可观。
  • 集成 Python 生态: 直接在规则里调用 Python 脚本,跟 pandas、numpy 无缝衔接。
坑: 我曾经试过用通用 Makefile 来管理特征工程流程,结果发现 Makefile 对 Python 路径和 conda 环境的处理特别别扭。Snakemake 在这点上就是原生支持,省心很多。

1.3 安装与环境配置

基础安装

最推荐的方式是用 conda 或 mamba 安装,避免依赖污染。我个人习惯在一个独立环境中部署,比如:

conda create -n fe-snakemake python=3.9
conda activate fe-snakemake
conda install -c bioconda snakemake

如果你的 conda 解析慢,可以试试 mamba:

conda install -c conda-forge mamba
mamba create -n fe-snakemake python=3.9
mamba activate fe-snakemake
mamba install -c bioconda snakemake

用 pip 也行,但要注意 snakemake 依赖的一些系统库(比如 Graphviz)需要额外装:

pip install snakemake
# 如果需要画 DAG 图,还要装(可选)
sudo apt-get install graphviz  # Linux
brew install graphviz          # macOS

验证安装

安装完成后用这个命令检查版本:

snakemake --version

正常应该输出类似 7.32.4 的版本号。我建议用 7.x 系列,8.x 有些改动较大,目前社区文档主要还是基于 7.x。

Snakefile 初体验

Snakemake 的配置文件默认名字是 Snakefile,也可以自定义。先写一个最简单的例子感受一下:

rule all:
    input: "output/cleaned.csv"

rule clean_csv:
    input: "data/raw.csv"
    output: "output/cleaned.csv"
    shell: "python scripts/clean.py {input} {output}"

在终端运行:

snakemake -c1

这就完成了从原始数据到清洗文件的执行。如果 output/cleaned.csv 已经存在且比输入新,Snakemake 会跳过不跑。嗯,增量构建的灵魂就在这里。

用 conda 环境封装备忘

为了可重复性,每个步骤最好声明自己的 conda 环境。在 Snakefile 里这样写:

rule clean_csv:
    input: "data/raw.csv"
    output: "output/cleaned.csv"
    conda: "envs/clean.yaml"
    shell: "python scripts/clean.py {input} {output}"

对应的 envs/clean.yaml 文件:

channels:
  - conda-forge
  - bioconda
dependencies:
  - python=3.9
  - pandas=1.5
  - numpy=1.24

运行时加上 --use-conda 参数:

snakemake --use-conda -c1
提示: 第一次运行时 Snakemake 会自动创建 conda 环境并安装依赖,后续跑就不会重复安装了。我在一个特征工程项目中用了 12 个不同的环境,每个规则独立的依赖完全隔离,再也没出现过依赖冲突。

1.4 Snakemake 工作流核心概念图

下面这张图把 Snakemake 工作流的核心组件和关系捋清楚,你看一眼就能明白整体骨架。

Snakemake 工作流核心概念 Snakefile(配置定义) 规则(Rule) 规则(Rule) 规则(Rule) input: raw.csv output: clean.parquet shell / run / script input: clean.parquet output: features.parquet conda: envs/feat.yaml input: features.parquet output: model.pt shell: train.py {input} 核心机制:自动解析 DAG + 增量构建 • 输入输出: 规则通过 input/output 声明依赖关系 • 条件执行: 输出已存在且比所有输入新 → 跳过 • 环境隔离: conda: 声明环境,--use-conda 自动切换

1.5 环境配置总结

上面这些够你跑起来了。我再贴一个我常用的完整环境初始化步骤,直接复制执行:

# 创建独立环境
conda create -n fe-snakemake python=3.9 -y
conda activate fe-snakemake

# 安装 snakemake 核心
conda install -c bioconda snakemake=7.32.4 -y

# 可选:可视化 dag
conda install -c conda-forge graphviz -y

# 验证
snakemake --version
注意: 如果你在 Windows 上用 Snakemake,建议在 WSL2 里运行,因为 Snakemake 很多功能(比如信号处理、进程管理)在原生 Windows 下有限制。我有个同事硬在 Windows cmd 里折腾了两天没跑通,切到 WSL2 十分钟就搞定了。

好了,基础环境和概念先讲到这里。有了 Snakefile 和规则的直觉,后面章节我们会一步步构建一个完整的特征工程流水线——从数据清洗到衍生计算,再到自动化调度。这部分内容经得起实际项目考验,你别看它简单,底层依赖管理的能力足够应付生产级别的特征工程管道。