中医药知识图谱与路径推理问答系统实战

发布时间:2026/9/14 4:15:22
中医药知识图谱与路径推理问答系统实战
简介本资源是一套基于PyTorch实现的中医药知识图谱智能问答系统源码面向计算机、人工智能、生物信息及中医药信息化相关专业的本科生与研究生适用于课程设计、期末大作业或毕业设计参考。系统融合知识图谱构建、自然语言处理与深度学习推理完整覆盖从中医实体识别、关系抽取、图谱构建到语义问答生成的全流程技术实践。压缩包共15个文件含9个核心Python脚本如KG.py、ans_bot.py、train_ner.py等、3个备份文件.zbak、1个Markdown说明文档、1张问答流程示意图及1个嵌套ZIP备份总大小仅243KB轻量但结构完整便于快速部署与代码研读。已有41人下载学习读者可直接获取可运行的端到端实现方案、模块化清晰的目录结构、关键环节的注释说明以及中医药领域特有的NER与实体链接实践逻辑是理解知识图谱与AI问答交叉应用的优质入门范例。1. 这不是通用问答模型而是一套可落地的中医药领域语义推理闭环你手头拿到的这个.zip包表面看是“PyTorch 知识图谱 问答系统”但实际它绕开了 LLM 时代常见的幻觉陷阱——它不靠大模型胡编乱造而是用结构化知识约束语义边界用路径推理替代概率采样。当你问“黄芪配当归能治什么病”系统不会泛泛回答“补气养血”而是从 KG.py 构建的实体关系图中定位到黄芪→功效→补气、当归→功效→补血、补气补血→适应症→气血两虚证再关联到《中医内科学》标准证型库最终返回带出处依据的答案。这种设计对课程设计者极其友好它不依赖 GPU 集群单卡 RTX 3060 即可完成 NER 训练与路径检索所有模块mention_extrator.py 做实体识别、path_extrator.py 做子图路径挖掘、ans_bot.py 做答案生成都封装为独立可调试脚本没有黑盒 wrapper更关键的是它把“知识图谱构建”和“深度学习推理”真正耦合在一起——比如 path_feature.py 不是简单拼接向量而是用 PyTorch 实现了基于 TransR 的关系路径嵌入让“黄芪-主治-高血压”这条路径在向量空间里天然靠近“天麻-主治-高血压”路径。适合计算机/信工专业学生做期末大作业代码有注释、流程有 png 图、README.md.zbak 里甚至保留了答辩时被问到的三个关键问题及应答逻辑。2. 知识图谱构建从非结构化文本到可计算三元组的工程化落地2.1 中医药领域知识的特殊性决定了图谱构建必须分层处理通用知识图谱如 Wikidata强调广度而中医药知识图谱必须解决三个硬约束术语歧义同一药材名在不同典籍中含义不同如“苍术”在《本草纲目》指北苍术在《中药学》教材中常指茅苍术关系模糊《伤寒论》中“桂枝汤证”的“证”不是实体而是症状组合的抽象模式无法直接映射为(桂枝汤, 主治, 桂枝汤证)数据稀疏权威典籍中明确写出的三元组极少大量知识隐含在“若……则……”“……者……也”等文言句式中。因此该源码未采用直接爬取维基或 CNKI 的粗暴方式而是通过KG.py定义了四层结构基础层标准化药材、方剂、证候、症状实体来自《中华人民共和国药典》2020版 《中医临床诊疗术语》国家标准关系层人工校验的 7 类核心关系主治、配伍禁忌、性味归经、功效、来源、鉴别、现代研究每类关系附带置信度标签规则层硬编码的中医逻辑规则如if 药材A.性味 甘温 and 药材B.性味 苦寒 then 配伍禁忌 True动态层由train_ner.py训练的 BiLSTM-CRF 模型识别出的新实体经人工审核后注入基础层。提示KG.py中build_kg_from_csv()方法读取的是data/kg_triples.csv该文件并非原始爬虫结果而是经过entitylink.py对齐过《本草纲目》《伤寒论》《金匮要略》三部典籍的标准化三元组——例如将《伤寒论》原文“芍药三两炙甘草三两”解析为(芍药, 配伍剂量, 3两)和(炙甘草, 配伍剂量, 3两)并链接到基础层中的芍药实体 ID。2.2 实体识别与链接用 BiLSTM-CRF 解决古籍命名实体边界难题train_ner.py是整个系统 NLP 层的起点它训练的模型专为中医古籍优化输入特征不仅包含字向量用path_filter.py提取的 50 维 word2vec还叠加了 3 类领域特征字符级特征是否为药名常用字如“芪”“苓”“术”、是否为量词“两”“钱”“枚”位置特征是否出现在“主之”“治”“宜”等动词后 3 字内句法特征依存句法树中是否为“核心谓词”的宾语节点通过spacy-zh中文模型预处理。标签体系采用 BIOES 标注但扩展了B-HERB/I-HERB药材、B-FORMULA/I-FORMULA方剂、B-SYMPTOM/I-SYMPTOM症状三类避免将“六味地黄丸”错误切分为“六味/地黄/丸”。训练命令如下需先运行python data_preprocess.py生成data/ner_train.conllpython train_ner.py \ --train_path data/ner_train.conll \ --dev_path data/ner_dev.conll \ --embed_dim 50 \ --hidden_dim 128 \ --dropout 0.3 \ --lr 0.001 \ --batch_size 16 \ --epochs 30 \ --model_save_path models/ner_bilstm_crf.pth参数说明--embed_dim 50对应path_filter.py中预训练的 word2vec 维度若更换 embedding 需同步修改--hidden_dim 128BiLSTM 隐藏层维度实测在 RTX 3060 上 128 是精度与显存的平衡点256 会导致 OOM--dropout 0.3针对古籍文本短、样本少的特点防止过拟合--model_save_path保存路径必须与mention_extrator.py中加载路径一致否则ans_bot.py启动时报FileNotFoundError。2.3 实体链接用entitylink.py解决一物多名与古今异名entitylink.py的核心是EntityLinker类它不依赖外部 API而是构建了一个本地别名映射表data/alias_map.json。该表包含三类映射古今名映射{苍术: [北苍术, 茅苍术, 山精], 黄连: [川连, 鸡爪连]}典籍特有名映射{伤寒论: {桂枝汤: CN001, 麻黄汤: CN002}, 本草纲目: {黄芪: MM001, 人参: MM002}}剂量单位映射{两: 30.0, 钱: 3.0, 分: 0.3, 铢: 0.65}单位统一为克。关键函数link_entity(text, candidate_entities)的逻辑是对输入文本text如“用黄芪三十钱”调用mention_extrator.py识别出[黄芪, 三十钱]将黄芪在alias_map.json中查找所有别名生成候选集[黄芪, 箭芪, 戴椹]对每个候选名计算其与知识库中实体的语义相似度用path_feature.py中的 TransR 嵌入向量余弦距离返回相似度最高且超过阈值0.75的实体 ID如MM001。若未命中则触发 fallback 机制启动kgclass.py中的规则引擎根据“黄芪→补气→肺脾经”这一路径特征匹配知识库中具有相同路径模式的实体。参数默认值说明similarity_threshold0.75低于此值视为链接失败进入规则引擎max_candidates5每个 mention 最多返回 5 个候选实体use_transr_embeddingTrue若设为 False则退化为字符串编辑距离匹配3. 问答推理基于路径特征的神经网络如何替代传统模板匹配3.1 为什么不用 BERT 微调——路径推理在小样本场景下的确定性优势该系统放弃主流的 BERTQA 微调方案根本原因在于中医药问答的低资源、高确定性特性训练数据不足公开的中医 QA 数据集如 CMNQA仅含 2,300 条问答对远低于 BERT 微调所需答案需可溯源医生需要知道答案来自哪条典籍原文而非模型“觉得”正确关系类型固定90% 的问题集中在X 的功效是什么Y 和 Z 能否同用A 方主治什么证三类模板覆盖率达 98%。因此ans_bot.py的核心是PathBasedQAEngine它将问题分解为三步问题解析用mention_extrator.py识别问题中的实体如“黄芪”“当归”和意图关键词如“配伍”“主治”路径检索在知识图谱中搜索从主实体出发、经指定关系到达目标实体的所有路径如黄芪 → 功效 → 补气 → 适应症 → 气血两虚证路径打分用path_feature.py中的 PyTorch 模型对每条路径计算置信度公式为$$ \text{score} \sigma\left( \mathbf{w}^T \cdot \text{MLP}\left( [\mathbf{e}_s; \mathbf{r}_1; \mathbf{e}_1; \mathbf{r}_2; \mathbf{e}_t] \right) \right) $$其中σ是 sigmoid[ ; ]表示向量拼接e_s/e_t是首尾实体嵌入r_i是关系嵌入MLP是两层全连接网络。3.2path_feature.py用 TransR 实现关系感知的路径嵌入path_feature.py中的TransRPathEncoder类是技术亮点。它改进了 TransE 的缺陷TransE 将实体和关系映射到同一空间导致(头实体, 关系)与(尾实体)的向量差无法区分不同关系路径。TransR 则为每个关系r分配一个投影矩阵M_r将头实体e_h投影到关系r的特定空间$$ \mathbf{e}_h^{(r)} \mathbf{e}_h \cdot \mathbf{M}_r $$再计算$$ f_r(\mathbf{e}_h, \mathbf{e}_t) | \mathbf{e}_h^{(r)} \mathbf{r} - \mathbf{e}_t^{(r)} |_2^2 $$该源码实现了路径级 TransR对长度为k的路径p (e_0, r_1, e_1, r_2, ..., e_k)其嵌入为$$ \mathbf{p} \text{GRU}\left( [\mathbf{e}_0^{(r_1)}; \mathbf{r}_1], [\mathbf{e}_1^{(r_2)}; \mathbf{r}2], ..., [\mathbf{e}{k-1}^{(r_k)}; \mathbf{r}_k] \right) $$其中 GRU 隐藏层输出作为路径特征向量输入path_extrator.py的分类器。训练此模型的关键命令需先运行python kg_to_triples.py生成data/kg_paths.pklpython path_feature.py \ --triples_path data/kg_triples.csv \ --paths_path data/kg_paths.pkl \ --embedding_dim 100 \ --relation_dim 100 \ --num_epochs 50 \ --batch_size 64 \ --lr 0.0005 \ --model_save_path models/transr_path_encoder.pth参数说明--embedding_dim 100实体嵌入维度与KG.py中entity_embedding初始化维度一致--relation_dim 100关系嵌入维度必须等于embedding_dim否则M_r矩阵乘法维度不匹配--lr 0.0005TransR 训练对学习率敏感0.001 易发散0.0001 收敛太慢--model_save_path此路径必须与ans_bot.py中load_state_dict()加载路径严格一致。3.3ans_bot.py从路径到答案的生成式后处理ans_bot.py的generate_answer()方法不直接返回路径而是进行三重后处理路径过滤剔除长度 5 的路径中医知识链通常 ≤ 3 跳过长路径可信度骤降证据标注对每条路径提取其在典籍中的原始出处。例如路径黄芪→功效→补气→适应症→气血两虚证会关联到《中医内科学》第 47 页“气血两虚证”条目自然语言生成用模板填充而非 NLG 模型。模板库data/answer_templates.json包含{ 功效: 【{entity}】的功效是{value}见于《{source}》。, 配伍禁忌: 【{e1}】与【{e2}】存在配伍禁忌依据为《{source}》中‘{rule}’。, 主治: 【{formula}】主治{syndrome}适用于{symptoms}等症状。 }其中{source}从路径中e_t.source字段获取{rule}从KG.py的rules字典中匹配。启动问答服务的命令python ans_bot.py --kg_path data/kg_triples.csv --model_path models/transr_path_encoder.pth此时服务监听http://localhost:5000/qaPOST 请求体为 JSON{question: 黄芪和当归一起用有什么功效}返回结构化答案{ answer: 【黄芪】与【当归】配伍的功效是补气养血见于《中医方剂学》第 123 页。, evidence: [ {path: [黄芪, 功效, 补气], source: 中医方剂学}, {path: [当归, 功效, 补血], source: 中药学} ], confidence: 0.92 }4. 期末大作业实战三步完成可演示的完整系统4.1 环境配置避开 Anaconda PyTorch 的常见陷阱该系统要求 Python ≥ 3.8PyTorch ≥ 1.10因path_feature.py使用了torch.nn.GRU的batch_firstTrue参数。严禁直接pip install torch必须按官网推荐方式安装以匹配 CUDA 版本# 查看本机 CUDA 版本Ubuntu nvidia-smi | grep CUDA Version # 若显示 CUDA Version: 11.3则执行 pip3 install torch1.10.0cu113 torchvision0.11.1cu113 torchaudio0.10.0cu113 -f https://download.pytorch.org/whl/torch_stable.html # 验证安装 python -c import torch; print(torch.__version__, torch.cuda.is_available())注意若torch.cuda.is_available()返回False检查nvidia-driver是否安装sudo apt install nvidia-driver-470并确认用户已加入video组sudo usermod -a -G video $USER。依赖包安装顺序至关重要pip install spacy3.4.4 scikit-learn1.1.3 pandas1.5.3 numpy1.23.5 python -m spacy download zh_core_web_sm pip install -r requirements.txt # 此文件在源码根目录含 torch-scatter 等图神经网络依赖requirements.txt中torch-scatter必须与 PyTorch 版本严格匹配否则path_extrator.py导入失败。若报错undefined symbol: _ZN3c104cuda17getCurrentCUDADeviceIdEv说明版本不兼容需卸载重装pip uninstall torch-scatter -y pip install torch-scatter2.1.0cu113 -f https://data.pyg.org/whl/torch-1.10.0.html4.2 数据准备从零构建最小可运行知识图谱无需下载外部数据集源码自带data/sample_corpus/目录含 3 个文件bencao_gangmu.txt《本草纲目》节选药材描述shanghan_lun.txt《伤寒论》方剂条文zhongyi_neike.txt《中医内科学》证候定义。运行初始化脚本python data_preprocess.py --corpus_dir data/sample_corpus/ --output_dir data/该脚本执行用spacy-zh分句、分词调用train_ner.py的预训练模型models/ner_bilstm_crf.pth识别实体通过entitylink.py对齐到data/standard_entities.json生成data/kg_triples.csv三元组和data/kg_paths.pkl路径样本。验证图谱质量head -n 5 data/kg_triples.csv # 输出示例 # 黄芪,功效,补气 # 当归,功效,补血 # 黄芪,性味归经,甘温肺脾经 # 桂枝汤,主治,太阳中风证 # 太阳中风证,症状,发热恶寒4.3 模型训练与问答演示一条命令跑通全流程按顺序执行以下命令每步耗时约 2–8 分钟无需 GPU 亦可运行 CPU 版本# 1. 训练实体识别模型CPU 模式 python train_ner.py --cpu --epochs 10 # 2. 构建知识图谱 python KG.py --input data/kg_triples.csv --output data/kg.pkl # 3. 训练路径编码器 python path_feature.py --cpu --num_epochs 20 # 4. 启动问答服务 python ans_bot.py --cpu打开浏览器访问http://localhost:5000输入问题测试“黄芪的功效是什么” → 返回“补气见于《本草纲目》”“麻黄汤主治什么” → 返回“太阳伤寒证适用于恶寒发热、无汗而喘等症状。”“黄连和吴茱萸能一起用吗” → 返回“存在配伍禁忌依据为《中药学》中‘辛热之品反佐苦寒’。”提示若答案为空检查ans_bot.py第 87 行self.path_encoder.eval()是否被注释——训练模式下 dropout 会干扰推理必须设为 eval 模式。4.4 答辩技巧如何向导师解释“为什么不用大模型”在答辩中当被问及“为何不采用 ChatGLM 或 Qwen 微调”时可聚焦三点可解释性展示问答流程.png中的路径可视化指出每条答案都有典籍出处而大模型无法提供确定性溯源资源效率对比数据——该系统在 4GB 显存上训练 30 分钟而微调 7B 模型需 24GB 显存12 小时领域适配性举反例——让大模型回答“《伤寒论》中桂枝汤的原方剂量”它可能编造“桂枝三钱”而本系统精确返回“桂枝三两约 90 克”因entitylink.py已将“两”映射为 30 克。最后将models/目录压缩为final_model.zip连同问答流程.png和README.md.zbak中的答辩问题清单一并提交——这比单纯交源码更能体现工程思维。本文还有配套的精品资源点击获取