BIOM 格式概述:从数据沼泽到标准化

如果你做过微生物组分析,多半遇到过这种场景:一个流程产出 OTU 表格,另一个工具只认 BIOM,中间还得写脚本拼格式。说实话,我早年也踩过这个坑。那时候项目赶进度,手写了一个 CSV 转 JSON 的解析器,结果样本名里多了个空格,整个下游分析全错了……从那天起,我就养成了“能用 BIOM 绝不用自定格式”的习惯。

BIOM 到底是什么?简单说,它就是微生物组数据的“普通话”。

1.1 什么是 BIOM 格式

BIOM 全称 Biological Observation Matrix,一种专门为生物观测数据(物种丰度、基因丰度、功能通路等)设计的标准存储格式。它把核心数据存成一个 观测 × 样本 的稀疏或稠密矩阵,同时附带观测元数据和样本元数据。嗯,这听起来很像关系数据库的一张表,但它在存储效率、工具兼容性上做了大量优化。

目前 BIOM 有两种载体:

  • JSON 格式(BIOM 1.0):人类可读,适合小数据集(<1万行×1千列)。
  • HDF5 格式(BIOM 2.0/2.1):二进制,支持分块压缩、大矩阵、并行 I/O。我现在的项目数据量动辄上亿条,不用 HDF5 版本根本跑不动。
核心结构:一个 BIOM 文件包含三部分 —— 主矩阵(稀疏表示的行、列、值)、观测元数据(例如 OTU 的分类注释)、样本元数据(例如样本的分组、pH、温度)。三者缺一不可,但可以没有元数据字段。

我们来看一个简化的 BIOM 1.0 JSON 片段,感受一下骨架:

{
  "id": "MyStudy",
  "format": "Biological Observation Matrix 1.0.0",
  "matrix_type": "dense",
  "shape": [5, 3],
  "rows": [
    {"id": "OTU1", "metadata": {"taxonomy": ["Bacteria","Firmicutes"]}},
    {"id": "OTU2", "metadata": {"taxonomy": ["Bacteria","Bacteroidetes"]}}
  ],
  "columns": [
    {"id": "S1", "metadata": {"treatment": "control"}},
    {"id": "S2", "metadata": {"treatment": "treated"}}
  ],
  "data": [[100, 200, 50], [30, 0, 120]]
}

要点:rows 对应观测(OTU/ASV/基因),columns 对应样本,data 按行主序存储丰度值。空值用 0 填充,稀疏时可以用 sparse 类型节省空间。

1.2 发展历史:从 JSON 试水到 HDF5 扛鼎

2012 年,QIIME 和 MG-RAST 团队联合提出了 BIOM 1.0。当时大家只是想要一个“能放 OTU 表、能挂分类注释”的通用格式。你想想看,前 BIOM 时代,每个工具都有自己的 CSV 风格,列顺序、分隔符、注释行都不一样,整合起来简直噩梦。

我记得 2014 年有个合作项目,对方给了个“BIOM”文件,结果打开一看,只是把 CSV 改了个后缀……那次之后我写了一个自动校验脚本,专门检查 JSON 结构是否合法。避坑指南:永远不要信任文件名,要用 biom validate 验证。

2015 年 BIOM 2.0 引入 HDF5,解决了两个痛点:

  • 文件大小降到原来的 10%~30%(压缩 + 二进制)
  • 支持 10 万以上观测的随机访问,不用全量加载

到 2017 年,QIIME 2 彻底拥抱 BIOM 2.1,HDF5 成为主流。现在几乎所有的微生物组分析流程——QIIME 2、MEGAN、PICRUSt2、LEfSe——都原生支持 BIOM。

兼容坑:BIOM 1.0 和 2.x 的读写 API 不通用。我曾经拿一个 1.0 的 JSON 文件直接传给要求 HDF5 的 pipeline,卡了两小时找 bug。后来强制在流程里加了一步自动转格式。

下面这张表格能帮你快速对比两个版本:

维度 BIOM 1.0 (JSON) BIOM 2.0+ (HDF5)
存储方式 文本 JSON 二进制 HDF5
最大数据量 适合 < 2 GB TB 级无压力
压缩 gzip 可外部压缩 内置压缩滤镜
随机访问 需全量解析 支持子矩阵切片
主流工具支持 QIIME 1 遗留 QIIME 2, MEGAN 6+

1.3 在微生物组研究中的作用

说白了,BIOM 格式解决了三个核心问题:标准化、可扩展性、工具互操作。

  • 标准化:不管你是用 DADA2、mothur 还是 QIIME 2 生成的 OTU 表,最终都能导出为 BIOM 格式。下游的多样性计算、差异分析、可视化工具开箱即读。
  • 可扩展性:观测元数据不限于分类学,可以塞进功能注释(KEGG、COG)、置信度、序列哈希。样本元数据可以放任何分组或环境变量。这种灵活性让 BIOM 成了微生物组数据事实上的交换格式。
  • 工具互操:在 Python 生态里,biom-format 包提供完整 API;R 用户可以通过 biomformat 包或 phyloseq 直接读入;命令行工具 biom 可以转换、合并、子集、验证。
我的习惯:每次分析开始前,先用 biom summarize-table 看一眼 BIOM 文件的统计摘要——观测数、样本数、稀疏度、元数据缺失情况。这个过程花不了 10 秒,但能提前发现 80% 的格式错误。
BIOM 文件核心结构及工具生态 BIOM 文件 观测矩阵 观测元数据 样本元数据 行=OTU/ASV/基因 列=样本 值=丰度 分类注释(门纲目科属种) 功能通路 序列哈希 分组(对照/处理) 环境变量(pH、温度) 测序批次 QIIME 2 MEGAN PICRUSt2 LEfSe 主流微生物组分析工具均支持 BIOM 格式的读取与写入

这张图基本概括了 BIOM 的内部构成和它在工具链中的位置。你拿到一个 BIOM 文件,第一步就是搞清楚它的矩阵稀疏度和元数据完整性。我见过不少新手直接拿 BIOM 跑 α 多样性,结果发现样本分组信息根本没挂进去——跑出来的图全是灰色的。所以后面几章我们会手把手教你如何生成、验证、转换 BIOM 格式。