Arboreto 基因调控网络推断实战指南:基于 GRNBoost2/GENIE3 的可扩展 GRN 推断(scientific-agent-skills 系列)
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
导读
本文聚焦于本仓库(scientific-agent-skills)中 Arboreto 技能 所封装的基因调控网络(Gene Regulatory Network, GRN)推断能力:基于基因表达数据(bulk RNA-seq、单细胞 RNA-seq),推断哪些转录因子(TF)调控哪些靶基因,输出「TF–target–importance」三元组。你将掌握 Arboreto 的安装与数据格式约定、GRNBoost2 与 GENIE3 两种算法的选型与完整参数、从本地多核到远程 Dask 集群的分布式运行方式、以及与 pySCENIC 的集成用法;同时结合仓库内的参考文档、可直接运行的 CLI 脚本与契约测试,理解底层调用约定与可复现的实践要点。
一、Arboreto 是什么:GRN 推断的核心能力
Arboreto 是 Aerts Lab 出品的 Python 库,用于从基因表达数据推断基因调控网络。它通过 Dask 将基于树的集成回归(GRNBoost2、GENIE3)并行化到本地多核或远程集群上执行。
核心能力:根据多个观测(细胞、样本、条件)上的表达模式,判定哪些转录因子(TF)调控哪些靶基因,输出带重要性得分的候选调控边。这一结果通常作为下游模块分析(如 pySCENIC 的 cisTarget 剪枝、regulon 定义、AUCell 打分)的输入。
仓库在 docs/skills.md 中把该技能定位为:面向 bulk 或单细胞表达矩阵,基于共表达模式推断 TF–target 调控边,支持 pandas DataFrame、稠密 NumPy 数组与稀疏 CSC 矩阵(cells × genes)三种输入,具备 TF 限定搜索、limittop-N 输出以及diy()自定义回归器等特性,是 pySCENIC 的核心推断引擎。
依赖与版本背景
- PyPI 上游最新版本为0.1.6(2021-02-09),依赖自上游
requirements.txt:dask[complete]、distributed、numpy、pandas、scikit-learn、scipy。 - 主要下游消费者是 pySCENIC:pySCENIC 0.11+ 将稀疏表达矩阵直接传给
grnboost2/genie3;pySCENIC 0.12+ 默认改用arboreto_with_multiprocessing.py(不依赖 Dask)。当需要 Dask 分布式扩展能力时,应使用独立安装的 arboreto。
事实边界说明:上述版本号、下游关系来自本仓库 SKILL.md 的说明;使用本技能前请确认实际安装的 arboreto 版本与数据规模匹配。
二、快速上手:安装与第一次 GRN 推断
安装
推荐通过uv安装:
uv pip install arboreto亦可通过 Conda(Bioconda)安装:
conda install -c bioconda arboreto最小推理示例
SKILL.md 提供了最小化的 GRNBoost2 推理流程。基本步骤为:加载表达数据(基因列为列名)→ 调用grnboost2→ 保存无表头的三列结果:
import pandas as pd from arboreto.algo import grnboost2 if __name__ == '__main__': # Load expression data (genes as columns) expression_matrix = pd.read_csv('expression_data.tsv', sep='\t') # Infer regulatory network network = grnboost2(expression_data=expression_matrix) # Save results (TF, target, importance) network.to_csv('network.tsv', sep='\t', index=False, header=False)关键约束:因为 Dask 在内部会 spawn 新进程,脚本必须加上if __name__ == '__main__':保护(尤其 Windows/macOS 使用 spawn 多进程时),否则会触发 Dask 报错。这一要求既是 SKILL.md 中的显式警告,也在 references/basic_inference.md 中被重复强调。
直接使用仓库提供的 CLI 脚本
SKILL.md 还封装了一个开箱即用的命令行工具 basic_grn_inference.py,它把上述流程参数化为四个选项:
python skills/arboreto/scripts/basic_grn_inference.py expression_data.tsv output_network.tsv \ --tf-file tfs.txt \ --seed 777 \ --limit 5000脚本实际执行时还会打印表达矩阵形状(基因数 = 列数、观测数 = 行数)、TF 数量、最终包含的调控链接条数以及 Top 10 链接预览,便于快速核对结果。其运行约定由仓库测试 test_scripts.py 逐一校验,见下文「源码与契约验证」小节。
三、输入数据格式与数据准备
GRN 推断对输入矩阵的布局有硬性约定,这是最容易出错也最容易排查的一步。Arboreto 接受三种输入,行均为观测(细胞/样本/条件),列均为基因:
1. pandas DataFrame(推荐)
- 行 = 观测;列 = 基因,且基因名必须作为列头(列名)
- 值为数值型表达量
import pandas as pd # Load expression matrix with genes as columns expression_matrix = pd.read_csv('expression_data.tsv', sep='\t') # Columns: ['gene1', 'gene2', 'gene3', ...] # Rows: observation data2. 稠密 NumPy 数组
- 形状为
(observations, genes) - 必须另行提供与列顺序一致、长度相同的
gene_names列表
import numpy as np expression_matrix = np.genfromtxt('expression_data.tsv', delimiter='\t', skip_header=1) with open('expression_data.tsv') as f: gene_names = [gene.strip() for gene in f.readline().split('\t')] assert expression_matrix.shape[1] == len(gene_names)3. 稀疏 CSC 矩阵(arboreto 0.1.6+)
scipy.sparse.csc_matrix,形状(observations, genes)- 同样必须传
gene_names,且与列顺序匹配 - 适用场景:大规模单细胞矩阵;pySCENIC 0.11+ 开启
--sparse时亦采用此格式
import scipy.sparse as sp from arboreto.algo import grnboost2 # expression_sparse: csc_matrix, cells x genes network = grnboost2( expression_data=expression_sparse, gene_names=gene_names, tf_names=tf_names, )转录因子列表(可选)
通过 TF 列表将候选调控因子限定在一个子集内,可显著减少计算量:
from arboreto.utils import load_tf_names # Load from file (one TF per line) tf_names = load_tf_names('transcription_factors.txt') # Or define directly tf_names = ['TF1', 'TF2', 'TF3']TF 参数语义存在一个极易踩坑的细节:若tf_names为None或'all',则所有gene_names都被当作潜在调控因子;传入空列表[]则会产生空网络且不报任何错误。仓库测试 test_scripts.py 的模块 docstring 特别指出了这一「静默失败」陷阱,并断言包装脚本在未提供 TF 文件时以字符串'all'(而非空列表)作为哨兵传给grnboost2。
四、算法选型:GRNBoost2 vs GENIE3 vs diy()
Arboreto 的两个高层算法共享同一套多重回归推断策略:
- 对数据集中每个靶基因训练一个回归模型;
- 从模型中提取最重要的特征(潜在调控因子);
- 将特征作为候选调控因子连同重要性分数输出。
两者的差异集中在底层回归方法与计算效率上。详细对比见 references/algorithms.md。
GRNBoost2(默认推荐)
- 方法:随机梯度提升(gradient boosting),带早停正则化(early-stopping window)
- 优势:专为大样本优化(1 万+ 观测,如单细胞 RNA-seq),速度显著快于 GENIE3
- 定位:旗舰算法,多数分析的默认选择
from arboreto.algo import grnboost2 network = grnboost2( expression_data=expression_matrix, tf_names=tf_names, seed=42, limit=5000, )GENIE3
- 方法:随机森林(Random Forest)回归;
diy模式可选 ExtraTrees - 优势:原始多重回归思路的经典实现,结果稳健、文献可比
- 定位:小到中等数据集、与已发表 GENIE3 结果对比、对 GRNBoost2 结果做交叉验证
from arboreto.algo import genie3 network = genie3( expression_data=expression_matrix, tf_names=tf_names, seed=42, )参数对照
| 参数 | grnboost2 | genie3 | 说明 |
|---|---|---|---|
expression_data | ✔ | ✔ | DataFrame / ndarray /scipy.sparse.csc_matrix |
gene_names | ✔ | ✔ | 数组/稀疏输入必须显式传入 |
tf_names | ✔ | ✔ | 默认'all';None/'all'→ 所有基因均可作调控因子 |
client_or_address | ✔ | ✔ | 'local'、Dask scheduler 地址或 Dask Client 对象 |
limit | ✔ | ✔ | 全局返回 top-N 条调控边 |
seed | ✔ | ✔ | 随机种子;None则不可复现 |
verbose | ✔ | ✔ | 进度日志 |
early_stop_window_length | ✔(仅 GRNBoost2) | ✖ | 早停观察窗口(默认 25) |
diy():自定义回归器的高级用法
当需要非默认的 scikit-learn 回归器超参数时,使用diy()(注意:不要试图把自定义超参塞进grnboost2/genie3的 kwargs):
from arboreto.algo import diy from arboreto.core import SGBM_KWARGS, RF_KWARGS # Custom GRNBoost2-style run custom_gbm = diy( expression_data=expression_matrix, regressor_type='GBM', # 'RF', 'GBM', or 'ET' regressor_kwargs={ **SGBM_KWARGS, 'n_estimators': 100, 'max_depth': 5, 'learning_rate': 0.1, }, tf_names=tf_names, seed=42, ) # Custom GENIE3-style run custom_rf = diy( expression_data=expression_matrix, regressor_type='RF', regressor_kwargs={ **RF_KWARGS, 'n_estimators': 1000, 'max_features': 'sqrt', }, tf_names=tf_names, )建议从arboreto.core导入默认 kwargs(SGBM_KWARGS/RF_KWARGS)后按需覆写个别键,避免遗漏关键默认配置。
选型决策指引
- 默认从 GRNBoost2 开始——更快、更适合大规模单细胞数据;
- 使用 GENIE3:与既有 GENIE3 文献直接对比、数据集为中小规模、或需要验证 GRNBoost2 结果时;
- 使用
diy():需要非默认回归器超参数时。
两个算法输出格式一致(同为三列调控边),可无缝对比。
五、分布式计算:从本地多核到远程集群
GRN 推断天然可并行:每个靶基因的回归模型可独立训练。Arboreto 把计算表示为 Dask 任务图,再分配到可用资源上执行。完整讨论见 references/distributed_computing.md。
本地多核(默认)
未指定客户端时,自动使用本地全部可用 CPU 核,无需任何额外配置,满足大多数场景:
from arboreto.algo import grnboost2 # Automatically uses all local cores network = grnboost2(expression_data=expression_matrix, tf_names=tf_names)自定义本地 Dask Client(精细控制资源)
通过LocalCluster精确限制进程数与每进程内存:
from distributed import LocalCluster, Client from arboreto.algo import grnboost2 if __name__ == '__main__': # Configure local cluster local_cluster = LocalCluster( n_workers=10, # Number of worker processes threads_per_worker=1, # Threads per worker memory_limit='8GB' # Memory limit per worker ) # Create client custom_client = Client(local_cluster) # Run inference with custom client network = grnboost2( expression_data=expression_matrix, tf_names=tf_names, client_or_address=custom_client ) # Clean up custom_client.close() local_cluster.close()自定义 Client 的三点收益:资源控制(限制 CPU/内存占用)、多轮复用(同一 Client 跑多组参数/算法)、可视化监控(访问 Dask dashboard)。复用同一 Client 做多次推断(不同 seed、不同算法)时,仅需初始化/关闭一次:
if __name__ == '__main__': local_cluster = LocalCluster(n_workers=8, threads_per_worker=1) client = Client(local_cluster) network_seed1 = grnboost2(expression_data=expression_matrix, tf_names=tf_names, client_or_address=client, seed=666) network_seed2 = grnboost2(expression_data=expression_matrix, tf_names=tf_names, client_or_address=client, seed=777) from arboreto.algo import genie3 network_genie3 = genie3(expression_data=expression_matrix, tf_names=tf_names, client_or_address=client) client.close() local_cluster.close()远程 Dask 集群
对超大数据集,将 Client 指向集群调度器即可:
Step 1— 在集群头节点启动 scheduler:
dask-scheduler # Output: Scheduler at tcp://10.118.224.134:8786Step 2— 在计算节点启动 workers:
dask-worker tcp://10.118.224.134:8786Step 3— 从客户端连接并推理:
from distributed import Client from arboreto.algo import grnboost2 if __name__ == '__main__': scheduler_address = 'tcp://10.118.224.134:8786' cluster_client = Client(scheduler_address) network = grnboost2( expression_data=expression_matrix, tf_names=tf_names, client_or_address=cluster_client ) cluster_client.close()集群配置建议(来自 references/distributed_computing.md):
dask-worker tcp://scheduler:8786 \ --nprocs 4 \ # Number of processes per node --nthreads 1 \ # Threads per process --memory-limit 16GB # Memory per process- 大规模推断:用「更多 worker + 适中内存」优于「少量 worker + 超大内存」;
- 设
threads_per_worker=1,避免 scikit-learn 内部的 GIL 争用; - 持续监控 worker 内存,防止进程被系统杀掉。
监控与调试
创建默认Client()会打印 dashboard 地址(默认http://localhost:8787/status),可实时观察:任务进度、每 worker 的 CPU/内存占用、任务流可视化和瓶颈定位。推断时可开启verbose=True输出进度日志。
性能优化要点汇总
- 数据格式:pandas DataFrame 比 NumPy 更适合 Dask 操作;推断前过滤低方差基因以压缩数据量;
- Worker 配置:CPU 密集任务 →
threads_per_worker=1并提高n_workers;内存密集任务 → 提高单 workermemory_limit; - 集群环境:保证节点间高带宽低延迟;大数据集使用共享文件系统或对象存储;为调度器分配专用节点避免资源争抢;
- TF 过滤:显式提供已知 TF 列表可大幅缩短计算时间:
# Full search (slow) network = grnboost2(expression_data=matrix) # Filtered search (faster) network = grnboost2(expression_data=matrix, tf_names=known_tfs)大规模单细胞端到端示例
from distributed import Client from arboreto.algo import grnboost2 import pandas as pd if __name__ == '__main__': # Connect to cluster client = Client('tcp://cluster-scheduler:8786') # Load large single-cell dataset (50,000 cells x 20,000 genes) expression_data = pd.read_csv('scrnaseq_data.tsv', sep='\t') # Load cell-type-specific TFs tf_names = pd.read_csv('tf_list.txt', header=None)[0].tolist() # Run distributed inference network = grnboost2( expression_data=expression_data, tf_names=tf_names, client_or_address=client, verbose=True, seed=42 ) network.to_csv('grn_results.tsv', sep='\t', index=False) client.close()这类集群化流程使单机难以承载的数据集(数万细胞 × 数万基因)具备分析可行性。
六、典型应用场景实战
场景 1:单细胞 RNA-seq 调控网络
对每个细胞类型推断特异性的调控网络,并用重要性阈值筛选高置信链接:
import pandas as pd from arboreto.algo import grnboost2 if __name__ == '__main__': # Load single-cell expression matrix (cells x genes) sc_data = pd.read_csv('scrna_counts.tsv', sep='\t') # Infer cell-type-specific regulatory network network = grnboost2(expression_data=sc_data, seed=42) # Filter high-confidence links high_confidence = network[network['importance'] > 0.5] high_confidence.to_csv('grn_high_confidence.tsv', sep='\t', index=False)场景 2:Bulk RNA-seq + TF 限定
用load_tf_names载入物种 TF 列表,将候选调控因子限定到已知转录因子:
from arboreto.utils import load_tf_names from arboreto.algo import grnboost2 if __name__ == '__main__': expression_data = pd.read_csv('rnaseq_tpm.tsv', sep='\t') tf_names = load_tf_names('human_tfs.txt') network = grnboost2( expression_data=expression_data, tf_names=tf_names, seed=123 ) network.to_csv('tf_target_network.tsv', sep='\t', index=False)场景 3:多条件对比分析
对多个处理条件分别推断,产出可比对的网络集合:
from arboreto.algo import grnboost2 if __name__ == '__main__': conditions = ['control', 'treatment_24h', 'treatment_48h'] for condition in conditions: data = pd.read_csv(f'{condition}_expression.tsv', sep='\t') network = grnboost2(expression_data=data, seed=42) network.to_csv(f'{condition}_network.tsv', sep='\t', index=False)七、输出格式与结果解读
grnboost2/genie3返回一个三列 pandas DataFrame:
| 列名 | 含义 |
|---|---|
TF | 转录因子(调控因子) |
target | 靶基因 |
importance | 调控重要性分数(值越大表示调控信号越强) |
输出示例(references/basic_inference.md):
TF1 gene5 0.856 TF2 gene12 0.743 TF1 gene8 0.621需要注意的是,Arboreto 下游消费者期望的是无表头、制表符分隔的三列文本;因此仓库内脚本与示例均以to_csv(..., sep='\t', index=False, header=False)落盘,测试 test_scripts.py 专门断言了「输出无importance表头、每行恰好三列」的契约。
链接筛选策略
- 推断期全局截断:
limit=N只返回全局重要性最高的 N 条链接; - 事后阈值:按
importance阈值过滤(如 > 0.5); - 每个靶基因的 top 链接:
network.groupby('target')取每组前几; - 统计显著性:基于置换检验等外部工具做显著性评估(Arboreto 本身不直接提供)。
八、与 pySCENIC 的集成
Arboreto 承担 pySCENIC 流程中的GRN 推断(第一步)。一个典型协作方式:先用 arboreto 独立推断共表达模块,再交给 pySCENIC 的 cisTarget 剪枝与 regulon 定义;pySCENIC 0.11+ 直接向grnboost2/genie3传稀疏表达矩阵,pySCENIC 0.12+ 默认改用arboreto_with_multiprocessing.py(不依赖 Dask)。需要 Dask 扩展时,独立使用 arboreto 即可。
# Standalone: infer co-expression modules before pySCENIC cisTarget pruning from arboreto.algo import grnboost2 network = grnboost2(expression_data=expression_df, tf_names=tf_list, limit=5000) # Downstream: pySCENIC ctx pruning, regulon definition, AUCell (see pySCENIC docs)若上游数据来自 scanpy 的 AnnData,可直接转为 DataFrame(cells × genes)喂给 arboreto:
expression_df = adata.to_df() # cells x genes九、可复现性
设置固定种子
不设置seed时每个回归器使用随机种子,结果不可复现;固定种子后每次运行结果一致:
network = grnboost2(expression_data=matrix, seed=777)多种子鲁棒性分析与共识网络
对多个种子分别运行,再把各次结果合并取「TF–target」对的均值重要性,并按阈值过滤得到共识网络:
from distributed import LocalCluster, Client if __name__ == '__main__': client = Client(LocalCluster()) seeds = [42, 123, 777] networks = [] for seed in seeds: net = grnboost2(expression_data=matrix, client_or_address=client, seed=seed) networks.append(net) import pandas as pd combined = pd.concat(networks) consensus = ( combined.groupby(['TF', 'target'], as_index=False)['importance'] .mean() .query('importance > 0.5') )十、源码与契约验证:仓库内的证据链
本技能不仅提供文档,还配有一套可运行的脚本与契约测试,让「文档所述的参数行为」获得可执行验证。
CLI 包装脚本:basic_grn_inference.py 核心逻辑集中在run_grn_inference(L25-L67),它以「genes-as-columns」方式读入 TSV(L37),未给 TF 文件时用tf_names = 'all'(L44-L47),随后一次性把seed、limit、verbose转发给grnboost2(L52-L58),最后以sep='\t', index=False, header=False落盘(L62)。
契约测试:test_scripts.py 因为真实 GRNBoost2 属于分钟级分布式任务,故用mock桩住grnboost2,转而校验包装器与算法之间的契约:
- 表达矩阵被按「基因作为列」读取,基因列顺序被原样保留(
test_the_expression_matrix_is_read_with_genes_as_columns,见 L71-L75); - 未给 TF 文件时哨兵是字符串
'all',空列表会静默产出空网络(test_without_a_tf_file_every_gene_is_a_candidate_regulator,L77-L81); - TF 文件会限制候选调控因子列表(L83-L87);
seed(默认 777)与limit(默认None= 不限)被正确转发(L89-L95);- 输出为无表头、制表符分隔的三列,且不写入行索引列(L97-L109)——这正是下游 Arboreto 消费方(含 pySCENIC)期望的格式。
这意味着你在本仓库中基于 SKILL.md 所看到的全部参数与输出约定,都有测试代码背书;如果你把该脚本接入自己的分析管道,可把上述断言当作格式回归基准。
十一、常见问题排查(Troubleshooting)
| 症状 | 原因与对策 |
|---|---|
| 内存错误 | 过滤低方差基因缩小数据集;或启用分布式计算分散内存压力 |
| 速度慢 | 改用 GRNBoost2 而非 GENIE3;启动 Dask Client;缩小 TF 列表(TF 越少回归次数越少) |
| Dask 报错 | 确认脚本有if __name__ == '__main__':保护——Windows/macOS 基于 spawn 的多进程必须如此 |
| 结果为空 | 检查数据布局(基因必须是列);核对 TF 名称与表达矩阵的列名完全一致;切勿把tf_names传成空列表(应以None/'all'表达「全部基因皆可为调控因子」) |
| 稀疏数据问题 | 使用scipy.sparse.csc_matrix并同步传入匹配的gene_names;稀疏支持自 arboreto 0.1.6 / pySCENIC 0.11 起可用 |
| 输出列名/格式异常 | 保存时用to_csv(path, sep='\t', index=False, header=False),保证下游(如 pySCENIC 相关工具)按无表头三列解析 |
结语
在 scientific-agent-skills 仓库中,Arboreto 技能 将「表达数据 → 调控网络」这一转录组核心分析步骤封装为一套可复现、可扩展的工程化能力:三种输入格式适配 DataFrame/NumPy/稀疏矩阵,GRNBoost2 与 GENIE3 覆盖从大规模单细胞到小样本对比的全部场景,diy()开放自定义回归器以对接精细调参需求,Dask 任务图则让推断从笔记本平滑迁移到集群。配合本仓库自带的 references 系列、CLI 脚本 与契约测试,你可以在任何具备该 Python 环境的机器上快速复现 GRN 推断流程,并将结果无缝衔接给 pySCENIC 或自行设计的下游调控分析。
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考