# medicalQA **Repository Path**: qwq007/medical-qa ## Basic Information - **Project Name**: medicalQA - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-08-18 - **Last Updated**: 2024-08-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # medicalQA 基于知识图谱的医疗问答系统&基于NLP的闲聊对话系统 ## 项目介绍 本项目是基于知识图谱的医疗问答系统和基于NLP的闲聊对话系统的相结合。 **基于知识图谱的医疗问答系统**参考:https://www.bilibili.com/video/BV1kM41177Qy/?share_source=copy_web&vd_source=95fed988f97d34e05b7fb30ee44c6dcc **基于NLP的闲聊对话系统**由seq2seq框架外加attention机制构成,seq2seq框架的encoder和decoder都选用GRU网络,attention机制采用的是Luong Attention,模型评估采用了beam search集束搜索。 训练语料为青云https://github.com/codemayq/chinese-chatbot-corpus ### 技术选型 编程语言:python 关系数据库:MySQL 图数据库:neo4j 闲聊对话模型框架:pytorch ### 功能介绍 医疗方面可回答的问题包括: - 某疾病的相关介绍 - 某疾病的并发症有哪些 - 某疾病属于什么科属 - 某疾病需要做哪些检查 - 某药物能治愈什么疾病 - 患有某疾病时能吃什么 - 患有某疾病时不能吃什么 - 某疾病应该如何治疗 - 某疾病会有哪些症状 - 出现某症状后可能患的疾病有哪些 - 某疾病的病因是什么 - 治疗某疾病需要多长时间 - 如何预防某疾病 - 某疾病患病的概率 - 某疾病治愈的概率 - 某疾病是如何感染的 - 易感某疾病的人有哪些(易感人群) - 某药物的详细名称有哪些 ​ 若医疗问答系统未能分析出用户提问的类型或意图,会将文本将给闲聊对话模型处理;分析出但不属于上述提问类型中的某一个,则系统会回复“抱歉,我没听懂您的意思,试试换个问法。”。 ![项目运行流程图](./README_img/项目运行流程图-1724037342164-5.png) ### 数据库介绍 **neo4j图数据库**中存有超过4万个节点和将近70万条关系边。 节点包括: | 标签 | 备注 | 个数 | | :--------: | :--------------: | :---: | | disease | 疾病 | 8807 | | drug | 药物 | 3828 | | symptom | 症状 | 5998 | | food | 食物 | 4870 | | department | 科属 | 54 | | cure | 治疗方式 | 544 | | check | 检查方式 | 3354 | | producer | (本项目未使用) | 17201 | 关系边包括: | 类别 | 备注 | 个数 | | :-------: | :---------------------------: | :----: | | accompany | 某疾病的并发症 | 23998 | | category | 某疾病的科属 | 33562 | | check | 某疾病要做的检查 | 78836 | | cure | 某药物可治疗的疾病 | 119472 | | cure_way | 某疾病的治疗方式 | 42094 | | do_eat | 患某疾病时应该吃/推荐吃的食物 | 124902 | | not_eat | 患某疾病时不能吃的食物 | 44478 | | drug | 某疾病的治疗药物 | 119472 | | symptom | 某疾病的症状 | 109420 | **MySQL关系数据库**中包含两张表: - model表:用于存放模型的名称以及相关的配置。 | 列名 | 类型 | 约束 | 备注 | | :-------------------: | :----------: | :--------: | :-----------------: | | name | varchar(100) | 主键,非空 | 模型名称 | | batch_size | int | 默认为空 | 一批数据的数据量 | | embedding_dim | int | 默认为空 | embedding维度 | | dropout | float | 默认为空 | dropout比例 | | max_len | int | 默认为空 | 句子长度 | | learn_rate | float | 默认为空 | 学习率 | | num_layer | int | 默认为空 | 网络层层数 | | hidden_size | int | 默认为空 | 隐藏层层数 | | attention_method | vahrchar(10) | 默认为空 | 注意力机制方法 | | teacher_forcing_radio | float | 默认为空 | teacher_forcing比率 | - record表:用于记录模型训练时相关的信息,包括epoch数、训练的时间、损失值等(BLEU、CHRF和METEOR也可记录,但本项目还没实现)。 | 列名 | 类型 | 约束 | 备注 | | :--------: | :----------: | :--------------: | :------: | | id | int | 主键,非空,自增 | id | | model_name | varchar(100) | 默认为空 | 模型名称 | | epoch | int | 默认为空 | 训练次数 | | loss | float | 默认为空 | 损失值 | | BLEU | float | 默认为空 | BLEU值 | | CHRF | float | 默认为空 | CHRF值 | | METEOR | float | 默认为空 | METEOR值 | | train_time | datatime | 默认为空 | 训练时间 | ## 项目文件介绍 ``` medicalQA 项目根目录 --data 静态数据文件夹 ----dict 用于存放本项目知识图谱所有相关的实体名称 ----origin_data 用于存放构建知识图谱的源文件 ----processed_data 用于存放处理后的文件 ----question_key_words 用于存放本项目知识图谱所有相关的提问关键字 --prepare 预处理脚本文件夹 ----build_graph_data.py 用于搭建“构建知识图谱的”数据文件 ----build_medical_graph.py 运行可构建图数据库 --seq2seq_attention 闲聊机器人子项目的根目录 ----data 静态数据文件夹,用于存放训练闲聊对话模型的语料 ------origin_data 静态数据文件夹,用于存放语料文件的源文件 ------processed_data 静态数据文件夹,用于存放处理后的语料 ------user_dict 静态数据文件夹,jieba分词用的自定义词典 ----object 静态数据文件夹,用于存放不同epoch闲聊对话模型的训练参数文件,word2seq类文件 ----prepare 预处理脚本文件夹 ------build_chat_corpus.py 用于搭建“训练闲聊对话模型的”语料 ------build_word2seq.py 用于搭建word2seq类 ------distribution_analysis.py 用于分析闲聊语料,绘制分布图,大致确定模型的超参数 ----subModel 闲聊对话模型的子类文件夹 ------attention.py Attention类 ------decoder.py Decoder类 ------encoder.py Encoder类 ----utils 工具类文件夹 ------dao 数据处理接口类文件夹 --------impl 数据处理接口实现类文件夹 ----------modelDaoImpl.py ModelDao接口的实现类 ----------recordDaoImpl.py RecordDao接口类的实现类 --------modelDao.py ModelDao接口类,用于操作mysql数据库中的模型配置表 --------recordDao.py RecordDao接口类,用于操作mysql数据库中的训练日志表 ------record.py Record类,运行可查看某epoch对话模型的配置信息、模型训练过程中损失值loss的折线图、已储存对话模型都有哪些版本等 ------tokenizer.py Tokenizer类,用于中文文本分词 ------word_sequence.py Word2Sequence类,用于将文本转换为模型可训练的形式 ----config.py 配置文件,用于设置闲聊对话模型的相关配置 ----dataset.py Dataset类,用于加载语料,搭建DataLoader类 ----eval_model.py 用于评估闲聊对话模型,运行可单独使用闲聊机器人 ----model.py 闲聊机器人类 ----test_model.py 用于闲聊对话模型的单元测试 ----train_model.py 闲聊对话模型的训练文件 --utils 工具类文件夹 ----dao 数据处理接口文件夹 ------medicalGraphDao.py medicalGraphDao接口类,用于操作neo4j图数据库 ------impl 数据处理接口实现类文件夹 --------medicalGraphDaoImpl.py medicalGraphDao接口实现类 --chatBot.py 医疗问答机器人类,运行该脚本即可使用本系统 --config.py 配置文件,用于设置医疗问答机器人的相关配置 --dataBase.sql MySQL数据库脚本 --README.md 医疗问答系统介绍文件 ``` ## 使用说明 ### 基本配置 1. 打开医疗问答系统的配置文件config.py并运行,将控制台输出的路径赋值给ROOT_PATH,闲聊对话系统的配置文件同理。 如:配置文件运行后输出`C:\pythonProjucts\medicalQA`,则`ROOT_PATH = r'C:\pythonProjucts\medicalQA'` 2. 在医疗问答系统的配置文件config.py中修改自己neo4j的用户名USERNAME和密码PASSWORD(一般情况下PROFILE无需修改,如要修改,则还需要在`.\medicalQA\utils\dao\impl\medicalGraphDaoImpl.py`文件中修改图数据库的连接方式,即MedicalGraphDaoImpl类构造函数中的self.graph)。 3. 在闲聊对话系统的配置文件config.py中修改自己的用户名USERNAME和密码PASSWORD 4. 搭建MySQL数据库:运行MySQL数据库脚本dataBase.sql 5. 搭建neo4j图数据库: 1. 启动neo4j win:`neo4j console` 2. 运行py脚本build_medical_graph.py *ps:可在医疗问答系统的配置文件config.py中修改搭建图数据库数据的文件路径PROCESSED_DATA_PATH,`medical_data.csv`为所有数据;`medical2_data.csv`是部分数据,搭建和访问速度更快,适用于检验项目是否可行。* ### 训练新的闲聊对话模型 1. 数据处理 1. 将数据(已分词)以question_tokens和answer_tokens的形式存储到.csv文件当中,修改配置文件`.\seq2seq_attention\config.py`中的PROCESS_DATA_PATH路径指向该文件。 ![image-20240818191926772](./README_img/image-20240818191926772-1724037297491-3.png) 2. 运行文件`.\seq2seq_attention\prepare\distribution_analysis.py`进行数据分析,确定超参数max_len和batch_size,修改配置文件`.\seq2seq_attention\config.py`中的MAX_LEN和BATCH_SIZE(其他超参数也可以修改) 3. 另起一个模型名称,配置文件`.\seq2seq_attention\config.py`中修改MODEL_NAME。 4. 配置文件`.\seq2seq_attention\config.py`中注释掉word2seq的两句代码。 ![image-20240818193014453](.\readme_img\image-20240818193014453.png) 2. 搭建word2seq 1. 运行脚本`.\seq2seq_attention\prepare\build_word2seq.py`。 2. 配置文件`.\seq2seq_attention\config.py`中取消注释word2seq的两句代码。 3. 运行脚本`.\seq2seq_attention\train_model.py`,训练模型。 1. 函数epoch_train(epoch):从0开始训练当前模型。参数epoch表示训练次数,训练结束后会保存epoch版本的模型。 2. 函数base_epoch_train(baseEpoch, time_train):从某一个epoch版本的模型开始训练。参数baseEpoch表示基于baseEpoch版本的模型开始训练,参数time_train表示训练次数,训练结束后会保存baseEpoch+time_train版本的模型。 *ps:开始训练时,Record类会自动存储当前模型的配置信息到数据库表当中,自动开始记录模型训练过程中的损失值。若不想记录,将文件`.\seq2seq_attention\train_model.py`中record的赋值改为None(注解掉21行代码,解除注解第22行代码即可)。* ![image-20240818194110796](./README_img/image-20240818194110796-1724037246290-1.png) ### 切换要使用的闲聊对话模型 1. 配置文件`.\seq2seq_attention\config.py`中将MODEL_NAME改为要切换模型的名称,将超参数修改为切换后的模型的超参数。 *ps:若配置文件中的超参数与该模型在数据库表中存储的超参数不同,会抛出一下异常(比如max_len和learn_rate不同):`AssertionError: 当前加载模型的配置与config.py中的配置不同,需要修改模型名称或恢复配置:max_len(model: 15, config.py: 20) learn_rate(model: 0.001, config.py: 0.0001)`,此时可以另起一个模型名称重新训练一个模型,或按照异常信息修改config.py中相应的超参数。* 2. 配置文件中修改训练语料路径。 ### 使用医疗问答系统 1. 打开`.\medicalQA\chatBot.py`文件 1. 设置modelName 2. 设置EPOCH 3. 运行,即可在控制台处使用医疗问答系统(输入`exit`即可退出) ### 单独使用闲聊对话系统 1. 打开`.\medicalQA\seq2seq_attention\eval_model.py`文件 1. 设置modelName 2. 设置EPOCH 3. 运行,即可在控制台处使用闲聊对话系统(输入`exit`即可退出) ### 查看搭建的图数据库 使用neo4j图形数据库提供的一个可视化工具neo4j browser。 1. `window + r`,输入`cmd`并回车,打开控制台。 2. 控制台中输入`neo4j console`并回车。 3. 稍等片刻后,打开浏览器并访问`http://localhost:7474/`(若是第一次访问,还需输入用户名和密码,初次登录默认用户名和密码都为`neo4j`)。 ### Record类的介绍与使用说明 `.\medicalQA\seq2seq_attention\utils\record.py`文件中的Record类主要用于查看模型相关的配置信息和训练日志。 1. 类方法show_all_model_info:输出数据库中model表存有的所有模型配置信息。 2. 通过模型名称声明一个Record类。 1. 函数record:记录一条训练信息(在训练模型时使用)。 2. 函数get_model_info:获取当前模型配置信息(一般配合其他函数使用)。 3. 函数get_max_epoch_info:获取当前模型训练次数最多的一次训练记录。 4. 函数get_all_model_epoch:获取当前模型拥有的epoch版本。 5. 函数show_linePlot:获取当前模型的训练记录的折线图,默认获取epoch最大的,损失值loss的折线图。 6. 函数print_model_info:以一定格式输出当前模型的配置信息。 需要查看哪些信息,在record.py文件底下键入相应的函数并运行即可。