生物医学网络科学Biomedical Network Science
Example05 / 13

AP-MS 拉下数据的 spoke 模型与 matrix 模型

所属专题
生物分子网络与拓扑特征
下载
Notebook · .py

模拟 40 个蛋白复合物(每个 3–8 个亚基,复合物内部的“真实二元接触”是一棵随机生成树加少量额外边), 对随机选取的 30% 蛋白做“诱饵”拉下实验:拉下的是诱饵所在复合物的全部成员(检出率 0.8)。 spoke 模型只连 诱饵–猎物;matrix 模型把同一次拉下的所有蛋白两两相连。 输出解读:matrix 模型的边数约为 spoke 的两倍,覆盖的直接接触更多,但“非直接接触”的边也成倍增加; 在这个模拟中两种模型对直接接触的精确率都只有约 4 成。两者都把“共复合物”当成边, 因此都不等于二元相互作用图(Y2H 测的那一类);复合物越大,matrix 模型引入的间接边越多(约按 s² 增长)。

Output输出图

AP-MS 拉下数据的 spoke 模型与 matrix 模型:输出图 1

Output文字输出

spoke :边数 =  256,直接接触 =  111,非直接 =  145(精确率 0.43),覆盖全部直接接触的比例 = 0.42
matrix:边数 =  495,直接接触 =  213,非直接 =  282(精确率 0.43),覆盖全部直接接触的比例 = 0.80
真实直接接触总数 = 265;蛋白数 = 232;诱饵数 = 69

Code代码

# 模拟 40 个蛋白复合物(每个 3–8 个亚基,复合物内部的“真实二元接触”是一棵随机生成树加少量额外边),
# 对随机选取的 30% 蛋白做“诱饵”拉下实验:拉下的是诱饵所在复合物的全部成员(检出率 0.8)。
# spoke 模型只连 诱饵–猎物;matrix 模型把同一次拉下的所有蛋白两两相连。
# 输出解读:matrix 模型的边数约为 spoke 的两倍,覆盖的直接接触更多,但“非直接接触”的边也成倍增加;
# 在这个模拟中两种模型对直接接触的精确率都只有约 4 成。两者都把“共复合物”当成边,
# 因此都不等于二元相互作用图(Y2H 测的那一类);复合物越大,matrix 模型引入的间接边越多(约按 s² 增长)。
import itertools
import numpy as np
import networkx as nx

rng = np.random.default_rng(3)
complexes, binary = [], set()
next_id = 0
for _ in range(40):                                  # 模拟数据,仅用于演示方法
    s = int(rng.integers(3, 9))
    members = list(range(next_id, next_id + s)); next_id += s
    complexes.append(members)
    T = nx.random_labeled_tree(s, seed=int(rng.integers(1e9))) if hasattr(nx, "random_labeled_tree") \
        else nx.random_tree(s, seed=int(rng.integers(1e9)))
    for a, b in T.edges():
        binary.add(frozenset((members[a], members[b])))
    for a, b in itertools.combinations(members, 2):  # 少量额外的直接接触
        if rng.random() < 0.15:
            binary.add(frozenset((a, b)))
member_of = {p: c for c in complexes for p in c}
proteins = np.arange(next_id)
baits = rng.choice(proteins, size=int(0.3 * len(proteins)), replace=False)

spoke, matrix = set(), set()
for b in baits:
    preys = [p for p in member_of[b] if p != b and rng.random() < 0.8]
    spoke |= {frozenset((b, p)) for p in preys}
    matrix |= {frozenset(e) for e in itertools.combinations([b] + preys, 2)}

for name, E in [("spoke", spoke), ("matrix", matrix)]:
    tp = len(E & binary)
    print(f"{name:6s}:边数 = {len(E):4d},直接接触 = {tp:4d},非直接 = {len(E) - tp:4d}"
          f"(精确率 {tp / len(E):.2f}),覆盖全部直接接触的比例 = {tp / len(binary):.2f}")
print(f"真实直接接触总数 = {len(binary)};蛋白数 = {len(proteins)};诱饵数 = {len(baits)}")

import matplotlib.pyplot as plt
tps = [len(E & binary) for E in (spoke, matrix)]
fps = [len(E) - t for E, t in zip((spoke, matrix), tps)]
fig, ax = plt.subplots(figsize=(6.4, 4.2))
ax.bar(["spoke", "matrix"], tps, width=0.5, color="C0", label="direct (binary) contact")
ax.bar(["spoke", "matrix"], fps, width=0.5, bottom=tps, color="0.75", label="indirect (co-complex only)")
ax.axhline(len(binary), color="k", ls="--", lw=1, label="all true binary contacts")
ax.set_ylabel("number of inferred edges")
ax.set_title("Matrix model adds many indirect edges"); ax.legend()
plt.tight_layout(); plt.show()

Run在浏览器中运行

首次加载 Python 环境约需 20–40 秒;可以修改参数后重新运行。

AP-MS 拉下数据的 spoke 模型与 matrix 模型