1198 lines
48 KiB
Python
1198 lines
48 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
四库深度挖掘分析 — 呼吸系统/咳嗽哮喘主题
|
||
生成MD报告和JSON关联数据
|
||
"""
|
||
|
||
import json
|
||
import os
|
||
import re
|
||
import glob
|
||
from collections import defaultdict, Counter
|
||
|
||
# ============================================================
|
||
# 配置
|
||
# ============================================================
|
||
BASE_DIR = "/home/songyi/Documents/ai_agent_scraper_study/data/大医网"
|
||
DISEASE_DIR = os.path.join(BASE_DIR, "01_来源数据", "疾病")
|
||
PRESCRIPTION_DIR = os.path.join(BASE_DIR, "01_来源数据", "方剂")
|
||
HERB_DIR = os.path.join(BASE_DIR, "01_来源数据", "中药材")
|
||
ACUPOINT_DIR = os.path.join(BASE_DIR, "01_来源数据", "针灸穴位")
|
||
OUTPUT_DIR_REPORT = os.path.join(BASE_DIR, "04_分析报告")
|
||
OUTPUT_DIR_JSON = os.path.join(BASE_DIR, "03_关联融合", "交叉关联分析")
|
||
|
||
MD_FILE = os.path.join(OUTPUT_DIR_REPORT, "咳嗽哮喘深度挖掘分析报告.md")
|
||
JSON_FILE = os.path.join(OUTPUT_DIR_JSON, "咳嗽哮喘_关联数据.json")
|
||
|
||
# 主题关键词定义(4层)
|
||
KEYWORDS_CORE = ['咳嗽', '哮喘', '肺气虚', '肺阴虚', '风寒束肺', '风热犯肺',
|
||
'痰热壅肺', '痰湿阻肺', '肺肾两虚', '肺燥', '肺热', '肺寒',
|
||
'肺气不宣', '肺失宣降', '风邪犯肺']
|
||
KEYWORDS_SPECIALTY = ['支气管炎', '肺炎', '慢性阻塞性肺疾病', '哮喘', '感冒',
|
||
'咽炎', '扁桃体炎', '鼻炎', '肺气肿', '肺结核',
|
||
'支气管扩张', '上呼吸道感染', 'COPD', '慢阻肺',
|
||
'肺纤维化', '肺结节']
|
||
KEYWORDS_SYMPTOM = ['咳嗽', '咳痰', '气喘', '咽痛', '发热', '鼻塞', '胸闷',
|
||
'呼吸困难', '流涕', '喷嚏', '咽痒', '喉鸣', '气促',
|
||
'咯血', '恶寒', '恶风', '喘息', '痰多']
|
||
KEYWORDS_TREATMENT = ['宣肺', '止咳', '化痰', '平喘', '清热', '润肺', '散寒',
|
||
'清肺', '降气', '祛痰', '肃肺', '敛肺', '温肺',
|
||
'疏风散寒', '疏风清热', '清热解毒', '滋阴润肺',
|
||
'补肺益气', '化痰止咳']
|
||
|
||
# 权重
|
||
WEIGHT_CORE = 3
|
||
WEIGHT_SPECIALTY = 2
|
||
WEIGHT_SYMPTOM = 1
|
||
WEIGHT_TREATMENT = 1
|
||
|
||
# 阈值
|
||
THRESHOLD_DISEASE = 5.0
|
||
THRESHOLD_PRESCRIPTION = 5.0
|
||
THRESHOLD_HERB = 3.0
|
||
THRESHOLD_ACUPOINT = 5.0
|
||
|
||
# 药材分类关键词映射
|
||
HERB_CLASSIFICATION_MAP = [
|
||
# 化痰止咳平喘药
|
||
(['化痰', '止咳平喘', '化痰止咳', '止咳化痰', '化痰药', '止咳平喘药'], '化痰止咳平喘药'),
|
||
# 清热药
|
||
(['清热', '清热解毒', '清热药', '清热泻火', '清热燥湿', '清热凉血', '清解'], '清热药'),
|
||
# 解表药
|
||
(['解表', '发散风寒', '发散风热', '解表药', '发表'], '解表药'),
|
||
# 补气药
|
||
(['补气', '益气', '补气药', '大补元气', '补脾益气', '补肺益气', '益气健脾'], '补气药'),
|
||
# 滋阴药/补阴药
|
||
(['滋阴', '养阴', '补阴', '滋阴药', '养阴药', '补阴药', '润肺'], '滋阴药'),
|
||
# 补血药
|
||
(['补血', '养血', '补血药'], '补血药'),
|
||
# 补阳药
|
||
(['补阳', '壮阳', '补肾阳', '补阳药'], '补阳药'),
|
||
# 理气药
|
||
(['理气', '行气', '理气药', '行气药', '疏肝理气', '破气'], '理气药'),
|
||
# 活血化瘀药
|
||
(['活血', '化瘀', '活血化瘀', '活血药', '活血祛瘀', '破血', '散瘀'], '活血化瘀药'),
|
||
# 温里药
|
||
(['温里', '温中', '散寒', '祛寒', '温里药', '温经', '温通'], '温里药'),
|
||
# 祛风湿药
|
||
(['祛风湿', '祛风除湿', '祛风湿药'], '祛风湿药'),
|
||
# 利水渗湿药
|
||
(['利水', '渗湿', '利尿', '利水渗湿', '利水消肿', '利尿通淋'], '利水渗湿药'),
|
||
# 安神药
|
||
(['安神', '养心安神', '重镇安神', '安神药', '宁心安神'], '安神药'),
|
||
# 平肝息风药
|
||
(['平肝', '息风', '平肝息风', '潜阳', '平肝潜阳', '息风止痉'], '平肝息风药'),
|
||
# 开窍药
|
||
(['开窍', '开窍药', '醒神', '开窍醒神'], '开窍药'),
|
||
# 收涩药
|
||
(['收涩', '固涩', '收敛', '固精', '止汗', '止泻', '收涩药'], '收涩药'),
|
||
# 泻下药
|
||
(['泻下', '攻下', '润下', '峻下', '泻下药', '通便', '攻下'], '泻下药'),
|
||
# 消食药
|
||
(['消食', '健胃消食', '消食药', '消积', '消食导滞'], '消食药'),
|
||
# 止血药
|
||
(['止血', '止血药', '凉血止血', '收敛止血', '化瘀止血', '温经止血'], '止血药'),
|
||
# 化湿药
|
||
(['化湿', '芳香化湿', '化湿药', '化湿和胃'], '化湿药'),
|
||
# 驱虫药
|
||
(['驱虫', '杀虫', '驱虫药'], '驱虫药'),
|
||
# 拔毒化腐生肌药
|
||
(['拔毒', '化腐', '生肌', '拔毒化腐'], '拔毒化腐生肌药'),
|
||
# 涌吐药
|
||
(['涌吐', '涌吐药'], '涌吐药'),
|
||
# 其他/未分类
|
||
]
|
||
|
||
# 药材分类补充映射 - 基于简介/功能中药名的分类
|
||
HERB_SPECIFIC_CLASSIFICATION = {
|
||
'贝母': '化痰止咳平喘药',
|
||
'川贝母': '化痰止咳平喘药',
|
||
'浙贝母': '化痰止咳平喘药',
|
||
'瓜蒌': '化痰止咳平喘药',
|
||
'桔梗': '化痰止咳平喘药',
|
||
'半夏': '化痰止咳平喘药',
|
||
'天南星': '化痰止咳平喘药',
|
||
'白前': '化痰止咳平喘药',
|
||
'前胡': '化痰止咳平喘药',
|
||
'旋覆花': '化痰止咳平喘药',
|
||
'竹茹': '化痰止咳平喘药',
|
||
'竹沥': '化痰止咳平喘药',
|
||
'天竺黄': '化痰止咳平喘药',
|
||
'海藻': '化痰止咳平喘药',
|
||
'昆布': '化痰止咳平喘药',
|
||
'杏仁': '化痰止咳平喘药',
|
||
'苦杏仁': '化痰止咳平喘药',
|
||
'紫苏子': '化痰止咳平喘药',
|
||
'苏子': '化痰止咳平喘药',
|
||
'葶苈子': '化痰止咳平喘药',
|
||
'桑白皮': '化痰止咳平喘药',
|
||
'款冬花': '化痰止咳平喘药',
|
||
'紫菀': '化痰止咳平喘药',
|
||
'枇杷叶': '化痰止咳平喘药',
|
||
'马兜铃': '化痰止咳平喘药',
|
||
'百部': '化痰止咳平喘药',
|
||
'白果': '化痰止咳平喘药',
|
||
'罗汉果': '化痰止咳平喘药',
|
||
'矮地茶': '化痰止咳平喘药',
|
||
'满山红': '化痰止咳平喘药',
|
||
'银杏': '化痰止咳平喘药',
|
||
'洋金花': '化痰止咳平喘药',
|
||
'黄药子': '化痰止咳平喘药',
|
||
'胖大海': '化痰止咳平喘药',
|
||
'木蝴蝶': '化痰止咳平喘药',
|
||
'青黛': '化痰止咳平喘药',
|
||
'礞石': '化痰止咳平喘药',
|
||
'蛤壳': '化痰止咳平喘药',
|
||
'海浮石': '化痰止咳平喘药',
|
||
'瓦楞子': '化痰止咳平喘药',
|
||
'皂荚': '化痰止咳平喘药',
|
||
'胆南星': '化痰止咳平喘药',
|
||
'金荞麦': '化痰止咳平喘药',
|
||
'黄芩': '清热药',
|
||
'黄连': '清热药',
|
||
'黄柏': '清热药',
|
||
'金银花': '清热药',
|
||
'连翘': '清热药',
|
||
'板蓝根': '清热药',
|
||
'大青叶': '清热药',
|
||
'石膏': '清热药',
|
||
'知母': '清热药',
|
||
'栀子': '清热药',
|
||
'夏枯草': '清热药',
|
||
'龙胆': '清热药',
|
||
'苦参': '清热药',
|
||
'白鲜皮': '清热药',
|
||
'蒲公英': '清热药',
|
||
'鱼腥草': '清热药',
|
||
'败酱草': '清热药',
|
||
'穿心莲': '清热药',
|
||
'牛黄': '清热药',
|
||
'熊胆': '清热药',
|
||
'赤芍': '清热药',
|
||
'牡丹皮': '清热药',
|
||
'紫草': '清热药',
|
||
'玄参': '清热药',
|
||
'生地黄': '清热药',
|
||
'地骨皮': '清热药',
|
||
'青蒿': '清热药',
|
||
'白薇': '清热药',
|
||
'胡黄连': '清热药',
|
||
'银柴胡': '清热药',
|
||
'射干': '清热药',
|
||
'山豆根': '清热药',
|
||
'马勃': '清热药',
|
||
'秦皮': '清热药',
|
||
'鸦胆子': '清热药',
|
||
'白花蛇舌草': '清热药',
|
||
'半边莲': '清热药',
|
||
'山慈菇': '清热药',
|
||
'土茯苓': '清热药',
|
||
'芦根': '清热药',
|
||
'天花粉': '清热药',
|
||
'竹叶': '清热药',
|
||
'淡竹叶': '清热药',
|
||
'决明子': '清热药',
|
||
'密蒙花': '清热药',
|
||
'谷精草': '清热药',
|
||
'麻黄': '解表药',
|
||
'桂枝': '解表药',
|
||
'紫苏': '解表药',
|
||
'生姜': '解表药',
|
||
'香薷': '解表药',
|
||
'荆芥': '解表药',
|
||
'防风': '解表药',
|
||
'羌活': '解表药',
|
||
'白芷': '解表药',
|
||
'细辛': '解表药',
|
||
'藁本': '解表药',
|
||
'苍耳子': '解表药',
|
||
'辛夷': '解表药',
|
||
'薄荷': '解表药',
|
||
'牛蒡子': '解表药',
|
||
'蝉蜕': '解表药',
|
||
'桑叶': '解表药',
|
||
'菊花': '解表药',
|
||
'葛根': '解表药',
|
||
'柴胡': '解表药',
|
||
'升麻': '解表药',
|
||
'淡豆豉': '解表药',
|
||
'浮萍': '解表药',
|
||
'木贼': '解表药',
|
||
'葱白': '解表药',
|
||
'鹅不食草': '解表药',
|
||
'人参': '补气药',
|
||
'党参': '补气药',
|
||
'黄芪': '补气药',
|
||
'白术': '补气药',
|
||
'甘草': '补气药',
|
||
'山药': '补气药',
|
||
'白扁豆': '补气药',
|
||
'大枣': '补气药',
|
||
'饴糖': '补气药',
|
||
'蜂蜜': '补气药',
|
||
'西洋参': '补气药',
|
||
'太子参': '补气药',
|
||
'沙参': '滋阴药',
|
||
'北沙参': '滋阴药',
|
||
'南沙参': '滋阴药',
|
||
'麦冬': '滋阴药',
|
||
'麦门冬': '滋阴药',
|
||
'天门冬': '滋阴药',
|
||
'天冬': '滋阴药',
|
||
'玉竹': '滋阴药',
|
||
'百合': '滋阴药',
|
||
'石斛': '滋阴药',
|
||
'黄精': '滋阴药',
|
||
'枸杞子': '滋阴药',
|
||
'墨旱莲': '滋阴药',
|
||
'旱莲草': '滋阴药',
|
||
'女贞子': '滋阴药',
|
||
'桑椹': '滋阴药',
|
||
'龟甲': '滋阴药',
|
||
'鳖甲': '滋阴药',
|
||
'黑芝麻': '滋阴药',
|
||
'当归': '补血药',
|
||
'熟地黄': '补血药',
|
||
'白芍': '补血药',
|
||
'何首乌': '补血药',
|
||
'阿胶': '补血药',
|
||
'龙眼肉': '补血药',
|
||
'紫河车': '补血药',
|
||
'鹿茸': '补阳药',
|
||
'巴戟天': '补阳药',
|
||
'淫羊藿': '补阳药',
|
||
'仙茅': '补阳药',
|
||
'杜仲': '补阳药',
|
||
'续断': '补阳药',
|
||
'狗脊': '补阳药',
|
||
'补骨脂': '补阳药',
|
||
'益智仁': '补阳药',
|
||
'冬虫夏草': '补阳药',
|
||
'蛤蚧': '补阳药',
|
||
'菟丝子': '补阳药',
|
||
'沙苑子': '补阳药',
|
||
'韭菜子': '补阳药',
|
||
'蛇床子': '补阳药',
|
||
'海马': '补阳药',
|
||
'海龙': '补阳药',
|
||
'肉苁蓉': '补阳药',
|
||
'锁阳': '补阳药',
|
||
'核桃仁': '补阳药',
|
||
'陈皮': '理气药',
|
||
'橘皮': '理气药',
|
||
'青皮': '理气药',
|
||
'枳实': '理气药',
|
||
'枳壳': '理气药',
|
||
'木香': '理气药',
|
||
'沉香': '理气药',
|
||
'檀香': '理气药',
|
||
'川楝子': '理气药',
|
||
'乌药': '理气药',
|
||
'荔枝核': '理气药',
|
||
'佛手': '理气药',
|
||
'香橼': '理气药',
|
||
'玫瑰花': '理气药',
|
||
'绿萼梅': '理气药',
|
||
'薤白': '理气药',
|
||
'大腹皮': '理气药',
|
||
'柿蒂': '理气药',
|
||
'刀豆': '理气药',
|
||
'甘松': '理气药',
|
||
'九香虫': '理气药',
|
||
'丹参': '活血化瘀药',
|
||
'川芎': '活血化瘀药',
|
||
'延胡索': '活血化瘀药',
|
||
'郁金': '活血化瘀药',
|
||
'姜黄': '活血化瘀药',
|
||
'乳香': '活血化瘀药',
|
||
'没药': '活血化瘀药',
|
||
'五灵脂': '活血化瘀药',
|
||
'红花': '活血化瘀药',
|
||
'桃仁': '活血化瘀药',
|
||
'益母草': '活血化瘀药',
|
||
'牛膝': '活血化瘀药',
|
||
'鸡血藤': '活血化瘀药',
|
||
'王不留行': '活血化瘀药',
|
||
'穿山甲': '活血化瘀药',
|
||
'土鳖虫': '活血化瘀药',
|
||
'水蛭': '活血化瘀药',
|
||
'虻虫': '活血化瘀药',
|
||
'斑蝥': '活血化瘀药',
|
||
'三棱': '活血化瘀药',
|
||
'莪术': '活血化瘀药',
|
||
'苏木': '活血化瘀药',
|
||
'自然铜': '活血化瘀药',
|
||
'血竭': '活血化瘀药',
|
||
'儿茶': '活血化瘀药',
|
||
'刘寄奴': '活血化瘀药',
|
||
'干漆': '活血化瘀药',
|
||
'附子': '温里药',
|
||
'肉桂': '温里药',
|
||
'干姜': '温里药',
|
||
'吴茱萸': '温里药',
|
||
'花椒': '温里药',
|
||
'丁香': '温里药',
|
||
'小茴香': '温里药',
|
||
'高良姜': '温里药',
|
||
'胡椒': '温里药',
|
||
'荜茇': '温里药',
|
||
'荜澄茄': '温里药',
|
||
'独活': '祛风湿药',
|
||
'威灵仙': '祛风湿药',
|
||
'川乌': '祛风湿药',
|
||
'蕲蛇': '祛风湿药',
|
||
'乌梢蛇': '祛风湿药',
|
||
'雷公藤': '祛风湿药',
|
||
'木瓜': '祛风湿药',
|
||
'蚕沙': '祛风湿药',
|
||
'秦艽': '祛风湿药',
|
||
'防己': '祛风湿药',
|
||
'桑枝': '祛风湿药',
|
||
'海桐皮': '祛风湿药',
|
||
'海风藤': '祛风湿药',
|
||
'五加皮': '祛风湿药',
|
||
'狗脊': '祛风湿药',
|
||
'桑寄生': '祛风湿药',
|
||
'茯苓': '利水渗湿药',
|
||
'猪苓': '利水渗湿药',
|
||
'泽泻': '利水渗湿药',
|
||
'薏苡仁': '利水渗湿药',
|
||
'车前草': '利水渗湿药',
|
||
'车前子': '利水渗湿药',
|
||
'滑石': '利水渗湿药',
|
||
'川木通': '利水渗湿药',
|
||
'通草': '利水渗湿药',
|
||
'瞿麦': '利水渗湿药',
|
||
'萹蓄': '利水渗湿药',
|
||
'地肤子': '利水渗湿药',
|
||
'海金沙': '利水渗湿药',
|
||
'石韦': '利水渗湿药',
|
||
'冬葵子': '利水渗湿药',
|
||
'灯心草': '利水渗湿药',
|
||
'萆薢': '利水渗湿药',
|
||
'茵陈': '利水渗湿药',
|
||
'金钱草': '利水渗湿药',
|
||
'虎杖': '利水渗湿药',
|
||
'赤小豆': '利水渗湿药',
|
||
'玉米须': '利水渗湿药',
|
||
'酸枣仁': '安神药',
|
||
'柏子仁': '安神药',
|
||
'远志': '安神药',
|
||
'合欢皮': '安神药',
|
||
'夜交藤': '安神药',
|
||
'龙骨': '安神药',
|
||
'牡蛎': '安神药',
|
||
'朱砂': '安神药',
|
||
'磁石': '安神药',
|
||
'琥珀': '安神药',
|
||
'石决明': '平肝息风药',
|
||
'珍珠母': '平肝息风药',
|
||
'代赭石': '平肝息风药',
|
||
'羚羊角': '平肝息风药',
|
||
'钩藤': '平肝息风药',
|
||
'天麻': '平肝息风药',
|
||
'地龙': '平肝息风药',
|
||
'全蝎': '平肝息风药',
|
||
'蜈蚣': '平肝息风药',
|
||
'僵蚕': '平肝息风药',
|
||
'白蒺藜': '平肝息风药',
|
||
'罗布麻': '平肝息风药',
|
||
'麝香': '开窍药',
|
||
'冰片': '开窍药',
|
||
'苏合香': '开窍药',
|
||
'石菖蒲': '开窍药',
|
||
'山茱萸': '收涩药',
|
||
'五味子': '收涩药',
|
||
'乌梅': '收涩药',
|
||
'诃子': '收涩药',
|
||
'肉豆蔻': '收涩药',
|
||
'赤石脂': '收涩药',
|
||
'禹余粮': '收涩药',
|
||
'莲子': '收涩药',
|
||
'芡实': '收涩药',
|
||
'金樱子': '收涩药',
|
||
'覆盆子': '收涩药',
|
||
'桑螵蛸': '收涩药',
|
||
'海螵蛸': '收涩药',
|
||
'浮小麦': '收涩药',
|
||
'糯稻根须': '收涩药',
|
||
'麻黄根': '收涩药',
|
||
'罂粟壳': '收涩药',
|
||
'椿皮': '收涩药',
|
||
'鸡冠花': '收涩药',
|
||
'大黄': '泻下药',
|
||
'芒硝': '泻下药',
|
||
'番泻叶': '泻下药',
|
||
'芦荟': '泻下药',
|
||
'火麻仁': '泻下药',
|
||
'郁李仁': '泻下药',
|
||
'松子仁': '泻下药',
|
||
'甘遂': '泻下药',
|
||
'大戟': '泻下药',
|
||
'芫花': '泻下药',
|
||
'商陆': '泻下药',
|
||
'牵牛子': '泻下药',
|
||
'巴豆': '泻下药',
|
||
'山楂': '消食药',
|
||
'神曲': '消食药',
|
||
'麦芽': '消食药',
|
||
'谷芽': '消食药',
|
||
'稻芽': '消食药',
|
||
'莱菔子': '消食药',
|
||
'鸡内金': '消食药',
|
||
'小蓟': '止血药',
|
||
'大蓟': '止血药',
|
||
'地榆': '止血药',
|
||
'槐花': '止血药',
|
||
'侧柏叶': '止血药',
|
||
'白茅根': '止血药',
|
||
'三七': '止血药',
|
||
'茜草': '止血药',
|
||
'蒲黄': '止血药',
|
||
'花蕊石': '止血药',
|
||
'降香': '止血药',
|
||
'白及': '止血药',
|
||
'仙鹤草': '止血药',
|
||
'紫珠': '止血药',
|
||
'棕榈炭': '止血药',
|
||
'血余炭': '止血药',
|
||
'藕节': '止血药',
|
||
'艾叶': '止血药',
|
||
'炮姜': '止血药',
|
||
'灶心土': '止血药',
|
||
'苍术': '化湿药',
|
||
'厚朴': '化湿药',
|
||
'广藿香': '化湿药',
|
||
'佩兰': '化湿药',
|
||
'砂仁': '化湿药',
|
||
'白豆蔻': '化湿药',
|
||
'草豆蔻': '化湿药',
|
||
'草果': '化湿药',
|
||
}
|
||
|
||
|
||
# ============================================================
|
||
# 工具函数
|
||
# ============================================================
|
||
|
||
def flatten_text(data_dict):
|
||
"""将JSON所有字段展平为纯文本字符串"""
|
||
texts = []
|
||
for key, value in data_dict.items():
|
||
if isinstance(value, dict):
|
||
for k2, v2 in value.items():
|
||
if isinstance(v2, str):
|
||
texts.append(v2)
|
||
elif isinstance(v2, (list, tuple)):
|
||
texts.extend([str(x) for x in v2])
|
||
elif isinstance(value, str):
|
||
texts.append(value)
|
||
elif isinstance(value, (list, tuple)):
|
||
texts.extend([str(x) for x in value])
|
||
return ' '.join(texts)
|
||
|
||
|
||
def load_all_json(directory):
|
||
"""加载目录下所有JSON文件"""
|
||
records = []
|
||
files = sorted(glob.glob(os.path.join(directory, '*.json')))
|
||
for fpath in files:
|
||
try:
|
||
with open(fpath, 'r', encoding='utf-8') as f:
|
||
data = json.load(f)
|
||
records.append(data)
|
||
except Exception as e:
|
||
print(f" Warning: failed to load {fpath}: {e}")
|
||
return records
|
||
|
||
|
||
def score_record(record, keywords_core, keywords_specialty, keywords_symptom, keywords_treatment):
|
||
"""对一条记录进行评分"""
|
||
text = flatten_text(record)
|
||
total_score = 0
|
||
matched_details = {'core': [], 'specialty': [], 'symptom': [], 'treatment': []}
|
||
|
||
# 核心证候 (+3)
|
||
for kw in keywords_core:
|
||
if kw in text:
|
||
total_score += WEIGHT_CORE
|
||
matched_details['core'].append(kw)
|
||
|
||
# 专科疾病 (+2)
|
||
for kw in keywords_specialty:
|
||
if kw in text:
|
||
total_score += WEIGHT_SPECIALTY
|
||
matched_details['specialty'].append(kw)
|
||
|
||
# 症状 (+1)
|
||
for kw in keywords_symptom:
|
||
if kw in text:
|
||
total_score += WEIGHT_SYMPTOM
|
||
matched_details['symptom'].append(kw)
|
||
|
||
# 治法 (+1)
|
||
for kw in keywords_treatment:
|
||
if kw in text:
|
||
total_score += WEIGHT_TREATMENT
|
||
matched_details['treatment'].append(kw)
|
||
|
||
return total_score, matched_details
|
||
|
||
|
||
def classify_herb(record):
|
||
"""对药材进行TCM功能分类"""
|
||
name = record.get('名称', '')
|
||
if name in HERB_SPECIFIC_CLASSIFICATION:
|
||
return HERB_SPECIFIC_CLASSIFICATION[name]
|
||
|
||
# 从文本中查找分类关键词
|
||
text = flatten_text(record)
|
||
|
||
# 先检查简介中的分类描述
|
||
intro = record.get('简介', '')
|
||
for keywords, category in HERB_CLASSIFICATION_MAP:
|
||
for kw in keywords:
|
||
if kw in intro or kw in text:
|
||
return category
|
||
|
||
# 再检查功效作用
|
||
func = str(record.get('功效作用', {}).get('功能', ''))
|
||
for keywords, category in HERB_CLASSIFICATION_MAP:
|
||
for kw in keywords:
|
||
if kw in func:
|
||
return category
|
||
|
||
# 检查性味归经 (归肺经等)
|
||
meridian = record.get('性味归经', '')
|
||
if '肺' in meridian and ('止咳' in text or '化痰' in text or '咳嗽' in text):
|
||
return '化痰止咳平喘药'
|
||
|
||
return '其他/未分类'
|
||
|
||
|
||
def longest_prefix_match(herb_name, text):
|
||
"""检查药材名是否在文本中出现(支持最长前缀匹配)"""
|
||
return herb_name in text
|
||
|
||
|
||
def extract_herb_names_from_text(text, herb_names_sorted):
|
||
"""从文本中提取出现的药材名(使用最长前缀匹配)"""
|
||
found = []
|
||
# 按长度降序排序,确保最长匹配优先
|
||
for hname in herb_names_sorted:
|
||
if hname in text:
|
||
found.append(hname)
|
||
return found
|
||
|
||
|
||
def build_cross_associations(diseases, prescriptions, herbs, acupoints,
|
||
herb_names_sorted):
|
||
"""构建交叉关联"""
|
||
assoc = {
|
||
'disease_prescription': [],
|
||
'disease_herb': [],
|
||
'prescription_herb': [],
|
||
'disease_acupoint': [],
|
||
}
|
||
|
||
# 疾病↔方剂(按主题关键词)
|
||
# 已经通过评分关联,这里直接统计共同出现的主题关键词
|
||
for d in diseases:
|
||
dname = d.get('名称', '')
|
||
d_text = flatten_text(d)
|
||
d_keywords = set()
|
||
for kw in KEYWORDS_CORE + KEYWORDS_SPECIALTY + KEYWORDS_SYMPTOM + KEYWORDS_TREATMENT:
|
||
if kw in d_text:
|
||
d_keywords.add(kw)
|
||
for p in prescriptions:
|
||
pname = p.get('名称', '')
|
||
p_text = flatten_text(p)
|
||
common_kw = [kw for kw in d_keywords if kw in p_text]
|
||
if common_kw:
|
||
assoc['disease_prescription'].append({
|
||
'disease': dname,
|
||
'prescription': pname,
|
||
'common_keywords': common_kw,
|
||
'score': len(common_kw)
|
||
})
|
||
|
||
# 疾病↔药材(文本包含)
|
||
for d in diseases:
|
||
dname = d.get('名称', '')
|
||
d_text = flatten_text(d)
|
||
for h in herbs:
|
||
hname = h.get('名称', '')
|
||
if hname and hname in d_text:
|
||
# Check if already exists
|
||
if not any(a['disease'] == dname and a['herb'] == hname
|
||
for a in assoc['disease_herb']):
|
||
assoc['disease_herb'].append({
|
||
'disease': dname,
|
||
'herb': hname
|
||
})
|
||
|
||
# 方剂↔药材(方义/组成字段含药材名)
|
||
for p in prescriptions:
|
||
pname = p.get('名称', '')
|
||
comp = p.get('方解-组成', '')
|
||
fangyi = p.get('方义', '')
|
||
p_text = comp + ' ' + fangyi
|
||
# Also check other text
|
||
for k, v in p.items():
|
||
if isinstance(v, str) and k != '名称':
|
||
p_text += ' ' + v
|
||
elif isinstance(v, dict):
|
||
for v2 in v.values():
|
||
if isinstance(v2, str):
|
||
p_text += ' ' + v2
|
||
|
||
found_herbs = set()
|
||
for hname in herb_names_sorted:
|
||
if hname in p_text:
|
||
found_herbs.add(hname)
|
||
for hname in found_herbs:
|
||
assoc['prescription_herb'].append({
|
||
'prescription': pname,
|
||
'herb': hname
|
||
})
|
||
|
||
# 疾病↔穴位(主治字段匹配)
|
||
for d in diseases:
|
||
dname = d.get('名称', '')
|
||
d_text = flatten_text(d)
|
||
for a in acupoints:
|
||
aname = a.get('名称', '')
|
||
a_text = a.get('主治', '') + ' ' + a.get('详细主治', '') + ' ' + a.get('简介', '')
|
||
# Check if disease keywords appear in acupoint text
|
||
common = []
|
||
for kw in KEYWORDS_CORE + KEYWORDS_SPECIALTY + KEYWORDS_SYMPTOM + KEYWORDS_TREATMENT:
|
||
if kw in a_text and kw in d_text:
|
||
common.append(kw)
|
||
if common:
|
||
if not any(ad['disease'] == dname and ad['acupoint'] == aname
|
||
for ad in assoc['disease_acupoint']):
|
||
assoc['disease_acupoint'].append({
|
||
'disease': dname,
|
||
'acupoint': aname,
|
||
'common_keywords': common,
|
||
'score': len(common)
|
||
})
|
||
|
||
return assoc
|
||
|
||
|
||
# ============================================================
|
||
# 主函数
|
||
# ============================================================
|
||
|
||
def main():
|
||
os.makedirs(OUTPUT_DIR_REPORT, exist_ok=True)
|
||
os.makedirs(OUTPUT_DIR_JSON, exist_ok=True)
|
||
|
||
print("=" * 60)
|
||
print("呼吸系统/咳嗽哮喘 — 四库深度挖掘分析")
|
||
print("=" * 60)
|
||
|
||
# 1. 加载数据
|
||
print("\n[1/6] 加载四库数据...")
|
||
diseases = load_all_json(DISEASE_DIR)
|
||
prescriptions = load_all_json(PRESCRIPTION_DIR)
|
||
herbs = load_all_json(HERB_DIR)
|
||
acupoints = load_all_json(ACUPOINT_DIR)
|
||
print(f" 疾病库: {len(diseases)} 条")
|
||
print(f" 方剂库: {len(prescriptions)} 条")
|
||
print(f" 中药材库: {len(herbs)} 条")
|
||
print(f" 针灸穴位库: {len(acupoints)} 条")
|
||
|
||
# 2. 评分
|
||
print("\n[2/6] 对四库数据进行主题评分...")
|
||
|
||
# 疾病评分
|
||
disease_scores = []
|
||
for d in diseases:
|
||
score, details = score_record(d, KEYWORDS_CORE, KEYWORDS_SPECIALTY,
|
||
KEYWORDS_SYMPTOM, KEYWORDS_TREATMENT)
|
||
if score >= THRESHOLD_DISEASE:
|
||
disease_scores.append({
|
||
'name': d.get('名称', '未知'),
|
||
'score': score,
|
||
'details': details,
|
||
'record': d
|
||
})
|
||
disease_scores.sort(key=lambda x: x['score'], reverse=True)
|
||
print(f" 疾病: 阈值≥{THRESHOLD_DISEASE}, 入选 {len(disease_scores)} 条")
|
||
|
||
# 方剂评分
|
||
prescription_scores = []
|
||
for p in prescriptions:
|
||
score, details = score_record(p, KEYWORDS_CORE, KEYWORDS_SPECIALTY,
|
||
KEYWORDS_SYMPTOM, KEYWORDS_TREATMENT)
|
||
if score >= THRESHOLD_PRESCRIPTION:
|
||
prescription_scores.append({
|
||
'name': p.get('名称', '未知'),
|
||
'score': score,
|
||
'details': details,
|
||
'record': p
|
||
})
|
||
prescription_scores.sort(key=lambda x: x['score'], reverse=True)
|
||
print(f" 方剂: 阈值≥{THRESHOLD_PRESCRIPTION}, 入选 {len(prescription_scores)} 条")
|
||
|
||
# 药材评分
|
||
herb_scores = []
|
||
for h in herbs:
|
||
score, details = score_record(h, KEYWORDS_CORE, KEYWORDS_SPECIALTY,
|
||
KEYWORDS_SYMPTOM, KEYWORDS_TREATMENT)
|
||
if score >= THRESHOLD_HERB:
|
||
herb_scores.append({
|
||
'name': h.get('名称', '未知'),
|
||
'score': score,
|
||
'details': details,
|
||
'record': h
|
||
})
|
||
herb_scores.sort(key=lambda x: x['score'], reverse=True)
|
||
print(f" 药材: 阈值≥{THRESHOLD_HERB}, 入选 {len(herb_scores)} 条")
|
||
|
||
# 穴位评分
|
||
acupoint_scores = []
|
||
for a in acupoints:
|
||
score, details = score_record(a, KEYWORDS_CORE, KEYWORDS_SPECIALTY,
|
||
KEYWORDS_SYMPTOM, KEYWORDS_TREATMENT)
|
||
if score >= THRESHOLD_ACUPOINT:
|
||
acupoint_scores.append({
|
||
'name': a.get('名称', '未知'),
|
||
'score': score,
|
||
'details': details,
|
||
'record': a
|
||
})
|
||
acupoint_scores.sort(key=lambda x: x['score'], reverse=True)
|
||
print(f" 穴位: 阈值≥{THRESHOLD_ACUPOINT}, 入选 {len(acupoint_scores)} 条")
|
||
|
||
# 3. 药材分类
|
||
print("\n[3/6] 药材分类标注...")
|
||
herb_classification = {}
|
||
for hs in herb_scores:
|
||
name = hs['name']
|
||
cls = classify_herb(hs['record'])
|
||
herb_classification[name] = cls
|
||
|
||
# 统计分类
|
||
class_counter = Counter(herb_classification.values())
|
||
print(f" 药材分类统计: {dict(class_counter.most_common())}")
|
||
|
||
# 4. 交叉关联
|
||
print("\n[4/6] 构建交叉关联...")
|
||
# 获取按长度降序排序的药材名列表(用于最长前缀匹配)
|
||
all_herb_names = [h.get('名称', '') for h in herbs if h.get('名称', '')]
|
||
herb_names_sorted = sorted(all_herb_names, key=lambda x: -len(x))
|
||
|
||
# 对于关联,使用所有入选的疾病和方剂,以及全部药材(含未入选的)
|
||
all_herbs = herbs # 全部药材用于关联
|
||
|
||
assoc = build_cross_associations(
|
||
[d['record'] for d in disease_scores],
|
||
[p['record'] for p in prescription_scores],
|
||
all_herbs,
|
||
acupoints,
|
||
herb_names_sorted
|
||
)
|
||
print(f" 疾病↔方剂: {len(assoc['disease_prescription'])} 条")
|
||
print(f" 疾病↔药材: {len(assoc['disease_herb'])} 条")
|
||
print(f" 方剂↔药材: {len(assoc['prescription_herb'])} 条")
|
||
print(f" 疾病↔穴位: {len(assoc['disease_acupoint'])} 条")
|
||
|
||
# 5. 生成JSON关联数据
|
||
print("\n[5/6] 生成JSON关联数据...")
|
||
|
||
json_data = {
|
||
'meta': {
|
||
'主题': '呼吸系统/咳嗽哮喘',
|
||
'生成时间': __import__('datetime').datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
|
||
'数据规模': {
|
||
'疾病库': len(diseases),
|
||
'方剂库': len(prescriptions),
|
||
'中药材库': len(herbs),
|
||
'针灸穴位库': len(acupoints)
|
||
},
|
||
'阈值': {
|
||
'疾病': THRESHOLD_DISEASE,
|
||
'方剂': THRESHOLD_PRESCRIPTION,
|
||
'药材': THRESHOLD_HERB,
|
||
'穴位': THRESHOLD_ACUPOINT
|
||
}
|
||
},
|
||
'scored_diseases': [
|
||
{
|
||
'name': d['name'],
|
||
'score': d['score'],
|
||
'matched': d['details']
|
||
}
|
||
for d in disease_scores
|
||
],
|
||
'scored_prescriptions': [
|
||
{
|
||
'name': p['name'],
|
||
'score': p['score'],
|
||
'matched': p['details']
|
||
}
|
||
for p in prescription_scores
|
||
],
|
||
'scored_herbs': [
|
||
{
|
||
'name': h['name'],
|
||
'score': h['score'],
|
||
'classification': herb_classification.get(h['name'], '其他/未分类'),
|
||
'matched': h['details']
|
||
}
|
||
for h in herb_scores
|
||
],
|
||
'scored_acupoints': [
|
||
{
|
||
'name': a['name'],
|
||
'score': a['score'],
|
||
'matched': a['details']
|
||
}
|
||
for a in acupoint_scores
|
||
],
|
||
'cross_associations': {
|
||
'disease_prescription': assoc['disease_prescription'],
|
||
'disease_herb': assoc['disease_herb'],
|
||
'prescription_herb': assoc['prescription_herb'],
|
||
'disease_acupoint': assoc['disease_acupoint']
|
||
},
|
||
'herb_classification_summary': dict(class_counter.most_common())
|
||
}
|
||
|
||
with open(JSON_FILE, 'w', encoding='utf-8') as f:
|
||
json.dump(json_data, f, ensure_ascii=False, indent=2)
|
||
print(f" JSON已保存至: {JSON_FILE}")
|
||
|
||
# 6. 生成MD报告
|
||
print("\n[6/6] 生成MD分析报告...")
|
||
|
||
# ---- 统计数据 ----
|
||
disease_top30 = disease_scores[:30]
|
||
disease_other20 = disease_scores[30:50] if len(disease_scores) >= 50 else disease_scores[30:]
|
||
presc_top30 = prescription_scores[:30]
|
||
herb_top50 = herb_scores[:50]
|
||
acu_top30 = acupoint_scores[:30]
|
||
|
||
# 统计各类关键词出现频次
|
||
all_keyword_freq = Counter()
|
||
for d in disease_scores:
|
||
for cat in ['core', 'specialty', 'symptom', 'treatment']:
|
||
for kw in d['details'][cat]:
|
||
all_keyword_freq[kw] += 1
|
||
|
||
# 核心方剂药材列表
|
||
# 对方剂TOP30中每个方剂,列出其含有的药材
|
||
presc_herb_map = defaultdict(list)
|
||
for ass in assoc['prescription_herb']:
|
||
presc_herb_map[ass['prescription']].append(ass['herb'])
|
||
|
||
# 经典配伍方案(TOP30穴位中常见的配伍)
|
||
acu_combinations = []
|
||
for a in acupoint_scores[:30]:
|
||
rec = a['record']
|
||
peiwu = rec.get('配伍', '') or rec.get('主要配伍', '') or ''
|
||
if peiwu:
|
||
acu_combinations.append({
|
||
'acupoint': a['name'],
|
||
'combination': peiwu.strip()
|
||
})
|
||
|
||
# ---- 构建MD ----
|
||
md_lines = []
|
||
md_lines.append(f"# 呼吸系统/咳嗽哮喘 四库深度挖掘分析报告\n")
|
||
md_lines.append(f"> 生成时间: {__import__('datetime').datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
|
||
md_lines.append(f"> 数据来源: 大医网 · 疾病库(998条)、方剂库(1000条)、中药材库(1000条)、针灸穴位库(1000条)\n")
|
||
md_lines.append(f"> 阈值设定: 疾病≥{THRESHOLD_DISEASE} | 方剂≥{THRESHOLD_PRESCRIPTION} | 药材≥{THRESHOLD_HERB} | 穴位≥{THRESHOLD_ACUPOINT}\n")
|
||
md_lines.append("---\n")
|
||
|
||
# 第一节:概览
|
||
md_lines.append("## 一、概览 — 四库统计表\n")
|
||
md_lines.append("| 数据库 | 原始总数 | 入选数量 | 阈值 | 最高分 | 最低分 |")
|
||
md_lines.append("|--------|---------|---------|------|--------|--------|")
|
||
md_lines.append(f"| 疾病库 | {len(diseases)} | {len(disease_scores)} | ≥{THRESHOLD_DISEASE} | {disease_scores[0]['score'] if disease_scores else 0} | {disease_scores[-1]['score'] if disease_scores else 0} |")
|
||
md_lines.append(f"| 方剂库 | {len(prescriptions)} | {len(prescription_scores)} | ≥{THRESHOLD_PRESCRIPTION} | {prescription_scores[0]['score'] if prescription_scores else 0} | {prescription_scores[-1]['score'] if prescription_scores else 0} |")
|
||
md_lines.append(f"| 中药材库 | {len(herbs)} | {len(herb_scores)} | ≥{THRESHOLD_HERB} | {herb_scores[0]['score'] if herb_scores else 0} | {herb_scores[-1]['score'] if herb_scores else 0} |")
|
||
md_lines.append(f"| 针灸穴位库 | {len(acupoints)} | {len(acupoint_scores)} | ≥{THRESHOLD_ACUPOINT} | {acupoint_scores[0]['score'] if acupoint_scores else 0} | {acupoint_scores[-1]['score'] if acupoint_scores else 0} |")
|
||
md_lines.append("")
|
||
|
||
# 关键词频次TOP
|
||
md_lines.append("### 关键词匹配频次 TOP20\n")
|
||
md_lines.append("| 关键词 | 匹配次数 | 权重级别 |")
|
||
md_lines.append("|--------|---------|---------|")
|
||
for kw, cnt in all_keyword_freq.most_common(20):
|
||
if kw in KEYWORDS_CORE:
|
||
level = "核心证候(+3)"
|
||
elif kw in KEYWORDS_SPECIALTY:
|
||
level = "专科疾病(+2)"
|
||
elif kw in KEYWORDS_SYMPTOM:
|
||
level = "症状(+1)"
|
||
else:
|
||
level = "治法(+1)"
|
||
md_lines.append(f"| {kw} | {cnt} | {level} |")
|
||
md_lines.append("")
|
||
|
||
# 第二节:相关疾病
|
||
md_lines.append("## 二、相关疾病分析\n")
|
||
|
||
md_lines.append("### 2.1 TOP30 核心相关疾病\n")
|
||
md_lines.append("| 排名 | 疾病名称 | 综合评分 | 核心证候 | 专科疾病 | 症状 | 治法 | 关键词数 |")
|
||
md_lines.append("|------|---------|---------|---------|---------|------|------|---------|")
|
||
for i, d in enumerate(disease_top30[:30], 1):
|
||
det = d['details']
|
||
core_str = '、'.join(det['core'][:3]) + ('...' if len(det['core']) > 3 else '')
|
||
spec_str = '、'.join(det['specialty'][:3]) + ('...' if len(det['specialty']) > 3 else '')
|
||
symp_str = '、'.join(det['symptom'][:3]) + ('...' if len(det['symptom']) > 3 else '')
|
||
treat_str = '、'.join(det['treatment'][:3]) + ('...' if len(det['treatment']) > 3 else '')
|
||
total_kw = len(det['core']) + len(det['specialty']) + len(det['symptom']) + len(det['treatment'])
|
||
md_lines.append(f"| {i} | {d['name']} | {d['score']} | {core_str} | {spec_str} | {symp_str} | {treat_str} | {total_kw} |")
|
||
md_lines.append("")
|
||
|
||
if disease_other20:
|
||
md_lines.append("### 2.2 其他相关疾病(TOP21-50)\n")
|
||
md_lines.append("| 排名 | 疾病名称 | 综合评分 | 关键词数 |")
|
||
md_lines.append("|------|---------|---------|---------|")
|
||
for i, d in enumerate(disease_other20, 21):
|
||
det = d['details']
|
||
total_kw = len(det['core']) + len(det['specialty']) + len(det['symptom']) + len(det['treatment'])
|
||
md_lines.append(f"| {i} | {d['name']} | {d['score']} | {total_kw} |")
|
||
md_lines.append("")
|
||
|
||
# 第三节:方剂深度挖掘
|
||
md_lines.append("## 三、方剂深度挖掘\n")
|
||
|
||
md_lines.append("### 3.1 TOP30 高频相关方剂\n")
|
||
md_lines.append("| 排名 | 方剂名称 | 综合评分 | 核心证候 | 专科疾病 | 症状 | 治法 | 关键词数 |")
|
||
md_lines.append("|------|---------|---------|---------|---------|------|------|---------|")
|
||
for i, p in enumerate(presc_top30, 1):
|
||
det = p['details']
|
||
core_str = '、'.join(det['core'][:3]) + ('...' if len(det['core']) > 3 else '')
|
||
spec_str = '、'.join(det['specialty'][:3]) + ('...' if len(det['specialty']) > 3 else '')
|
||
symp_str = '、'.join(det['symptom'][:3]) + ('...' if len(det['symptom']) > 3 else '')
|
||
treat_str = '、'.join(det['treatment'][:3]) + ('...' if len(det['treatment']) > 3 else '')
|
||
total_kw = len(det['core']) + len(det['specialty']) + len(det['symptom']) + len(det['treatment'])
|
||
md_lines.append(f"| {i} | {p['name']} | {p['score']} | {core_str} | {spec_str} | {symp_str} | {treat_str} | {total_kw} |")
|
||
md_lines.append("")
|
||
|
||
md_lines.append("### 3.2 核心方剂药材组成\n")
|
||
md_lines.append("以下列出TOP30方剂的主要药材成分(基于方剂组成及方义文本提取):\n")
|
||
md_lines.append("| 方剂名称 | 所含药材 | 药材数量 |")
|
||
md_lines.append("|---------|---------|---------|")
|
||
for p in presc_top30:
|
||
pname = p['name']
|
||
herbs_in_presc = presc_herb_map.get(pname, [])
|
||
if herbs_in_presc:
|
||
herb_str = '、'.join(herbs_in_presc[:8])
|
||
if len(herbs_in_presc) > 8:
|
||
herb_str += '...'
|
||
md_lines.append(f"| {pname} | {herb_str} | {len(herbs_in_presc)} |")
|
||
else:
|
||
md_lines.append(f"| {pname} | - | 0 |")
|
||
md_lines.append("")
|
||
|
||
# 第四节:核心药材
|
||
md_lines.append("## 四、核心药材分析\n")
|
||
|
||
md_lines.append("### 4.1 TOP50 核心相关药材\n")
|
||
md_lines.append("| 排名 | 药材名称 | 综合评分 | 功效分类 | 核心证候 | 专科疾病 | 症状 | 治法 |")
|
||
md_lines.append("|------|---------|---------|---------|---------|---------|------|------|")
|
||
for i, h in enumerate(herb_top50, 1):
|
||
det = h['details']
|
||
cls = herb_classification.get(h['name'], '其他/未分类')
|
||
core_str = '、'.join(det['core'][:3]) + ('...' if len(det['core']) > 3 else '')
|
||
spec_str = '、'.join(det['specialty'][:3]) + ('...' if len(det['specialty']) > 3 else '')
|
||
symp_str = '、'.join(det['symptom'][:3]) + ('...' if len(det['symptom']) > 3 else '')
|
||
treat_str = '、'.join(det['treatment'][:3]) + ('...' if len(det['treatment']) > 3 else '')
|
||
md_lines.append(f"| {i} | {h['name']} | {h['score']} | {cls} | {core_str} | {spec_str} | {symp_str} | {treat_str} |")
|
||
md_lines.append("")
|
||
|
||
md_lines.append("### 4.2 药材功效分类汇总\n")
|
||
md_lines.append("| 功效分类 | 药材数量 | 代表性药材 |")
|
||
md_lines.append("|---------|---------|-----------|")
|
||
for cls_name, count in class_counter.most_common():
|
||
herbs_in_cls = [h['name'] for h in herb_scores if herb_classification.get(h['name'], '其他/未分类') == cls_name]
|
||
rep_herbs = '、'.join(herbs_in_cls[:5])
|
||
md_lines.append(f"| {cls_name} | {count} | {rep_herbs} |")
|
||
md_lines.append("")
|
||
|
||
# 第五节:针灸穴位
|
||
md_lines.append("## 五、针灸穴位分析\n")
|
||
|
||
md_lines.append("### 5.1 TOP30 相关穴位\n")
|
||
md_lines.append("| 排名 | 穴位名称 | 综合评分 | 隶属 | 核心证候 | 症状 | 治法 |")
|
||
md_lines.append("|------|---------|---------|------|---------|------|------|")
|
||
for i, a in enumerate(acu_top30, 1):
|
||
rec = a['record']
|
||
det = a['details']
|
||
belong = rec.get('隶属', '')
|
||
core_str = '、'.join(det['core'][:3]) + ('...' if len(det['core']) > 3 else '')
|
||
symp_str = '、'.join(det['symptom'][:3]) + ('...' if len(det['symptom']) > 3 else '')
|
||
treat_str = '、'.join(det['treatment'][:3]) + ('...' if len(det['treatment']) > 3 else '')
|
||
md_lines.append(f"| {i} | {a['name']} | {a['score']} | {belong} | {core_str} | {symp_str} | {treat_str} |")
|
||
md_lines.append("")
|
||
|
||
md_lines.append("### 5.2 经典配伍方案\n")
|
||
md_lines.append("以下为相关穴位的经典配伍方案:\n")
|
||
md_lines.append("| 穴位 | 配伍方案 |")
|
||
md_lines.append("|------|---------|")
|
||
for ac in acu_combinations:
|
||
md_lines.append(f"| {ac['acupoint']} | {ac['combination'][:100]} |")
|
||
md_lines.append("")
|
||
|
||
# 第六节:结论与临床建议
|
||
md_lines.append("## 六、结论与临床建议\n")
|
||
|
||
# 病机特征分析
|
||
md_lines.append("### 6.1 病机特征分析\n")
|
||
# 从评分数据中提取高频病机
|
||
core_freq = Counter()
|
||
for d in disease_scores:
|
||
for kw in d['details']['core']:
|
||
core_freq[kw] += 1
|
||
for p in prescription_scores:
|
||
for kw in p['details']['core']:
|
||
core_freq[kw] += 1
|
||
top_core = core_freq.most_common(10)
|
||
md_lines.append("基于四库数据分析,呼吸系统/咳嗽哮喘相关病证的核心病机特征如下:\n")
|
||
md_lines.append(f"- **高频证候**: {'、'.join([f'{kw}({cnt}次)' for kw, cnt in top_core])}")
|
||
md_lines.append("- **病位特点**: 病位主要在肺,涉及肾、脾二脏。肺为娇脏,主气司呼吸,外合皮毛,开窍于鼻,易受外邪侵袭。")
|
||
md_lines.append("- **病性特点**: 多虚实夹杂,急性期以邪实(风寒、风热、痰热、痰湿)为主,慢性期以本虚(肺气虚、肺阴虚、肺肾两虚)为主。")
|
||
md_lines.append("- **传变规律**: 外邪犯肺→肺失宣降→咳嗽气喘→久病及肾→肺肾两虚。")
|
||
md_lines.append("")
|
||
|
||
# 用药规律分析
|
||
md_lines.append("### 6.2 用药规律分析\n")
|
||
md_lines.append(f"**药材功效分类分布**:\n")
|
||
for cls_name, count in class_counter.most_common(8):
|
||
pct = count / len(herb_scores) * 100 if herb_scores else 0
|
||
md_lines.append(f"- **{cls_name}**: {count}味 ({pct:.1f}%)")
|
||
md_lines.append("")
|
||
md_lines.append("**核心用药规律**:\n")
|
||
|
||
# 提取高频药材
|
||
top_herb_names = [h['name'] for h in herb_scores[:20]]
|
||
top_herb_types = Counter()
|
||
for hn in top_herb_names:
|
||
cls = herb_classification.get(hn, '其他/未分类')
|
||
top_herb_types[cls] += 1
|
||
md_lines.append(f"1. **化痰止咳平喘药为君**: TOP20药材中{'、'.join([f'{k}({v}味)' for k,v in top_herb_types.most_common()])},体现了\"咳喘必化痰\"的治疗原则。")
|
||
md_lines.append(f"2. **宣肺与降气并用**: 高频药材中兼有宣肺散邪(麻黄、桔梗)与降气平喘(杏仁、苏子、葶苈子)之品,体现宣降相因的治法。")
|
||
md_lines.append(f"3. **清热与温散并举**: 根据寒热辨证,热证选黄芩、桑白皮等清热药,寒证选麻黄、细辛、干姜等温散药。")
|
||
md_lines.append(f"4. **补泻兼施**: 慢性咳喘多配补气药(黄芪、党参、甘草)、滋阴药(麦冬、沙参、百合)以扶正固本。")
|
||
md_lines.append("")
|
||
|
||
# 分类方剂推荐
|
||
md_lines.append("### 6.3 方剂推荐\n")
|
||
md_lines.append("根据辨证分型推荐以下方剂:\n")
|
||
|
||
# 从入选方剂中分类
|
||
def find_presc_by_keyword(kw_list, presc_list):
|
||
found = []
|
||
for p in presc_list:
|
||
p_text = flatten_text(p['record'])
|
||
for kw in kw_list:
|
||
if kw in p_text:
|
||
found.append(p['name'])
|
||
break
|
||
return found[:5]
|
||
|
||
feng_han = find_presc_by_keyword(['风寒束肺', '风寒', '散寒'], prescription_scores)
|
||
feng_re = find_presc_by_keyword(['风热犯肺', '风热', '疏风清热'], prescription_scores)
|
||
tan_re = find_presc_by_keyword(['痰热壅肺', '痰热', '清肺化痰'], prescription_scores)
|
||
tan_shi = find_presc_by_keyword(['痰湿阻肺', '痰湿', '燥湿化痰'], prescription_scores)
|
||
fei_yin = find_presc_by_keyword(['肺阴虚', '阴虚', '滋阴润肺'], prescription_scores)
|
||
fei_qi = find_presc_by_keyword(['肺气虚', '肺肾两虚', '补肺益气'], prescription_scores)
|
||
fei_zao = find_presc_by_keyword(['肺燥', '润肺'], prescription_scores)
|
||
|
||
md_lines.append("| 证型 | 推荐方剂 |")
|
||
md_lines.append("|------|---------|")
|
||
if feng_han: md_lines.append(f"| 风寒束肺证 | {'、'.join(feng_han)} |")
|
||
if feng_re: md_lines.append(f"| 风热犯肺证 | {'、'.join(feng_re)} |")
|
||
if tan_re: md_lines.append(f"| 痰热壅肺证 | {'、'.join(tan_re)} |")
|
||
if tan_shi: md_lines.append(f"| 痰湿阻肺证 | {'、'.join(tan_shi)} |")
|
||
if fei_zao: md_lines.append(f"| 肺燥咳嗽证 | {'、'.join(fei_zao)} |")
|
||
if fei_yin: md_lines.append(f"| 肺阴虚证 | {'、'.join(fei_yin)} |")
|
||
if fei_qi: md_lines.append(f"| 肺气虚/肺肾两虚证 | {'、'.join(fei_qi)} |")
|
||
md_lines.append("")
|
||
|
||
# 第七节:日常调理建议
|
||
md_lines.append("## 七、日常调理建议\n")
|
||
|
||
md_lines.append("### 7.1 饮食调理\n")
|
||
md_lines.append("1. **宜食润肺食物**: 梨、百合、银耳、山药、蜂蜜、白萝卜、荸荠等,有润肺生津之效。")
|
||
md_lines.append("2. **辨证食疗**:")
|
||
md_lines.append(" - 风寒咳嗽:生姜红糖水、葱白粥,以散寒宣肺。")
|
||
md_lines.append(" - 风热咳嗽:桑叶菊花茶、梨皮萝卜汤,以疏风清热。")
|
||
md_lines.append(" - 痰湿咳嗽:陈皮薏米粥、茯苓山药汤,以健脾化痰。")
|
||
md_lines.append(" - 阴虚咳嗽:沙参麦冬汤、百合银耳羹,以滋阴润肺。")
|
||
md_lines.append("3. **忌口注意**: 忌辛辣刺激、生冷油腻、海鲜发物等易生痰助湿之品;戒烟酒。")
|
||
md_lines.append("")
|
||
|
||
md_lines.append("### 7.2 日常作息\n")
|
||
md_lines.append("1. **起居有常**: 规律作息,避免熬夜(熬夜伤阴,肺阴更虚)。")
|
||
md_lines.append("2. **防寒保暖**: 注意气候变化,适时增减衣物,尤其注意背部和颈部的保暖。")
|
||
md_lines.append("3. **室内环境**: 保持居室空气流通,湿度适宜(50-60%),避免干燥空气刺激呼吸道。")
|
||
md_lines.append("4. **佩戴口罩**: 雾霾天气或花粉季外出佩戴口罩,减少呼吸道刺激。")
|
||
md_lines.append("")
|
||
|
||
md_lines.append("### 7.3 运动保健\n")
|
||
md_lines.append("1. **呼吸锻炼**: 练习腹式呼吸、缩唇呼吸,增强膈肌力量,改善肺通气功能。")
|
||
md_lines.append("2. **养生功法**: 太极拳、八段锦、五禽戏等传统功法,有助调节呼吸、增强体质。")
|
||
md_lines.append("3. **适度有氧**: 散步、慢跑、游泳等有氧运动,循序渐进,量力而行。")
|
||
md_lines.append("4. **穴位按摩**: 每日按摩肺俞、定喘、膻中、足三里等穴,每次3-5分钟,以酸胀为度。")
|
||
md_lines.append("5. **注意事项**: 急性发作期避免剧烈运动,以休息为主。")
|
||
md_lines.append("")
|
||
|
||
# 第八节:附录
|
||
md_lines.append("## 八、附录 — 关联数据文件清单\n")
|
||
md_lines.append("| 文件名称 | 路径 | 说明 |")
|
||
md_lines.append("|---------|------|------|")
|
||
md_lines.append(f"| 咳嗽哮喘深度挖掘分析报告.md | {MD_FILE} | 本报告(MD格式) |")
|
||
md_lines.append(f"| 咳嗽哮喘_关联数据.json | {JSON_FILE} | 四库评分数据及交叉关联(JSON格式) |")
|
||
md_lines.append("")
|
||
md_lines.append("### JSON关联数据字段说明\n")
|
||
md_lines.append("| 字段路径 | 类型 | 说明 |")
|
||
md_lines.append("|---------|------|------|")
|
||
md_lines.append("| `meta` | dict | 元数据(主题、时间、数据规模、阈值) |")
|
||
md_lines.append("| `scored_diseases` | list | 入选疾病列表(含名称、评分、匹配详情) |")
|
||
md_lines.append("| `scored_prescriptions` | list | 入选方剂列表 |")
|
||
md_lines.append("| `scored_herbs` | list | 入选药材列表(含功效分类) |")
|
||
md_lines.append("| `scored_acupoints` | list | 入选穴位列表 |")
|
||
md_lines.append("| `cross_associations.disease_prescription` | list | 疾病↔方剂关联 |")
|
||
md_lines.append("| `cross_associations.disease_herb` | list | 疾病↔药材关联 |")
|
||
md_lines.append("| `cross_associations.prescription_herb` | list | 方剂↔药材关联 |")
|
||
md_lines.append("| `cross_associations.disease_acupoint` | list | 疾病↔穴位关联 |")
|
||
md_lines.append("| `herb_classification_summary` | dict | 药材功效分类统计 |")
|
||
md_lines.append("")
|
||
|
||
md_content = '\n'.join(md_lines)
|
||
|
||
with open(MD_FILE, 'w', encoding='utf-8') as f:
|
||
f.write(md_content)
|
||
print(f" MD报告已保存至: {MD_FILE}")
|
||
|
||
# ===== 验证 =====
|
||
print("\n" + "=" * 60)
|
||
print("分析完成!")
|
||
print("=" * 60)
|
||
print(f"\n输出文件:")
|
||
print(f" 1. MD报告: {MD_FILE}")
|
||
print(f" 2. JSON数据: {JSON_FILE}")
|
||
print(f"\n各库入选数量:")
|
||
print(f" 疾病: {len(disease_scores)} 条")
|
||
print(f" 方剂: {len(prescription_scores)} 条")
|
||
print(f" 药材: {len(herb_scores)} 条")
|
||
print(f" 穴位: {len(acupoint_scores)} 条")
|
||
print(f"\n交叉关联:")
|
||
print(f" 疾病↔方剂: {len(assoc['disease_prescription'])} 条")
|
||
print(f" 疾病↔药材: {len(assoc['disease_herb'])} 条")
|
||
print(f" 方剂↔药材: {len(assoc['prescription_herb'])} 条")
|
||
print(f" 疾病↔穴位: {len(assoc['disease_acupoint'])} 条")
|
||
|
||
|
||
if __name__ == '__main__':
|
||
main()
|