最近在系统学习计算辅助药物设计这块内容,拿到一份 2026 版的 AI 虚拟筛选与生信全套视频课程,整体看下来内容覆盖确实比较全。这套课程从生信环境搭建、分子数据处理、分子对接,到 AI 模型训练和虚拟筛选实战都有涉及,视频、代码、数据集打包在一起,很适合零基础入门后再逐步进阶。本文就把这套课程的核心学习路线和关键知识点整理成一份可复用的技术笔记,包含完整代码示例、运行思路和常见的排错方案,不管是刚接触虚拟筛选的新手,还是已经在做生信分析想补 AI 方向的开发者,都可以直接参考。
1. 虚拟筛选到底是什么
1.1 从一个药物发现场景说起
传统药物发现流程中,研究人员需要从海量化合物里寻找能够与靶点蛋白结合并调节其活性的小分子。这个过程如果全靠湿实验逐一验证,成本高、周期长、成功率也不稳定。为了缩小候选化合物范围,计算模拟方法被引入到药物研发早期阶段。虚拟筛选,就是通过计算机从大规模化合物库中挑选出可能具有活性的分子,再将这些候选分子交给实验人员做进一步验证。
虚拟筛选不是要替代实验,而是要降低实验筛选的试错成本。它可以基于已知活性分子的结构特征去搜索相似分子,也可以基于靶点蛋白的三维结构去预测小分子与蛋白的结合模式。前者的代表方法是基于配体的虚拟筛选,后者的代表方法是基于结构的虚拟筛选。实际项目中,两种方法经常组合使用,先根据结构做初步筛选,再用相似性方法做二次排序。
1.2 为什么现在 AI 虚拟筛选这么热
AI 与虚拟筛选结合之后,整个流程又发生了很大的变化。传统的打分函数大多基于物理化学经验公式,计算速度快但精度有限;AI 模型则可以从大量已知活性数据中自动学习分子与蛋白相互作用的特征,在打分精度、活性预测和分子生成方面表现出更强的潜力。
目前 AI 在虚拟筛选中的典型应用包括:
- 用深度学习模型预测分子活性,例如基于分子指纹或图结构的分类、回归模型;
- 用生成模型设计全新分子,例如 VAE、GAN 或强化学习生成满足活性约束的候选结构;
- 用机器学习对分子对接结果进行重打分,提升虚拟筛选富集率;
- 用图神经网络建模分子结构,捕捉原子与化学键之间的拓扑关系。
课程前半部分先不讲这些复杂的算法,而是从数据、工具、基本流程入手,把基础打牢后再进入模型部分。这在学习路线上是合理的,因为 AI 模型训练的输入数据本质上就是分子结构和活性数据,如果基础数据规范没做好,模型效果很难保证。
1.3 虚拟筛选的标准流程
一个完整的虚拟筛选流程通常包含以下步骤:
- 获取靶点蛋白结构:从 PDB 数据库下载蛋白晶体结构,或通过同源建模获得受体结构;
- 准备蛋白结构:去除水分子、添加氢原子、修补缺失残基、定义结合口袋;
- 构建小分子化合物库:来源包括 ZINC、ChEMBL、Enamine REAL 等公开库,也可以是自建库;
- 小分子预处理:生成 3D 构象、分配质子化状态、计算部分电荷;
- 分子对接或 AI 预测:将小分子对接到结合口袋,计算结合亲和力或直接用模型打分;
- 结果分析:对打分排序、聚类分析、目视检查关键相互作用,挑选候选分子。
这套课程的所有实战内容基本都围绕这个流程展开,下面我们按照同样顺序来拆解。
2. 环境准备与工具链选型
2.1 基础运行环境
虚拟筛选涉及分子处理、对接和 AI 模型训练,环境配置是整个流程中最容易劝退新手的环节。课程中推荐的环境方案如下,具体版本可根据实际情况调整。
操作系统建议使用 Linux 或 Windows WSL2,因为分子对接和深度学习框架在 Linux 下的兼容性最好。如果只做轻量学习,Windows 也可以运行,但要注意部分对接程序的编译环境依赖。
Python 环境建议使用 Anaconda 管理,创建独立虚拟环境,避免依赖冲突。核心依赖包括:
- RDKit:分子结构处理工具包,处理 SMILES、SDF、分子指纹等;
- NumPy / Pandas:数据处理;
- Matplotlib / Seaborn:结果可视化;
- scikit-learn:传统机器学习模型;
- PyTorch / TensorFlow:深度学习模型(视课程章节需要);
- AutoDock Vina:分子对接程序;
- Open Babel:分子文件格式转换。
创建环境的命令如下:
conda create -n vscreen python=3.10 -y conda activate vscreen conda install -c conda-forge rdkit openbabel -y pip install numpy pandas matplotlib seaborn scikit-learn2.2 分子对接工具准备
课程中分子对接部分以 AutoDock Vina 为主要工具,兼容性好、开源免费、计算速度快,适合新手学习。Vina 的安装方式取决于操作系统。
Linux 下可以直接下载预编译二进制文件,放进系统 PATH。Windows 下建议使用 WSL 或从官方渠道获取可执行文件。安装完成后,建议验证一下版本:
vina --version如果终端能正常输出版本号,说明对接工具已经就绪。课程中还有部分章节演示了商业软件 Discovery Studio 和 Schr\u00f6dinger Glide 的操作,如果你手头没有商业软件许可证,用 Vina 跟着思路走也一样能掌握虚拟筛选的核心逻辑。
2.3 数据集准备
虚拟筛选需要用到靶点蛋白结构和小分子数据库。常用的公开数据源包括:
- RCSB PDB:蛋白晶体结构数据库,通过 PDB ID 获取结构;
- ZINC 数据库:大规模可购买化合物库,支持按物化性质筛选下载;
- ChEMBL:生物活性数据数据库,适合训练 AI 活性预测模型;
- PubChem:化合物结构、生物活性、文献数据综合平台。
课程附带的资料中已经准备好了几个常用数据集,包括用于演示对接流程的小分子库、用于模型训练的活性数据文件。自己练习时可以直接使用这些公开数据源,避免版权和合规风险。
3. 分子数据处理核心技能
3.1 分子表示与 SMILES 入门
分子结构在计算机里有多种表示方式,最常见的是 SMILES 字符串,例如苯丙氨酸的 SMILES 为N[C@@H](Cc1ccccc1)C(=O)O。SMILES 是线性表示,便于存储和检索,但丢失了三维坐标信息。进行分子对接之前,需要将 SMILES 转换为带 3D 坐标的构象。
RDKit 是最常用的分子处理工具。下面看一个用 RDKit 将 SMILES 转为 3D 结构的示例:
from rdkit import Chem from rdkit.Chem import AllChem from rdkit.Chem import Descriptors # 输入 SMILES smiles = "N[C@@H](Cc1ccccc1)C(=O)O" # 从 SMILES 构建分子对象 mol = Chem.MolFromSmiles(smiles) if mol is None: print("SMILES 解析失败,请检查字符串格式") exit(1) # 添加氢原子 mol = Chem.AddHs(mol) # 生成 3D 构象 result = AllChem.EmbedMolecule(mol, randomSeed=42) if result != 0: print("3D 构象生成失败,尝试使用 ETKDG 方法") AllChem.EmbedMolecule(mol, AllChem.ETKDGv3(), randomSeed=42) # 对构象做力学优化 AllChem.MMFFOptimizeMolecule(mol) # 输出分子量(验证分子是否正常) print("分子量:", Descriptors.MolWt(mol)) print("SMILES:", Chem.MolToSmiles(mol))关键点说明:
Chem.AddHs步骤不能省略,尤其是后续做对接或力场计算时,氢原子会影响电荷和相互作用;EmbedMolecule负责生成初始 3D 坐标,randomSeed固定后结果可复现;MMFFOptimizeMolecule对构象做局部优化,让分子几何更合理。
3.2 分子文件格式与转换
虚拟筛选流程中经常遇到格式转换需求,例如把 Mol2 转 PDBQT、把 SDF 转 SMILES、把 SMILES 批量转 3D SDF。PDBQT 格式是 AutoDock 系列工具的标准输入格式,在原子坐标基础上增加了原子类型和电荷信息。
课程中常用 Open Babel 做格式转换,命令行方式如下:
obabel input.sdf -O output.pdbqt -p 7.4-p 7.4表示在 pH 7.4 条件下质子化,模拟生理环境下的分子状态。如果是批量转换多个分子,可以直接指定 SDF 文件作为输入。
RDKit 也能完成类似工作,而且与 Python 生态集成的更好。将批量 SMILES 转为 SDF 文件的示例:
import pandas as pd from rdkit import Chem from rdkit.Chem import AllChem # 示例数据 data = { "name": ["mol1", "mol2"], "smiles": ["CC(=O)Oc1ccccc1C(=O)O", "CCO"] } df = pd.DataFrame(data) w = Chem.SDWriter("output.sdf") for _, row in df.iterrows(): mol = Chem.MolFromSmiles(row["smiles"]) if mol is None: continue mol = Chem.AddHs(mol) AllChem.EmbedMolecule(mol, randomSeed=42) AllChem.MMFFOptimizeMolecule(mol) mol.SetProp("_Name", row["name"]) w.write(mol) w.close() print("转换完成,共写入 {} 个分子".format(len(df)))这里需要注意 SDF 文件中的_Name属性,对接结束后要根据名称把打分结果对应回原化合物,名称是唯一的关联字段。
3.3 分子指纹与相似性搜索
在做基于配体的虚拟筛选时,分子指纹是核心工具。分子指纹将分子结构编码成固定长度的二进制向量,通过比较向量之间的相似度(如 Tanimoto 系数)来寻找与已知活性分子结构相似的候选化合物。
RDKit 中计算 Morgan 指纹的示例:
from rdkit import Chem from rdkit.Chem import AllChem from rdkit.DataStructs import TanimotoSimilarity # 查询分子和候选分子 query = Chem.MolFromSmiles("CC(=O)Oc1ccccc1C(=O)O") candidate = Chem.MolFromSmiles("CC(=O)Oc1ccc(Cl)cc1C(=O)O") # 生成 Morgan 指纹(半径 2,1024 位) fp_query = AllChem.GetMorganFingerprintAsBitVect(query, 2, nBits=1024) fp_candidate = AllChem.GetMorganFingerprintAsBitVect(candidate, 2, nBits=1024) # 计算 Tanimoto 相似度 similarity = TanimotoSimilarity(fp_query, fp_candidate) print("Tanimoto 相似度:", round(similarity, 4))Tanimoto 相似度取值 0 到 1,数值越大表示两个分子越相似。实际虚拟筛选中,通常会设定一个阈值(例如 0.7),筛选出与已知活性分子相似度超过阈值的化合物,再做分子对接验证。这种方式计算速度快,适合处理百万级化合物库。
4. 分子对接完整实战
4.1 对接前准备:蛋白结构处理
分子对接的第一步是准备受体蛋白结构。课程中强调,从 PDB 下载的晶体结构通常带有水分子、配体、金属离子等,直接拿去对接会影响结果,必须先做清理。
以典型的激酶靶点为例,处理流程如下:
- 下载 PDB 结构文件,例如
1A4G.pdb; - 去除水分子和无关配体;
- 添加氢原子;
- 转化为 PDBQT 格式。
使用 Open Babel 快速清理蛋白并转换格式:
obabel 1A4G.pdb -O receptor.pdbqt -xr-xr表示去除配体。如果还想去除水分子,可以先用文本工具过滤掉包含HOH的行,再进行转换。
更推荐的做法是使用 ADFRsuite 或 MGLTools 中的 prepare_receptor4.py 脚本,它专门用于 AutoDock 系列工具的受体准备,能正确处理原子类型和电荷。
4.2 定义结合口袋
结合口袋是配体分子可能结合的蛋白区域。口袋定义是否准确,直接影响对接结果。常见做法有两种:
一是根据已知共晶配体的坐标定义口袋,即将配体周围一定范围内的残基视为结合位点;二是用预测工具(如 FPocket)预测可能的结合腔。
在 Vina 中,结合口袋通过中心坐标和盒子尺寸定义。假设已知共晶配体中心坐标为x=10, y=20, z=30,盒子尺寸为20 x 20 x 20埃,配置如下:
receptor = receptor.pdbqt ligand = ligand.pdbqt center_x = 10 center_y = 20 center_z = 30 size_x = 20 size_y = 20 size_z = 20 exhaustiveness = 16 num_modes = 9exhaustiveness控制搜索深度,值越大结果越可靠但耗时越长。课程中的建议是,先用 8 快速试跑,确认流程无误后再增加到 32 做正式计算。
4.3 运行 AutoDock Vina 对接
将上述参数保存为conf.txt,然后命令行运行:
vina --config conf.txt --out result.pdbqt --log log.txt如果一切正常,result.pdbqt中会包含多个对接构象,log.txt中会记录每个构象的 Vina 打分(单位 kcal/mol)。打分越负,表示预测结合亲和力越强。通常打分低于 -7.0 kcal/mol 的配体值得重点关注。
4.4 对接结果批量处理与排序
虚拟筛选面对的是成百上千个小分子,不可能一个个手动运行 Vina。课程中是先准备多个配体文件,再用脚本批量对接。下面给出一个批量对接脚本的示例:
import subprocess import os import glob # 配体目录 ligand_dir = "./ligands_pdbqt" output_dir = "./results" os.makedirs(output_dir, exist_ok=True) # Vina 配置模板,中心和盒子大小固定 conf_template = """ receptor = receptor.pdbqt ligand = {ligand} center_x = 10 center_y = 20 center_z = 30 size_x = 20 size_y = 20 size_z = 20 exhaustiveness = 16 num_modes = 9 """ for ligand_file in glob.glob(os.path.join(ligand_dir, "*.pdbqt")): name = os.path.basename(ligand_file).replace(".pdbqt", "") print("正在对接:", name) conf_file = f"/tmp/conf_{name}.txt" with open(conf_file, "w") as f: f.write(conf_template.format(ligand=ligand_file)) out_file = os.path.join(output_dir, f"{name}_out.pdbqt") log_file = os.path.join(output_dir, f"{name}_log.txt") cmd = ["vina", "--config", conf_file, "--out", out_file, "--log", log_file] subprocess.run(cmd, capture_output=True, text=True) print("批量对接完成")运行完成后,写一个解析脚本读取 log 文件,汇总打分结果:
import glob import re import pandas as pd rows = [] for log_file in glob.glob("results/*_log.txt"): name = log_file.split("/")[-1].replace("_log.txt", "") with open(log_file, "r") as f: lines = f.readlines() best_score = None for line in lines: # Vina 日志中打分行形如: 1 -7.2 0.000 0.000 parts = line.strip().split() if len(parts) >= 2 and parts[0].isdigit(): try: score = float(parts[1]) if best_score is None or score < best_score: best_score = score except ValueError: continue rows.append({"name": name, "vina_score": best_score}) # 排序输出 Top 10 result_df = pd.DataFrame(rows).dropna() result_df = result_df.sort_values("vina_score") print("打分最低(结合最强)的前 10 个分子:") print(result_df.head(10))课程中强调一个观点:对接打分只是一个粗筛工具。打分靠前的分子不一定真有活性,因为打分函数存在局限,而且诱导契合效应无法完全模拟。因此,虚拟筛选结果一定要结合后续的分子动力学模拟和湿实验验证。
4.5 对接结果可视化
选出候选分子后,需要用 PyMOL 等工具查看结合模式,确认分子是否与关键残基形成氢键、疏水相互作用等。PyMOL 打开对接结果的步骤比较简单:
load receptor.pdbqt load result.pdbqt hide everything show cartoon, receptor show sticks, result人工目视检查时重点观察:
- 配体是否完全落在结合口袋内部;
- 是否与已知的关键残基形成相互作用;
- 是否有明显的空间位阻冲突。
如果一组分子与靶点的结合模式高度一致,说明它们的结合模式有共性,这类结果更可信。
5. AI 模型在虚拟筛选中怎么用
5.1 从对接打分到 AI 打分
传统对接打分依赖物理势能函数,AI 打分模型则从数据中学习。课程中演示了一种常见做法:用已知活性数据训练一个分类模型,输入分子指纹或分子图,输出分子是否具有活性的概率。模型训练完成后,可以对新化合物库做快速预测,实现百万级化合物的快速筛选。
这里的核心区别在于:
- 对接打分不需要标签数据,但有明显近似误差;
- AI 模型依赖高质量标注数据,但预测速度极快;
- 实际项目倾向于两种方法结合,先用 AI 模型粗筛,再用分子对接精筛。
5.2 构建分子活性预测模型
下面是一个用 RDKit 计算分子描述符,再用随机森林构建活性分类模型的完整示例。假设训练数据是 CSV 文件,包含smiles和active两列,active取值为 0 或 1。
import pandas as pd import numpy as np from rdkit import Chem from rdkit.Chem import Descriptors from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import roc_auc_score, accuracy_score # 读取数据 df = pd.read_csv("bioactivity_data.csv") print("数据总量:", len(df)) # 用 RDKit 计算分子描述符 descriptor_names = [d[0] for d in Descriptors.descList] def compute_descriptors(smiles): mol = Chem.MolFromSmiles(smiles) if mol is None: return [np.nan] * len(descriptor_names) desc_values = [] for name, func in Descriptors.descList: try: desc_values.append(func(mol)) except Exception: desc_values.append(np.nan) return desc_values # 注意:实际数据量大时不要用循环逐条计算,建议向量化或分批处理 descriptors = df["smiles"].apply(compute_descriptors) X = pd.DataFrame(descriptors.tolist(), columns=descriptor_names) y = df["active"].values # 删除包含 NaN 的列 X = X.dropna(axis=1) print("描述符特征维度:", X.shape[1]) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y ) # 训练随机森林 model = RandomForestClassifier(n_estimators=300, random_state=42) model.fit(X_train, y_train) # 评估 y_pred_proba = model.predict_proba(X_test)[:, 1] y_pred = model.predict(X_test) print("准确率:", round(accuracy_score(y_test, y_pred), 4)) print("AUC:", round(roc_auc_score(y_test, y_pred_proba), 4)) # 输出特征重要性 Top20 feature_importance = pd.Series(model.feature_importances_, index=X.columns) top_features = feature_importance.sort_values(ascending=False).head(20) print("Top20 重要描述符:") print(top_features)这段代码有几个地方需要注意:
Descriptors.descList包含 200 多个分子描述符,计算量较大,数据量大时建议用并行优化;- 描述符计算失败时用
np.nan占位,后续通过dropna处理; stratify=y保证训练集和测试集中活性分子的比例一致,避免类别不均衡带来的偏差;- 随机森林的特征重要性可以帮你理解哪些分子性质对活性影响最大。
5.3 深度学习模型的简单入门
课程后半部分进入了深度学习方法,以图神经网络为主。对于完全没有深度学习基础的读者,这里建议先掌握以下几个概念:
- 分子图:把原子看作节点、化学键看作边,用图结构表示分子;
- 图神经网络:通过消息传递机制学习节点和边的特征表示;
- 消息传递:每个节点聚合邻居节点的信息,更新自身特征,经过多层迭代后得到整个图的表示。
下面是用 PyTorch Geometric 实现一个简单 GNN 分类模型的骨架代码,作为入门示例:
import torch import torch.nn.functional as F from torch_geometric.nn import GCNConv from torch_geometric.nn import global_mean_pool class MolGCN(torch.nn.Module): def __init__(self, num_node_features, hidden_dim=64, num_classes=2): super().__init__() self.conv1 = GCNConv(num_node_features, hidden_dim) self.conv2 = GCNConv(hidden_dim, hidden_dim) self.fc = torch.nn.Linear(hidden_dim, num_classes) def forward(self, x, edge_index, batch): x = self.conv1(x, edge_index) x = F.relu(x) x = F.dropout(x, p=0.2, training=self.training) x = self.conv2(x, edge_index) x = global_mean_pool(x, batch) x = self.fc(x) return x课程中建议,入门深度学习时先不要在模型结构上花太多时间,重点是把数据准备逻辑搞清楚,包括:
- 如何将 SMILES 转化为图数据;
- 如何划分训练集、验证集、测试集;
- 如何处理类别不均衡;
- 如何评估模型并防止过拟合。
把这些问题想清楚后,再更换更复杂的模型结构就会顺利很多。
5.4 分子生成与反向设计
除了预测打分,AI 在虚拟筛选中的另一个重要方向是分子生成。课程中提到一种常见的生成策略:训练一个变分自编码器或生成对抗网络,将分子结构编码到潜在空间,然后在潜在空间中进行插值或优化,生成具有理想性质的新分子结构。
生成式分子设计目前仍存在可合成性差、活性难以准确预测等问题,更适合作为灵感来源,而不是直接替代药物化学家的设计思路。实际项目中,生成的分子通常还需要经过合成可行性评估和实验验证。
6. 实战案例:从零筛选一个靶点的候选化合物
6.1 案例背景
下面将课程中的一个实战案例整理出来,完成一个完整的虚拟筛选小项目。目标靶点选择比较简单的丝氨酸蛋白酶,任务是从一个包含 1000 个小分子的库中筛选出潜在抑制剂。
整体流程为:
- 获取靶点蛋白结构;
- 准备小分子库并转换为 3D 结构;
- 批量分子对接;
- 汇总打分并挑选候选分子;
- 用 PyMOL 目视检查关键结合模式。
6.2 准备小分子库
课程附带的案例数据中,小分子库以一个 CSV 文件给出,包含化合物名称和 SMILES。我们先用 RDKit 将其转换为对接需要的 3D SDF。
import pandas as pd from rdkit import Chem from rdkit.Chem import AllChem df = pd.read_csv("compound_library.csv") print("化合物数量:", len(df)) w = Chem.SDWriter("library_3d.sdf") success_count = 0 for _, row in df.iterrows(): mol = Chem.MolFromSmiles(row["smiles"]) if mol is None: print("解析失败:", row["name"]) continue mol = Chem.AddHs(mol) ok = AllChem.EmbedMolecule(mol, AllChem.ETKDGv3(), randomSeed=42) if ok == 0: AllChem.MMFFOptimizeMolecule(mol) mol.SetProp("_Name", str(row["name"])) w.write(mol) success_count += 1 else: print("3D 构象生成失败:", row["name"]) w.close() print("成功写入分子数:", success_count)这一步需要注意:如果EmbedMolecule返回非 0 值,说明构象生成失败,可能是分子过于柔性或含有特殊元素。课程中的建议是可以尝试增加构象生成次数,例如AllChem.EmbedMolecule(mol, AllChem.ETKDGv3(), randomSeed=42, numThreads=0, maxIterations=500)。
6.3 将 SDF 转换为 PDBQT
对接前需要将 SDF 转换为 PDBQT,这里用 Open Babel 批量处理:
obabel library_3d.sdf -O library_3d.pdbqt -p 7.4 --multi--multi参数表示保留多个分子输出到一个文件。如果后续要并行对接,也可以拆分成多个单分子文件。
6.4 进行对接并获取打分
根据前面 4.4 节的批量对接脚本,将受体和配体文件路径替换为实际路径,运行即可。跑完后汇总打分表现,例如:
import pandas as pd result_df = pd.read_csv("docking_results.csv") top_candidates = result_df.sort_values("vina_score").head(20) print("Top20 候选分子:") print(top_candidates[["name", "vina_score"]])6.5 候选分子人工审查
最终的人工审查非常关键。课程中建议从以下三个维度判断候选分子:
- 结合模式是否合理:关键极性残基是否形成氢键;
- 分子是否容易合成:是否存在复杂的立体中心、稀有结构片段;
- 类药性质是否合格:分子量、LogP、可旋转键数、氢键供体/受体数量是否符合类药规则。
如果有药物化学背景,这一步可以发挥很大作用;即使没有背景,至少也应该把打分靠前的分子文件整理好,交给合作方或实验团队做后续判断。
7. 常见问题与排查思路
虚拟筛选流程长、涉及工具多,新手很容易在不同环节踩坑。下表总结了课程中反复出现的高频问题。
| 问题现象 | 可能原因 | 解决思路 |
|---|---|---|
| RDKit 无法解析 SMILES | SMILES 格式错误、元素类型不支持 | 用Chem.MolFromSmiles返回 None 时,检查 SMILES 是否规范;不支持的原子类型需要检查来源数据 |
| 3D 构象生成失败 | 分子过大、柔性过强、初始坐标问题 | 增加maxIterations,固定随机种子,尝试不同版本 ETKDG;仍然失败则剔除该分子 |
| Open Babel 转换 PDBQT 报错 | 原子类型映射失败、电荷缺失 | 检查分子是否含有特殊元素;使用-p 7.4参数指定质子化状态;确认 PDBQT 文件输出目录可写 |
| Vina 运行找不到受体 | PDBQT 格式不规范 | 重新用prepare_receptor4.py或 Open Babel 转换;确认受体结构中不包含异常残基 |
| 对接结果全为高打分 | 结合口袋定义有误、受体处理不当 | 核对口袋中心坐标和盒子尺寸;用已知活性配体验证对接流程 |
| 批量对接脚本崩溃 | 配体文件命名冲突、日志文件路径不合法 | 给每个任务加唯一标识;捕获子进程返回值;输出错误日志 |
| AI 模型过拟合 | 训练数据量不足、模型太复杂 | 增加数据量、使用交叉验证、降低模型复杂度、增加正则化 |
| 描述符计算全为 NaN | SMILES 解析失败或特殊结构 | 首先检查 SMILES 解析率;利用 try-except 捕获单条失败数据 |
排查问题时,建议按照数据 → 格式 → 工具 → 参数的顺序来检查。大多数问题其实不是算法问题,而是数据格式或路径问题。
8. 虚拟筛选工程化最佳实践
8.1 数据管理规范
虚拟筛选项目涉及的数据文件非常多,蛋白结构、配体文件、对接结果、日志、模型权重,如果没有统一命名和目录规范,很容易混乱。推荐的目录结构如下:
project/ ├── data/ │ ├── raw/ # 原始数据,如 PDB、SMILES │ ├── processed/ # 预处理后的分子文件 │ └── external/ # 公开数据库下载的数据 ├── scripts/ # 所有处理脚本 ├── results/ │ ├── docking/ # 对接输出 │ ├── models/ # 训练好的模型 │ └── analysis/ # 分析图表 ├── conf/ # 配置文件 └── logs/ # 运行日志课程中还强调,所有原始文件不要手动修改,处理脚本应该重复可运行,处理结果随时可以重新生成。原始数据本身是只读的,这样可以避免无意破坏原始数据后无法追溯。
8.2 可复现性控制
虚拟筛选和 AI 训练都涉及随机过程,可复现性直接影响结果可信度和实验可重复性。建议在每个脚本开头固定随机种子:
import random import numpy as np import torch random.seed(42) np.random.seed(42) torch.manual_seed(42)涉及到 RDKit 构象生成的随机种子也建议固定。对接工具 Vina 虽然有确定性,但不同版本之间的打分可能有细微差异,日志文件中应该记录工具版本号。
8.3 推荐结果验证策略
虚拟筛选结果的可靠性需要验证,课程中给出了几个可行的策略:
- 已知活性分子验证:把已知的活性分子放进化合物库作为阳性对照,看它们是否排在前列;
- 诱饵分子验证:加入一批与活性分子性质相似但不具有活性的诱饵分子(decoy),观察富集率;
- 结合模式一致性:查看多个打分较高的候选分子是否与受体形成一致的相互作用模式,如果结合模式混乱,结果可信度较低;
- 动力学验证候选分子:对筛选出的 Top 分子做分子动力学模拟,验证结合稳定性。
对于刚入门的读者,至少应该先做阳性对照实验,这一步能快速判断整个虚拟筛选流程是否可靠。
8.4 高性能计算的注意事项
当化合物库规模达到几十万甚至百万级时,本地单机跑对接会非常耗时。课程中提到几个工程优化方向:
- 对接任务并行化:不同化合物之间的对接相互独立,天然适合并行调度;
- GPU 加速:AI 模型推理可以迁移到 GPU,对接环节部分工具也支持 GPU 加速;
- 数据库缓存:已经计算过的化合物保存结果,避免重复计算;
- 分层筛选:先用 AI 模型或2D 相似性做快速粗筛,大幅缩小候选集后再做对接精筛。
在正式生产环境或高算力集群上运行前,建议先在小规模数据上完整跑通流程,再提交大规模任务。
9. 学习路线与后续方向
9.1 零基础入门阶段
如果是零基础,建议按照课程顺序先把环境搭建、Python 基础、RDKit 分子处理、AutoDock Vina 对接这四个模块掌握。这个阶段的目标是跑通一个最小流程:选择一个靶点,准备 10 个小分子,完成对接并获得打分结果。不要急着学习深度学习和分子生成。
9.2 进阶提升阶段
跑通最小流程后,可以从以下方向逐步深入:
- 分子描述符与机器学习:熟练使用 RDKit、scikit-learn,构建自己的活性预测模型;
- 深度学习基础:掌握 PyTorch 基础和张量操作,理解图神经网络原理;
- 自动化脚本开发:把数据处理、对接、结果解析串成一个完整的自动化 pipeline;
- 项目实战:从公开数据库中构建一个完整的虚拟筛选项目,完成从靶点到候选分子的闭环。
9.3 拓展方向
虚拟筛选只是计算辅助药物设计的一部分,相关方向还包括:
- 分子动力学模拟:评估蛋白-配体复合物的动态稳定性;
- 自由能微扰 FEP:更精确地预测相对结合自由能;
- 药效团建模:基于已知活性分子提取共同药效特征;
- ADMET 预测:评估候选分子的吸收、分布、代谢、排泄和毒性性质。
AI 虚拟筛选是一个交叉领域,需要不断积累化学、生物学和计算机科学三方面的知识。课程能帮你快速搭建体系框架,但真正的提升还是来自持续的项目实践,尤其是遇到问题、排查问题的过程。
这套课程中值得反复学习的内容集中在分子对接实操、RDKit 数据处理和 AI 模型构建这几块。如果只是看视频不敲代码,效果会大打折扣。建议每看完一个章节,就动手把配套代码运行一遍,再尝试修改参数或换一个数据集,这样才能真正把知识变成自己的技能。