数据收集与格式:QSAR 的第一道门槛
做 QSAR 呢,说白了就是跟数据打交道。模型做得再花哨,数据底子不行,结果就是废纸一堆。今天咱们就把数据收集与格式这块聊透。
我在项目里栽过跟头。有一回批处理怎么也跑不通,模型 R² 看着挺高,但一交叉验证就崩。查了一整天,最后发现是 SDF 文件里有几个分子的原子数格式不统一。你说冤不冤?
原始数据来源
QSAR 数据主要有三个源头。每个我都有点血泪史。
文献数据
这是最常见的方法。你去翻论文,把作者验证过的分子活性和结构抄下来。我个人习惯是先看 Supporting Information,很多论文会把 SDF 或 SMILES 贴在补充材料里。
- 优点:数据已经被同行评审过,可信度相对高
- 缺点:很多论文只给了少数代表性分子,样本量不够
- 坑:不同论文用的实验条件不一样,IC₅₀ 值不能直接怼到一起
一条经验:我通常只看近十年的文献,太老的数据实验标准差异太大,对模型反而是噪声。
公共数据库
这是主力来源。做 QSAR 绕不开这几个库:
| 数据库名称 | 特点 | 我常用的场景 |
|---|---|---|
| PubChem | 量大,免费,支持批量下载 | 做大规模虚拟筛选前,先捞一波数据 |
| ChEMBL | 数据经过人工校验,质量好 | 做活性回归模型时的首选 |
| DrugBank | 已上市药物信息齐全 | 做 ADMET 预测时参考 |
| BindingDB | 靶点亲和力数据很全 | 靶向药物设计的场景 |
注意:公共数据库里的数据不是直接能用的。我曾从 PubChem 直接拉了一批数据,结果发现里面有 30% 的分子 SMILES 编码标准不统一。你说这模型能做好才怪。
自测数据
这是最靠谱但最贵的路子。你实验室自己测出来的数据,实验条件一致,误差可追溯。不过量通常不大,几十到几百个分子是常态。
- 主动设计实验矩阵,保证结构多样性
- 每个分子最好有 3 次以上重复测量
- 记录实验细节:温度、pH、时间、批次
常见文件格式
QSAR 这块的文件格式,说多不多,说少不少。我建议你把三个核心格式吃透就够了。
SDF 格式
SDF(Structure Data File)是 QSAR 的元老级格式。它不光存分子结构,还能挂各种各样的属性字段。嗯,这个格式我建议必须要会。
# 一个标准的 SDF 条目结构
# 数据头
mol-12345
ChemOffice 1234567890D 3D
# 原子坐标
9 9 0 0 0 0 0 0 0 0999 V2000
1.2345 2.3456 3.4567 C 0 0 0 0 0 0 0 0 0 0 0 0
2.3456 3.4567 4.5678 N 0 0 0 0 0 0 0 0 0 0 0 0
# 属性字段
> <IC50>
12.5
> <LogP>
2.34
$$$$
读取 SDF 时,记得检查一下原子坐标列格式。我遇到过有些软件导出的 SDF 里,坐标列数对不上,直接导致后续计算全崩。
CSV 格式
CSV 是最简单的表格格式,但也是最容易出问题的。说白了,它的规则就是:逗号分隔,换行一条记录。
SMILES,IC50_uM,LogP,MW
CC(C)Cc1ccc(cc1)C(C)C(=O)O,8.5,2.45,206.28
c1ccccc1C(=O)O,15.2,1.42,122.12
CN(C)c1ccc(cc1)C=CC(=O)O,3.8,1.89,205.25
常见问题——我列一下:
- SMILES 里如果有逗号,必须用引号括起来
- 数值字段里不能有空值,要填 NA 或者直接删掉
- 表头名称不能有空格,用下划线代替
CSV 编码是个大坑。Excel 默认存的是 ANSI 或 GBK,但 Python 读的时候可能默认是 UTF-8,乱码就来了。我现在的习惯是:收到 CSV 第一件事,用记事本另存为 UTF-8 with BOM。
Excel 格式
Excel 在合作时常用,但它不是标准的数据交换格式。为什么我会这么说?
- 单元格格式可能被 Excel 自动修改,比如你输的 CAS 号,可能变成科学计数法
- 合并单元格、条件格式这些,读数据时很难处理
- 多个工作表靠你肉眼去对,很容易漏
我的建议:用 Excel 做展示可以,但做数据处理时,优先转成 CSV 或 SDF。
数据清洗基础
数据清洗这事,枯燥但绕不过。你想想看,如果一个数据集里混着几套命名体系,模型能学出什么来?
为什么要做数据清洗?
说白了,原始数据就像刚挖出来的矿石,杂质多得很。常见的脏数据包括:
- 重复分子:同一个结构用了不同的名字
- 结构歧义:SMILES 写法不统一
- 数值错误:活性值标反了逻辑单位
- 缺失值:关键字段空了
清洗的基本步骤
我一般在做 QSAR 时,按这个流程走一遍:
- 去重:基于 InChI Key 或 Canonical SMILES 去重
- 标准化:统一 SMILES 为 RDKit 能识别的标准写法
- 类型检查:确认数值字段都是数字,文本字段不乱码
- 异常值过滤:活性值超出 3 个标准差的,单独检查
- 缺失值处理:能补就补,不能补的就删行
实操提示:RDKit 的 SanitizeMol 函数能帮你做大部分的标准化工作。我建议你把这个函数加到你的清洗流程里,能省不少事。
一个清洗范例
假设你有一个 CSV 文件,里面存着分子 SMILES 和活性值。我们来写个简单的清洗流程:
import pandas as pd
from rdkit import Chem
df = pd.read_csv("raw_data.csv")
# 去重:基于标准 SMILES
df['mol_obj'] = df['SMILES'].apply(Chem.MolFromSmiles)
df['canonical'] = df['mol_obj'].apply(
lambda x: Chem.MolToSmiles(x) if x else None
)
df = df.drop_duplicates(subset='canonical')
# 检查数值列
df = df[pd.to_numeric(df['IC50'], errors='coerce').notna()]
# 输出清洗后的数据
df.to_csv("cleaned_data.csv", index=False)
你看,代码不过几行,但能过滤掉不少问题。我用这个脚本处理过几百个数据集,基本能解决 80% 的常见问题。
常见问题域总结
| 问题类型 | 表现 | 我的处理方式 |
|---|---|---|
| SMILES 歧义 | 同一分子的 SMILES 写法不同 | 统一用 RDKit 标准 SMILES |
| 活性值单位不统一 | 部分 uM 部分 nM | 全部转成同一单位,记录转换日志 |
| 重复记录 | 同一分子出现多次 | 基于 InChI Key 去重,取活性均值 |
| 结构错误 | 分子无法被 RDKit 解析 | 记录失败列表,人工核查 |
| 缺失关键字段 | SMILES 或活性值为空 | 直接删除该条记录 |
我曾经为了一个清洗问题熬了大半夜。后来发现是 Excel 把 IC₅₀ 的 "µM" 符号给自动替换了。从那以后,我再也不直接用 Excel 打开实验数据文件。接收后第一件事就是转成纯文本格式。
好了,这一章的内容基本就这些。数据收集和格式虽然基础,但地基不打牢,后面建多高的楼都立不住。