数据收集与格式: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 时,按这个流程走一遍:

  1. 去重:基于 InChI Key 或 Canonical SMILES 去重
  2. 标准化:统一 SMILES 为 RDKit 能识别的标准写法
  3. 类型检查:确认数值字段都是数字,文本字段不乱码
  4. 异常值过滤:活性值超出 3 个标准差的,单独检查
  5. 缺失值处理:能补就补,不能补的就删行

实操提示: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 打开实验数据文件。接收后第一件事就是转成纯文本格式。

好了,这一章的内容基本就这些。数据收集和格式虽然基础,但地基不打牢,后面建多高的楼都立不住。