4. 药物数据清洗与预处理

药物数据来自药品说明书、临床试验登记、文献抽取、公开数据库和内部药历系统,天然带有大量“脏”特征:字段缺失、同一实体多种写法、剂量单位混杂、化学结构表示不统一、文本编码与格式各异。如果直接把这些数据灌入知识图谱,节点会重复、关系会错连、数值比较会失真。数据清洗与预处理的目标,就是把异构、含噪的原始记录转换成可对齐、可计算、可追溯的规范化三元组素材。本节围绕缺失值处理、实体别名归一化、剂量单位统一、化学结构标准化、文本编码与格式转换五个环节展开。

缺失值处理:先判断缺失机制,再决定策略

缺失值不能一律删除或一律填充。首先要区分三类机制:完全随机缺失(MCAR)、随机缺失(MAR)和非随机缺失(MNAR)。例如“适应症”字段缺失往往与数据来源有关,属于 MNAR,直接删除会系统性丢失某类药品信息。工程上可按字段重要度分层处理:

  • 关键标识字段(药品通用名、CAS 号、InChIKey):缺失则记录无法入图,标记为隔离区待人工补录,不参与自动对齐。
  • 属性字段(剂型、规格、给药途径):可用同通用名、同批准文号的记录做众数填充,并记录填充来源。
  • 数值字段(剂量、半衰期):优先按同活性成分、同给药途径的中位数填充;若缺失比例超过阈值(示例取 40%),该字段不进入图谱属性,避免引入偏差。

无论采用哪种策略,都应在记录上保留 missing_flag 与 impute_source 两个溯源字段,使后续审计能区分“原始值”和“推断值”。

实体别名归一化:把多种写法收敛到唯一标识

同一药物常有通用名、商品名、英文名、缩写、盐型名和拼写变体。例如“阿司匹林”“乙酰水杨酸”“Aspirin”“ASA”“acetylsalicylic acid”指向同一活性成分。归一化的核心是建立别名到标准实体的映射,而不是简单字符串替换。

推荐流程为:先做文本规范化(统一大小写、全半角、去除多余空格与标点),再用规则匹配处理盐型与剂型后缀(如“盐酸”“钠”“片”“注射液”),最后用词典加相似度做候选召回。对候选对计算编辑距离或字符 n-gram 相似度,超过阈值(示例取 0.92)自动合并,处于灰区(0.80~0.92)的进入人工复核队列。归一化结果应写入 drug_alias 表,字段包括 alias、standard_id、match_type(exact/rule/fuzzy/manual)和 confidence,保证每次合并可回溯。

药物数据清洗与预处理:五条并行处理链 原始记录 说明书 临床试验登记 文献抽取 公开数据库 内部药历 缺失 / 别名 / 单位 结构 / 编码 混杂 ① 缺失值处理 MCAR/MAR/MNAR 判定 → 关键标识隔离 · 属性众数填充 · 数值中位数填充 输出:missing_flag、impute_source 溯源字段 ② 实体别名归一化 文本规范化 → 盐型/剂型规则 → 词典+相似度召回 → 阈值合并/人工复核 输出:drug_alias(alias, standard_id, match_type, confidence) ③ 剂量单位统一 质量/效价/体积换算 → 统一到 mg 或 IU → 按体重/体表面积归一 输出:dose_value、dose_unit、dose_basis ④ 化学结构标准化 SMILES 解析 → 加氢/去盐/中和 → 生成 InChI 与 InChIKey 输出:canonical_smiles、inchi、inchikey(结构唯一标识) ⑤ 文本编码与格式转换 UTF-8 统一 → 全半角/换行/空白规范化 → JSON/CSV/RDF 格式对齐 输出:统一编码的规范化记录 规范化输出 唯一实体 ID 标准剂量值 InChIKey 统一编码文本 溯源字段 → 三元组素材 (头实体, 关系, 尾实体) 可直接入图 五条链可并行执行,但结构标准化与别名归一化需在入图前完成交叉校验

剂量单位统一:让数值可比较

剂量字段常见“mg”“g”“μg”“IU”“mL”“片”等混用,还有“按体重给药”的 mg/kg 和“按体表面积给药”的 mg/m²。统一策略是:先识别单位并换算到基准单位,再保留给药依据。质量类统一到 mg:1 g = 1000 mg,1 μg = 0.001 mg;效价类(如维生素、肝素)保留 IU 并单独建维度,不与质量直接换算。对于 mg/kg 类剂量,需同时保留体重基准值,否则无法还原绝对剂量。

示例:某记录为“阿司匹林 0.5 g,口服,每日一次”,换算后得到 dose_value=500、dose_unit=mg、dose_basis=absolute。若记录为“10 mg/kg,每日两次”,则保留 dose_basis=per_kg,并在入图时关联体重属性节点,避免与绝对剂量直接比较。

化学结构标准化:SMILES 与 InChI 的协同

化学结构表示不统一是药物图谱对齐的最大障碍之一。SMILES 适合机器解析和子结构检索,但同一分子可有多种合法 SMILES 写法;InChI 是 IUPAC 标准表示,InChIKey 是固定长度哈希,适合做唯一键。标准流程为:读取原始 SMILES → 用化学工具包解析并检查合法性 → 去盐、中和、加氢 → 生成 canonical SMILES → 计算 InChI 与 InChIKey。若原始记录只有名称而无结构,则通过名称到结构的映射服务补全,并标记来源。

需要注意立体化学与互变异构:同一药物的 R/S 构型不同可能对应不同活性,标准化时必须保留立体信息;盐型(如盐酸盐)应去盐后与游离碱对齐,但盐型本身可作为独立属性保留。InChIKey 的前 14 位对应骨架连接性,后段包含立体与质子化信息,可作为分层匹配依据。

文本编码与格式转换:统一到可解析的形态

多源数据常出现 GBK、GB18030、UTF-8 混用,导致中文乱码;还有全角半角、不可见字符、换行不一致等问题。处理顺序建议为:先探测编码并统一转为 UTF-8,再做 Unicode 规范化(NFKC),去除控制字符与多余空白,最后按目标格式输出。若下游是图数据库,可转换为 RDF 三元组或属性图导入格式;若下游是分析流程,可输出规范化 CSV 或 JSON Lines。

# 示例:编码探测与统一(伪代码)
raw = read_bytes("drug_raw.csv")
enc = detect_encoding(raw)          # 返回 'gb18030' 或 'utf-8'
text = raw.decode(enc, errors="replace")
text = unicodedata.normalize("NFKC", text)
text = re.sub(r"[\x00-\x1f]+", " ", text)
write_text("drug_clean.csv", text, encoding="utf-8")
清洗后的每条记录都应保留 source_id、clean_time、operator 三个溯源字段,便于出现错误对齐时快速定位并回滚。
不要在没有记录映射关系的情况下直接覆盖原始值。别名合并、单位换算、结构标准化都可能引入错误,保留原始字段与转换日志是质量审计的前提。

完成上述五步后,药物数据从“多源异构文本”变为“带唯一标识、标准数值、标准结构和统一编码的规范化记录”,为后续实体对齐、关系抽取和图谱入库提供了可靠输入。实际工程中,这五条链通常以流水线方式编排,每步输出中间结果并做质量抽检,确保错误不会在链路中累积放大。