质控流程总览:从数据采集到报告输出的全链路设计
说实话,我刚接触ADMET质控的时候,也以为就是跑个预测、打个标签就完事了。结果第一次做全流程整合,数据源乱七八糟,格式不统一,阈值设得太松,报告没人看得懂……
后来我花了两周重新梳理链路,才把整个质控流程捋顺。你想想看,从原始数据进来,到最后一份报告出去,中间每一步都可能出幺蛾子。今天我就把这条全链路拆开来讲,每个环节我会提一嘴我踩过的坑。
3.1 全链路概览:从分子到决策
整个ADMET质控流程,我习惯分成五个阶段——数据采集、清洗标准化、计算预测、质控检查、报告输出。每个阶段都有明确的输入、操作和输出。下面这个图可以帮你快速建立整体认知。
3.2 数据采集:源头决定质量
数据采集是第一关,也是最容易出鬼的地方。我的习惯是先列一张清单,把每类数据的来源、文件格式、更新频率搞清楚。
| 数据来源 | 常见格式 | 关键字段 | 典型问题 |
|---|---|---|---|
| PubChem / ChEMBL | CSV, SDF | SMILES, IC50, MW | SMILES不规范、单位缺失 |
| 内部实验数据 | Excel, LIMS导出txt | CpdID, LogD, Solubility | Excel日期格式篡改、空格混用 |
| 文献手动录入 | CSV, JSON | DOI, pKa, Permeability | 人工拼写错误、数值范围不一 |
举个例子,有一次我拿到一批从某平台下载的LogD数据,SMILES里面有“Br”和“Cl”字符串结尾带换行符,导致后续标准化直接崩溃。后来我加了一道“前置检查”脚本,专门处理这类问题。
# 前置检查:SMILES清洗
import re
def clean_smiles(smi):
if not smi:
return None
smi = smi.strip()
# 去除多余空格和换行
smi = re.sub(r'\s+', '', smi)
# 统一大写原子符号
return smi.upper()
3.3 数据清洗与标准化
数据清洗说白了就是把脏数据弄干净。我一般做三件事:格式统一、缺失值处理、值域标准化。
- 格式统一:所有SMILES转为标准格式(Canonical SMILES),所有浓度统一为μM单位。
- 缺失值处理:非关键字段的缺失值用“-”标记,关键字段缺失直接剔除该条记录。
- 值域标准化:比如LogD通常与pH绑定,需要在字段中注明pH条件。
标准化脚本我通常会写一个YAML配置文件,方便不同项目复用。
# standardize_config.yaml
columns:
- name: smiles
type: canonical
- name: logd
unit: log
ph: 7.4
- name: solubility
unit: ug/mL
missing_handling:
- col: logd
action: drop
- col: solubility
action: fill -
3.4 计算与预测
到了计算阶段,工具选型就很关键了。常用的有内部QSAR模型、商业软件(如Schrödinger的QikProp)或开源框架(如RDKit + scikit-learn)。我个人偏爱用Python搭一套管线,这样好调试。
# 预测管线示例(简化)
from rdkit import Chem
from my_model import predict_logd
def predict_pipeline(smiles_list):
results = []
for smi in smiles_list:
mol = Chem.MolFromSmiles(smi)
if not mol:
results.append({'smiles': smi, 'error': 'invalid_smiles'})
continue
logd = predict_logd(mol)
results.append({'smiles': smi, 'logd': logd})
return results
这里要注意的是,每个预测模型都有自己的“适用域”。比如某个LogD模型是在pH 7.4下训练的,你拿来预测pH 2.0的数据,那结果基本就是废的。我在项目中遇到过这样的乌龙,当时模型还给出了很高的置信度,一检查才发现训练集和预测集pH根本对不上。
3.5 质控检查与阈值判定
这是全链路的核心把关环节。我一般设置三层检查:
- 完整性检查:所有必须字段是否非空,SMILES是否能被RDKit解析。
- 合理性检查:数值是否在合理区间(比如LogD不可能小于-5或大于10)。
- 一致性检查:同个化合物的重复实验值是否在±0.5 log单位内。
阈值定义我通常会放在单独的文件里,方便维护。
# thresholds.json
{
"logd": {"min": -2.0, "max": 6.0, "repeat_tolerance": 0.5},
"solubility": {"min": 0.1, "max": 1000.0, "unit": "ug/mL"},
"permeability": {"min": -8.0, "max": -3.0, "unit": "cm/s"}
}
3.6 报告输出与归档
报告输出的目标就一个:让下游同事一眼看懂。
我常用两种输出格式:一份详尽的Excel(带批注、带预测值和阈值对比、带质控flag),一份PDF摘要(只放通过率、异常分布、TOP5问题列表)。
| 输出类型 | 内容 | 接收方 |
|---|---|---|
| Excel(原始+质控标记) | 所有字段、预测值、通过/失败、异常备注 | 计算化学家、数据管理员 |
| PDF摘要报告 | 整体通过率、按类别统计、关键图表 | 项目经理、决策层 |
| 数据库归档 | 清洗后的标准化数据、质控结果、时间戳 | 长期存储、审计追溯 |
归档这一步很多人会忽略,但审计的时候你就知道它有多重要了。我每次跑完一个批次,都会把原始数据、清洗脚本、阈值配置、预测结果、质控日志一起打包成一个带时间戳的文件夹,存档到NAS上。