中药大数据(三)中医知识图谱的创建

铁佛  金牌会员 | 2025-3-21 03:29:25 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 987|帖子 987|积分 2961

本项目纯原创,转载请说明。
如果各人有其他必要制作的知识图谱,大概要基于知识图谱做一些应用,也欢迎接洽!
1 先看下效果

(1)总体图谱数据

(2)性味归经【部门】

(3)医学册本收录方剂【部门】


(4)医学册本收录药材【部门】

(5)方剂的构成药材【部门】

2 数据预处理

要做的事情是从处方字段中提取出所有的方剂
也就是根据以下的数据去提取药材

代码如下:
  1. # 读取 tb_prescriptions 和 tb_cmedicine 数据
  2. df_prescriptions = pd.read_sql('SELECT * FROM tb_prescription', cnn)  # 方剂表
  3. df_cmedicine = pd.read_sql('SELECT title FROM tb_cmedicine', cnn)  # 中药表
  4. # 获取中药名列表,并按长度从大到小排序
  5. medicine_titles = df_cmedicine['title'].tolist()
  6. medicine_titles.sort(key=len, reverse=True)  # 按长度排序,长的药名优先匹配
  7. # 函数:检查每个 prescription 中出现了哪些中药(最大匹配)
  8. def find_medicines_in_prescription(prescription, medicine_titles):
  9.     found_medicines = []
  10.     for medicine in medicine_titles:
  11.         if medicine in prescription:
  12.             found_medicines.append(medicine)
  13.             # 将匹配到的药名从 prescription 中移除,避免重复匹配较短的名称
  14.             prescription = prescription.replace(medicine, '')
  15.     return ','.join(found_medicines)
  16. # 遍历 prescription 列,并检查每个方剂中包含的中药
  17. df_prescriptions['found_medicines'] = df_prescriptions['prescription'].apply(find_medicines_in_prescription, args=(medicine_titles,))
  18. # 打印结果:prescription 中找到的中药
  19. for index, row in df_prescriptions.iterrows():
  20.     print(f"Prescription: {row['prescription']}\nFound Medicines: {row['found_medicines']}\n")
  21. # 将提取的中药信息更新到 tb_prescription 表的 fangji 字段
  22. for index, row in df_prescriptions.iterrows():
  23.     found_medicines = row['found_medicines']
  24.     # 更新 tb_prescription 表的 fangji 字段
  25.     update_query = f"""
  26.     UPDATE tb_prescription
  27.     SET fangji = '{found_medicines}'
  28.     WHERE id = {row['id']}  -- 假设 tb_prescription 表有一个 id 字段作为主键
  29.     """
  30.     # 执行 SQL 更新语句
  31.     cnn.execute(update_query)
  32. # 确保关闭连接
  33. cnn.close()
复制代码
其中有一个题目:
Prescription: 春酒5升,葶苈子2升。
Found Medicines: 酒,葶苈子,葶苈
药方里出现了苈子,但是匹配的时间葶苈子,葶苈都匹配了,出现这个题目主要是匹配的时间应该是最大匹配,就是类似要有贪心头脑。
3 neo4j 知识图谱构建代码

下面贴出部门的Neo4j导入的代码
创建节点尽可能用merge语句,否则会出现大量重复节点
  1. # 连接到 Neo4j 数据库
  2. # 读取 tb_prescription 和 tb_cmedicine 数据
  3. df_prescriptions = pd.read_sql('SELECT * FROM tb_prescription', cnn)
  4. df_cmedicine = pd.read_sql('SELECT * FROM tb_cmedicine', cnn)
  5. # 将 tb_cmedicine 转换为字典,方便根据药名查找对应的药材信息
  6. cmedicine_dict = df_cmedicine.set_index('title').T.to_dict()
  7. # 正则表达式,用于提取《》之间的书名号内容
  8. def extract_book_title(excerpt):
  9.     match = re.search(r'《([^》]+)》', excerpt)
  10.     if match:
  11.         return f'《{match.group(1)}》'
  12.     return None
  13. # 创建药方和药材的知识图谱,确保节点和关系不会重复
  14. for index, row in df_prescriptions.iterrows():
  15.     # 创建药方节点(防止重复)
  16.     prescription_node = Node("Prescription", name=row['title'],
  17.                              prescription=row['prescription'],
  18.                              making=row['making'],
  19.                              functional_indications=row['functional_indications'],
  20.                              usage=row['usage'],
  21.                              excerpt=row['excerpt'],
  22.                              care=row['care'])
  23.     graph.merge(prescription_node, "Prescription", "name")  # 防止重复创建方剂节点
  24.     # 分割 fangji 中的药材名称
  25.     medicines = row['fangji'].split(',') if row['fangji'] else []
  26.     for medicine in medicines:
  27.         medicine = medicine.strip()  # 去除药材名称前后的空格
  28.         # 从 tb_cmedicine 数据中获取该药材的详细信息
  29.         if medicine in cmedicine_dict:
  30.             med_info = cmedicine_dict[medicine]
  31.             # 创建药材节点(防止重复)
  32.             medicine_node = Node("Medicine", name=medicine,
  33.                                  pinyin=med_info.get('pinyin'),
  34.                                  alias=med_info.get('alias'),
  35.                                  source=med_info.get('source'),
  36.                                  english_name=med_info.get('english_name'),
  37.                                  habitat=med_info.get('habitat'),
  38.                                  flavor=med_info.get('flavor'),
  39.                                  functional_indications=med_info.get('functional_indications'),
  40.                                  usage=med_info.get('usage'),
  41.                                  excerpt=med_info.get('excerpt'),
  42.                                  provenance=med_info.get('provenance'),
  43.                                  shape_properties=med_info.get('shape_properties'),
  44.                                  attribution=med_info.get('attribution'),
  45.                                  prototype=med_info.get('prototype'),
  46.                                  discuss=med_info.get('discuss'),
  47.                                  chemical_composition=med_info.get('chemical_composition'))
  48.             graph.merge(medicine_node, "Medicine", "name")  # 防止重复创建药材节点
  49.             # 创建 Prescription -> Medicine 关系(防止重复)
  50.             relationship = Relationship(prescription_node, "所用药材", medicine_node)
  51.             graph.merge(relationship, "Prescription", "name")
  52.             # 提取古籍书名号《》中的内容并创建古籍节点(药材的摘录,防止重复)
  53.             book_title = extract_book_title(med_info.get('excerpt', ''))
  54.             if book_title:
  55.                 # 创建古籍节点(防止重复)
  56.                 book_node = Node("Book", name=book_title)
  57.                 graph.merge(book_node, "Book", "name")
  58.                 # 创建 Book -> Medicine 的 "收录药材" 关系(防止重复)
  59.                 recorded_relationship_medicine = Relationship(book_node, "收录药材", medicine_node)
  60.                 graph.merge(recorded_relationship_medicine, "Book", "name")
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

铁佛

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表