第2章 基础知识:生物医学文献结构与PubMed检索

在做药物靶点自动抽取之前,你得先了解战场是什么样的。说白了,PubMed就是咱们的数据库,而文献结构是咱们要解构的对象。我个人习惯把这一章当成整个课程的基石——如果连文献长什么样、怎么拿数据都搞不清楚,后面的代码写得再漂亮也没用。

2.1 生物医学文献的结构特征

一篇PubMed上的文献,虽然排版五花八门,但核心结构其实非常固定。我刚开始做文本挖掘时,以为每篇文献格式都不一样,后来发现这只是表面现象。真正的大结构,无非是以下几种:

  • 标题(Title):短小精悍,核心信息压缩在里面
  • 摘要(Abstract):分为目的、方法、结果、结论四个隐式段落
  • 关键词(MeSH Terms / Keywords):人工标引的主题词,是靶点抽取的黄金线索
  • 全文(Full Text):包含材料与方法、结果、讨论、参考文献等
  • 元数据(Metadata):作者、期刊、发表日期、PMID、PMCID等

核心思路:药物靶点提取主要依赖标题+摘要+MeSH词,全文虽好但API获取成本高、处理慢。我个人习惯先吃摘要,精度不够再补全文段落。

这里有一个我在项目里遇到的坑——你以为MeSH词都是规范的,但其实有些新发现的靶点并不在MeSH词表里。所以你不能完全依赖MeSH,还得从摘要的文本中抽。

2.2 PubMed检索基础

PubMed的检索引擎,本质上就是一个高级搜索语法。我建议你直接学它的核心语法,比点网页按钮快几倍。下面是我常用的几个检索操:

操作符 示例 说明
[tiab] aspirin[tiab] 限定在标题/摘要中搜索
[mh] Neoplasms[mh] MeSH主题词搜索
[pt] Review[pt] 限定文献类型
AND/OR/NOT drug AND target 布尔逻辑组合
#1 AND #2 — 引用历史检索编号

举个例子,我想搜“阿司匹林与癌症靶点”的综述文献:

aspirin[tiab] AND (cancer[tiab] OR neoplasms[mh]) AND Review[pt]

为什么会这样写?因为直接用cancer搜全文的话,匹配的文献量太大了。限定在[tiab]和[mh]能缩小范围,而且review类型的文献往往综述性地总结了靶点信息,省去你自己从头筛一遍的功夫。

2.3 PubMed API:E-utilities入门

很多时候我们不需要在网页上一条一条点。爬虫?不,PubMed官方提供了API——E-utilities。我常常用它们来批量获取文献数据。核心API有4个:

  • ESearch:根据查询词返回PMID列表
  • EFetch:根据PMID拉取详细记录(XML或JSON)
  • ESummary:获取摘要信息(比EFetch轻量)
  • ELink:获取与文献关联的其他数据库条目(比如PMC、Gene)

避坑指南:我曾经一次性发了200个请求到EFetch,结果PubMed把我的IP封了半小时。官方的限制是每秒3个请求,API key允许每秒10个。记得一定要限速,不然你这个月的数据采集计划就泡汤了。

一个最简单的ESearch调用示例(用Python的requests):

import requests

base_url = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/"
query = "aspirin AND therapeutic target[tiab]"

# 第一步:搜索
search_url = f"{base_url}esearch.fcgi?db=pubmed&term={query}&retmax=10&retmode=json"
resp = requests.get(search_url)
data = resp.json()
id_list = data["esearchresult"]["idlist"]
print(id_list)

# 第二步:取摘要
for pmid in id_list:
    fetch_url = f"{base_url}efetch.fcgi?db=pubmed&id={pmid}&retmode=xml"
    # 解析XML的细节后面会讲,这里只是展示流程

嗯,这里要注意一下retmode=json和retmode=xml的区别。ESearch的JSON模式很轻量,适合快速获取列表;但EFetch的JSON模式不如XML模式的信息完整。我个人习惯EFetch一律用XML,然后解析。

2.4 文献结构的核心:XML解析准备

EFetch返回的XML结构,才是我们真正要操作的对象。你想想看,一篇文献的标题、摘要、作者、MeSH词都嵌套在XML标签里。典型的层次是这样:

<PubmedArticle>
  <MedlineCitation>
    <Article>
      <ArticleTitle>Aspirin targets...</ArticleTitle>
      <Abstract>
        <AbstractText>...</AbstractText>
      </Abstract>
      <KeywordList>
        <Keyword>drug target</Keyword>
      </KeywordList>
    </Article>
    <ChemicalList>
      <Chemical>
        <NameOfSubstance>Aspirin</NameOfSubstance>
      </Chemical>
    </ChemicalList>
  </MedlineCitation>
</PubmedArticle>

看到了吗?药物名称藏在<ChemicalList>里,靶点信息在<Keyword>或<Abstract>中。这就给我们的自动抽取提供了明确的定位路径。

注意:有些文献的<Abstract>是空的,或者只有部分段落。这时候你只能靠MeSH词和ChemicalList来推断靶点。遇到这种情况,我通常会标记为“低置信度”,不纳入最终数据集,避免把噪声带进去。

2.5 本章知识体系一览

生物医学文本挖掘基础层 生物医学文献结构 PubMed检索语法 E-utilities API XML/JSON 药物靶点自动抽取核心 标题/摘要解析 定位靶点关键词 MeSH术语过滤 标准化语义提取 化学物质映射 药物-靶点关联

上图展示的是我从文献到靶点抽取的完整知识链路。底层是文献结构理解,中间层是检索与API获取数据,上层才是真正的抽取算法。如果你把文献结构搞明白,检索语法熟练,API调用顺手,基本上就搭建好了整个课程的基础设施。

一句话总结:这一章你只需要盯紧三件事——文献长什么样(结构),怎么找到目标文献(检索),怎么批量拿数据(API)。后面的章节全部建立在这三点之上。

我记得第一次给研究生讲这部分时,有人问为什么不直接从全文PDF里抽。我当时给的回答是:PDF解析的噪声太大,而PubMed的结构化数据,尤其是MeSH词和Chemical列表,是人类专家标引过的,质量高得多。除非你需要补充细节,否则先用结构化的数据。