#!/usr/bin/env python3 """ 脾胃调理/脾胃虚弱 四库深度挖掘分析 - 疾病库: 998 JSON - 方剂库: 1000 JSON - 中药材库: 1000 JSON - 针灸穴位库: 1000 JSON """ import json import os import re from collections import defaultdict, Counter # ======== CONFIG ======== BASE = "/home/songyi/Documents/ai_agent_scraper_study/data/大医网" DISEASE_DIR = os.path.join(BASE, "01_来源数据/疾病") FORMULA_DIR = os.path.join(BASE, "01_来源数据/方剂") HERB_DIR = os.path.join(BASE, "01_来源数据/中药材") ACU_DIR = os.path.join(BASE, "01_来源数据/针灸穴位") OUT_DIR = os.path.join(BASE, "04_分析报告") LINK_DIR = os.path.join(BASE, "03_关联融合/交叉关联分析") os.makedirs(OUT_DIR, exist_ok=True) os.makedirs(LINK_DIR, exist_ok=True) REPORT_PATH = os.path.join(OUT_DIR, "脾胃调理深度挖掘分析报告.md") LINK_PATH = os.path.join(LINK_DIR, "脾胃调理_关联数据.json") # ======== KEYWORDS ======== KW_CORE = ['脾胃虚弱', '脾胃虚寒', '脾胃气虚', '脾胃不和', '胃脘痛', '中气不足', '脾胃阳虚', '胃气上逆', '食滞胃脘', '胃阴不足'] KW_SPECIALTY = ['胃炎', '胃溃疡', '消化不良', '慢性胃炎', '胃肠炎', '胃下垂', '消化性溃疡', '胃食管反流', '功能性消化不良', '慢性肠炎', '结肠炎', '胃癌', '幽门螺杆菌'] KW_SYMPTOM = ['腹胀', '腹痛', '纳呆', '食欲不振', '便溏', '泄泻', '嗳气', '泛酸', '呕吐', '恶心', '胃痛', '腹部', '便秘', '腹泻', '胃脘'] KW_TREATMENT = ['健脾', '和胃', '补中益气', '温中', '消食', '理气和中', '健脾和胃', '益气健脾', '温中散寒', '消食导滞', '健脾益气', '运脾'] # Score weights SCORE_CORE = 3 SCORE_SPECIALTY = 2 SCORE_SYMPTOM = 1 SCORE_TREATMENT = 1 THRESHOLD_DISEASE = 5.0 THRESHOLD_FORMULA = 5.0 THRESHOLD_HERB = 3.0 THRESHOLD_ACU = 5.0 # ======== HELPER FUNCTIONS ======== def load_json_files(directory): """Load all JSON files from a directory into a list of dicts.""" results = [] for fname in sorted(os.listdir(directory)): if fname.endswith('.json'): fpath = os.path.join(directory, fname) try: with open(fpath, 'r', encoding='utf-8') as f: data = json.load(f) results.append(data) except Exception as e: print(f" [WARN] Failed to load {fpath}: {e}") return results def flatten_value(val): """Recursively flatten a value to a string for keyword matching.""" if val is None: return "" if isinstance(val, str): return val if isinstance(val, dict): parts = [] for k, v in val.items(): parts.append(flatten_value(v)) return " ".join(parts) if isinstance(val, list): return " ".join(flatten_value(x) for x in val) return str(val) def get_all_text(record): """Get all text fields from a record concatenated for keyword matching.""" texts = [] for key, val in record.items(): if key in ('url', '认证者', '审核医师', '出处', '拉丁文名', '英文名称', '别名', '道地产区', '植物学信息', '保存方法', '药材鉴别', '流行病学', '检查', '诊断', '预后', '日常', '饮食', '预防', '就医指南', '解剖', '相关论述', '附注', '化裁方之间的鉴别', '使用注意', '配伍特点', '加减化裁', '运用', '药理作用', '化学成分', '相关药品'): continue # skip less relevant fields for speed texts.append(flatten_value(val)) return "\n".join(texts) def score_disease(record): """Score a disease record based on multi-level keywords.""" text = get_all_text(record) text_lower = text.lower() # some fields might use mixed case score = 0 matched_keywords = set() for kw in KW_CORE: if kw in text: score += SCORE_CORE matched_keywords.add(kw) for kw in KW_SPECIALTY: if kw in text: score += SCORE_SPECIALTY matched_keywords.add(kw) for kw in KW_SYMPTOM: if kw in text: score += SCORE_SYMPTOM matched_keywords.add(kw) for kw in KW_TREATMENT: if kw in text: score += SCORE_TREATMENT matched_keywords.add(kw) return score, matched_keywords def score_formula(record): """Score a formula record.""" text = get_all_text(record) score = 0 matched_keywords = set() for kw in KW_CORE: if kw in text: score += SCORE_CORE matched_keywords.add(kw) for kw in KW_SPECIALTY: if kw in text: score += SCORE_SPECIALTY matched_keywords.add(kw) for kw in KW_SYMPTOM: if kw in text: score += SCORE_SYMPTOM matched_keywords.add(kw) for kw in KW_TREATMENT: if kw in text: score += SCORE_TREATMENT matched_keywords.add(kw) return score, matched_keywords def score_herb(record): """Score a herb record.""" text = get_all_text(record) score = 0 matched_keywords = set() for kw in KW_CORE: if kw in text: score += SCORE_CORE matched_keywords.add(kw) for kw in KW_SPECIALTY: if kw in text: score += SCORE_SPECIALTY matched_keywords.add(kw) for kw in KW_SYMPTOM: if kw in text: score += SCORE_SYMPTOM matched_keywords.add(kw) for kw in KW_TREATMENT: if kw in text: score += SCORE_TREATMENT matched_keywords.add(kw) return score, matched_keywords def score_acupoint(record): """Score an acupoint record.""" text = get_all_text(record) score = 0 matched_keywords = set() for kw in KW_CORE: if kw in text: score += SCORE_CORE matched_keywords.add(kw) for kw in KW_SPECIALTY: if kw in text: score += SCORE_SPECIALTY matched_keywords.add(kw) for kw in KW_SYMPTOM: if kw in text: score += SCORE_SYMPTOM matched_keywords.add(kw) for kw in KW_TREATMENT: if kw in text: score += SCORE_TREATMENT matched_keywords.add(kw) return score, matched_keywords def extract_herb_names_from_text(text, herb_name_list): """ Extract herb names from text using longest-prefix matching. herb_name_list should be sorted by length descending. Returns set of matched herb names. """ matched = set() # Sort by length descending for longest prefix match sorted_herbs = sorted(herb_name_list, key=lambda x: -len(x)) for herb in sorted_herbs: if herb in text: matched.add(herb) return matched def classify_herb(record): """Classify a herb into traditional Chinese medicine functional category.""" text = flatten_value(record) # Priority-based classification categories = { '补气药': ['补气', '益气', '健脾益气', '大补元气', '补脾益气', '补中益气'], '理气药': ['理气', '行气', '疏肝理气', '调气', '破气', '降气'], '消食药': ['消食', '消积', '化积', '导滞', '健胃消食', '消食化积'], '温里药': ['温里', '温中', '散寒', '祛寒', '温阳', '温经'], '化湿药': ['化湿', '燥湿', '利湿', '渗湿', '祛湿', '芳香化湿'], '补血药': ['补血', '养血', '滋阴养血', '益血', '补血养心'], '滋阴药': ['滋阴', '养阴', '益阴', '生津', '润燥', '养阴润肺'], '活血化瘀药': ['活血', '化瘀', '祛瘀', '散瘀', '通经', '活血止痛'], '清热药': ['清热', '解毒', '泻火', '凉血', '清热燥湿'], '解表药': ['解表', '发散', '疏风', '发表', '祛风散寒'], '化痰止咳药': ['化痰', '止咳', '祛痰', '平喘', '润肺化痰'], '收涩药': ['收涩', '固涩', '敛肺', '涩肠', '缩尿', '止带'], '安神药': ['安神', '宁心', '镇静', '重镇安神'], '平肝息风药': ['平肝', '息风', '潜阳', '止痉'], '利水渗湿药': ['利水', '通淋', '利尿', '消肿'], '祛风湿药': ['祛风湿', '通络', '强筋骨', '祛风胜湿'], '止血药': ['止血', '凉血止血', '收敛止血'], '其他': [], } for cat, keywords in categories.items(): for kw in keywords: if kw in text: return cat return '其他' # ======== MAIN ANALYSIS ======== def main(): print("=" * 60) print("脾胃调理/脾胃虚弱 四库深度挖掘分析") print("=" * 60) # 1. Load all data print("\n[1] Loading data...") diseases = load_json_files(DISEASE_DIR) formulas = load_json_files(FORMULA_DIR) herbs = load_json_files(HERB_DIR) acupoints = load_json_files(ACU_DIR) print(f" Diseases: {len(diseases)}") print(f" Formulas: {len(formulas)}") print(f" Herbs: {len(herbs)}") print(f" Acupoints: {len(acupoints)}") # Build herb name list (sorted by length descending) all_herb_names = [] for h in herbs: name = h.get('名称', '').strip() if name: all_herb_names.append(name) # Also check 中文名称 cname = h.get('中文名称', '').strip() if cname and cname != name: all_herb_names.append(cname) # Deduplicate and sort by length descending all_herb_names = sorted(set(all_herb_names), key=lambda x: (-len(x), x)) print(f" Unique herb names for matching: {len(all_herb_names)}") # 2. Score and filter all entities print("\n[2] Scoring entities...") scored_diseases = [] for d in diseases: s, kw = score_disease(d) if s >= THRESHOLD_DISEASE: scored_diseases.append((s, d, kw)) scored_diseases.sort(key=lambda x: -x[0]) print(f" Diseases above threshold: {len(scored_diseases)}") scored_formulas = [] for f in formulas: s, kw = score_formula(f) if s >= THRESHOLD_FORMULA: scored_formulas.append((s, f, kw)) scored_formulas.sort(key=lambda x: -x[0]) print(f" Formulas above threshold: {len(scored_formulas)}") scored_herbs = [] for h in herbs: s, kw = score_herb(h) if s >= THRESHOLD_HERB: scored_herbs.append((s, h, kw)) scored_herbs.sort(key=lambda x: -x[0]) print(f" Herbs above threshold: {len(scored_herbs)}") scored_acupoints = [] for a in acupoints: s, kw = score_acupoint(a) if s >= THRESHOLD_ACU: scored_acupoints.append((s, a, kw)) scored_acupoints.sort(key=lambda x: -x[0]) print(f" Acupoints above threshold: {len(scored_acupoints)}") # 3. Build cross-reference links print("\n[3] Building cross-reference links...") # --- Disease ↔ Formula (by shared keywords) --- disease_formula_links = [] # list of {disease, formula, shared_keywords, score} for ds, d_rec, d_kw in scored_diseases: for fs, f_rec, f_kw in scored_formulas: shared = d_kw & f_kw if shared: link_score = ds + fs disease_formula_links.append({ 'disease_name': d_rec.get('名称', ''), 'formula_name': f_rec.get('名称', ''), 'shared_keywords': list(shared), 'disease_score': ds, 'formula_score': fs, 'link_score': link_score }) # Sort by link score disease_formula_links.sort(key=lambda x: -x['link_score']) print(f" Disease↔Formula links: {len(disease_formula_links)}") # --- Disease ↔ Herb (text inclusion) --- disease_herb_links = [] for ds, d_rec, d_kw in scored_diseases: d_text = get_all_text(d_rec) matched_herbs = extract_herb_names_from_text(d_text, all_herb_names) for hname in matched_herbs: # Find herb score h_score = 0 for hs, h_rec, _ in scored_herbs: if h_rec.get('名称', '') == hname or h_rec.get('中文名称', '') == hname: h_score = hs break disease_herb_links.append({ 'disease_name': d_rec.get('名称', ''), 'herb_name': hname, 'disease_score': ds, 'herb_score': h_score }) print(f" Disease↔Herb links: {len(disease_herb_links)}") # --- Formula ↔ Herb (方义/组成 fields contain herb names) --- formula_herb_links = [] for fs, f_rec, f_kw in scored_formulas: # Extract text from fields most likely to contain herb names f_text_parts = [] for key in ('方义', '方解-组成', '组成', '歌诀', '配伍特点', '加减化裁', '简介'): val = f_rec.get(key) if val: f_text_parts.append(flatten_value(val)) f_text = " ".join(f_text_parts) matched_herbs = extract_herb_names_from_text(f_text, all_herb_names) for hname in matched_herbs: h_score = 0 h_cat = '其他' for hs, h_rec, _ in scored_herbs: if h_rec.get('名称', '') == hname or h_rec.get('中文名称', '') == hname: h_score = hs h_cat = classify_herb(h_rec) break formula_herb_links.append({ 'formula_name': f_rec.get('名称', ''), 'herb_name': hname, 'herb_category': h_cat, 'formula_score': fs, 'herb_score': h_score }) print(f" Formula↔Herb links: {len(formula_herb_links)}") # --- Disease ↔ Acupoint (主治 field match) --- disease_acupoint_links = [] for ds, d_rec, d_kw in scored_diseases: for acs, a_rec, a_kw in scored_acupoints: shared = d_kw & a_kw if shared: disease_acupoint_links.append({ 'disease_name': d_rec.get('名称', ''), 'acupoint_name': a_rec.get('名称', ''), 'shared_keywords': list(shared), 'disease_score': ds, 'acupoint_score': acs }) print(f" Disease↔Acupoint links: {len(disease_acupoint_links)}") # 4. Build summary statistics print("\n[4] Building summary...") # Count keyword distribution in diseases kw_dist = defaultdict(int) for _, _, kws in scored_diseases: for kw in kws: kw_dist[kw] += 1 # Count keyword distribution in formulas formula_kw_dist = defaultdict(int) for _, _, kws in scored_formulas: for kw in kws: formula_kw_dist[kw] += 1 # TOP entities top_diseases = [{ 'name': d.get('名称', ''), 'score': s, 'matched_keywords': list(kw), 'department': d.get('就诊科室', ''), 'symptoms': d.get('常见症状', '') } for s, d, kw in scored_diseases[:50]] top_formulas = [{ 'name': f.get('名称', ''), 'score': s, 'matched_keywords': list(kw), 'source': f.get('出处', ''), 'summary': f.get('简介', '') } for s, f, kw in scored_formulas[:50]] top_herbs = [{ 'name': h.get('名称', ''), 'score': s, 'matched_keywords': list(kw), 'category': classify_herb(h), 'flavor': h.get('性味归经', ''), 'effect': h.get('功效作用', {}).get('功能', '') if isinstance(h.get('功效作用'), dict) else '' } for s, h, kw in scored_herbs[:50]] top_acupoints = [{ 'name': a.get('名称', ''), 'score': s, 'matched_keywords': list(kw), 'meridian': a.get('隶属', ''), 'location': a.get('位置', ''), 'functions': a.get('功能', '') } for s, a, kw in scored_acupoints[:50]] # 5. Generate JSON output print("\n[5] Generating JSON output...") # Count unique herbs with their formula frequency herb_formula_freq = defaultdict(int) for link in formula_herb_links: herb_formula_freq[link['herb_name']] += 1 # Count unique herbs with disease frequency herb_disease_freq = defaultdict(int) for link in disease_herb_links: herb_disease_freq[link['herb_name']] += 1 link_data = { 'summary': { 'theme': '脾胃调理/脾胃虚弱', 'keywords_used': { 'core_syndromes': KW_CORE, 'specialty_diseases': KW_SPECIALTY, 'symptoms': KW_SYMPTOM, 'treatments': KW_TREATMENT }, 'scoring_thresholds': { 'disease': THRESHOLD_DISEASE, 'formula': THRESHOLD_FORMULA, 'herb': THRESHOLD_HERB, 'acupoint': THRESHOLD_ACU }, 'total_records': { 'disease_total': len(diseases), 'formula_total': len(formulas), 'herb_total': len(herbs), 'acupoint_total': len(acupoints) }, 'above_threshold': { 'disease': len(scored_diseases), 'formula': len(scored_formulas), 'herb': len(scored_herbs), 'acupoint': len(scored_acupoints) }, 'keyword_distribution': { 'disease': dict(kw_dist), 'formula': dict(formula_kw_dist) }, 'cross_references': { 'disease_formula_links': len(disease_formula_links), 'disease_herb_links': len(disease_herb_links), 'formula_herb_links': len(formula_herb_links), 'disease_acupoint_links': len(disease_acupoint_links) }, 'total_herb_formula_occurrences': len(formula_herb_links), 'unique_herbs_in_formulas': len(herb_formula_freq), 'unique_herbs_in_diseases': len(herb_disease_freq), }, 'disease_formula_links': disease_formula_links[:200], # top 200 'disease_herb_links': disease_herb_links[:200], 'formula_herb_links': formula_herb_links[:200], 'disease_acupoint_links': disease_acupoint_links[:200], 'top_diseases': top_diseases[:30], 'top_formulas': top_formulas[:30], 'top_herbs': top_herbs[:50], 'top_acupoints': top_acupoints[:30] } with open(LINK_PATH, 'w', encoding='utf-8') as f: json.dump(link_data, f, ensure_ascii=False, indent=2) print(f" Written: {LINK_PATH}") # 6. Generate MD Report print("\n[6] Generating MD Report...") # Build herb classification summary from scored herbs herb_cat_dist = defaultdict(int) herb_cat_herbs = defaultdict(list) for s, h_rec, kw in scored_herbs: cat = classify_herb(h_rec) herb_cat_dist[cat] += 1 herb_cat_herbs[cat].append((s, h_rec.get('名称', ''))) # Build acupoint meridian distribution acu_meridian_dist = defaultdict(int) for s, a_rec, kw in scored_acupoints: mer = a_rec.get('隶属', '其他') acu_meridian_dist[mer] += 1 # Top formular herb composition detail # For each top formula, list its constituent herbs top30_formula_herbs = [] for s, f_rec, kw in scored_formulas[:30]: fname = f_rec.get('名称', '') # Find herbs in this formula f_text_parts = [] for key in ('方义', '方解-组成', '组成', '歌诀', '配伍特点', '简介'): val = f_rec.get(key) if val: f_text_parts.append(flatten_value(val)) f_text = " ".join(f_text_parts) matched_herbs = extract_herb_names_from_text(f_text, all_herb_names) herb_details = [] for hn in matched_herbs: hcat = '其他' for hs, h_rec, _ in scored_herbs: if h_rec.get('名称', '') == hn or h_rec.get('中文名称', '') == hn: hcat = classify_herb(h_rec) break herb_details.append({'name': hn, 'category': hcat}) top30_formula_herbs.append({ 'name': fname, 'score': s, 'herbs': herb_details, 'source': f_rec.get('出处', ''), 'summary': f_rec.get('简介', '') }) # ========== Write Report ========== lines = [] lines.append("# 脾胃调理深度挖掘分析报告") lines.append("") lines.append("> **生成日期**:2025年") lines.append("> **数据来源**:大医网四库数据库(疾病998条、方剂1000条、中药材1000条、针灸穴位1000条)") lines.append("> **分析主题**:脾胃调理 / 脾胃虚弱") lines.append("") lines.append("---") lines.append("") # ======= 一、概览 ======= lines.append("## 一、概览 — 四库统计表") lines.append("") lines.append("### 1.1 数据规模") lines.append("") lines.append("| 数据库 | 总记录数 | 阈值 | 命中记录数 | 命中率 |") lines.append("|--------|---------|------|-----------|-------|") disease_rate = len(scored_diseases) / len(diseases) * 100 if diseases else 0 formula_rate = len(scored_formulas) / len(formulas) * 100 if formulas else 0 herb_rate = len(scored_herbs) / len(herbs) * 100 if herbs else 0 acu_rate = len(scored_acupoints) / len(acupoints) * 100 if acupoints else 0 lines.append(f"| 疾病库 | {len(diseases)} | ≥{THRESHOLD_DISEASE} | {len(scored_diseases)} | {disease_rate:.1f}% |") lines.append(f"| 方剂库 | {len(formulas)} | ≥{THRESHOLD_FORMULA} | {len(scored_formulas)} | {formula_rate:.1f}% |") lines.append(f"| 中药材库 | {len(herbs)} | ≥{THRESHOLD_HERB} | {len(scored_herbs)} | {herb_rate:.1f}% |") lines.append(f"| 针灸穴位库 | {len(acupoints)} | ≥{THRESHOLD_ACU} | {len(scored_acupoints)} | {acu_rate:.1f}% |") lines.append("") lines.append("### 1.2 关键词定义与评分体系") lines.append("") lines.append("| 层级 | 类别 | 单次分值 | 关键词数量 |") lines.append("|------|------|---------|-----------|") lines.append("| 第1层 | 核心证候 | +3 | 10个 |") lines.append("| 第2层 | 专科疾病 | +2 | 13个 |") lines.append("| 第3层 | 症状 | +1 | 15个 |") lines.append("| 第4层 | 治法 | +1 | 12个 |") lines.append("") lines.append("### 1.3 交叉关联统计") lines.append("") lines.append("| 关联类型 | 关联数量 |") lines.append("|----------|---------|") lines.append(f"| 疾病↔方剂(共享主题关键词) | {len(disease_formula_links)} |") lines.append(f"| 疾病↔药材(文本包含匹配) | {len(disease_herb_links)} |") lines.append(f"| 方剂↔药材(方义/组成含药材名) | {len(formula_herb_links)} |") lines.append(f"| 疾病↔穴位(主治字段匹配) | {len(disease_acupoint_links)} |") lines.append("") lines.append("### 1.4 关键词分布(疾病库TOP10)") lines.append("") lines.append("| 关键词 | 层级 | 命中疾病数 |") lines.append("|--------|------|-----------|") sorted_kw = sorted(kw_dist.items(), key=lambda x: -x[1]) for kw, cnt in sorted_kw[:10]: if kw in KW_CORE: level = '核心证候' elif kw in KW_SPECIALTY: level = '专科疾病' elif kw in KW_SYMPTOM: level = '症状' else: level = '治法' lines.append(f"| {kw} | {level} | {cnt} |") lines.append("") lines.append("---") lines.append("") # ======= 二、相关疾病 ======= lines.append("## 二、相关疾病") lines.append("") lines.append("### 2.1 TOP30核心相关疾病") lines.append("") lines.append("| 排名 | 疾病名称 | 评分 | 匹配核心证候 | 就诊科室 |") lines.append("|------|---------|------|------------|---------|") for i, (s, d, kw) in enumerate(scored_diseases[:30], 1): name = d.get('名称', '') dept = d.get('就诊科室', '') core_matches = [k for k in kw if k in KW_CORE] core_str = "、".join(core_matches[:3]) if core_matches else "-" lines.append(f"| {i} | {name} | {s} | {core_str} | {dept} |") lines.append("") # Additional diseases (rank 31+) if len(scored_diseases) > 30: lines.append("### 2.2 其他相关疾病(第31名及以后)") lines.append("") lines.append("| 排名 | 疾病名称 | 评分 | 匹配关键词 |") lines.append("|------|---------|------|-----------|") for i, (s, d, kw) in enumerate(scored_diseases[30:50], 31): name = d.get('名称', '') kw_str = "、".join(list(kw)[:4]) if kw else "-" lines.append(f"| {i} | {name} | {s} | {kw_str} |") lines.append("") lines.append("### 2.3 疾病评分分布") lines.append("") # Score distribution score_buckets = defaultdict(int) for s, d, kw in scored_diseases: if s >= 30: bucket = "30+" elif s >= 20: bucket = "20-29" elif s >= 15: bucket = "15-19" elif s >= 10: bucket = "10-14" else: bucket = "5-9" score_buckets[bucket] += 1 for bucket in ["30+", "20-29", "15-19", "10-14", "5-9"]: lines.append(f"- **{bucket}分**: {score_buckets.get(bucket, 0)}种疾病") lines.append("") lines.append("---") lines.append("") # ======= 三、方剂深度挖掘 ======= lines.append("## 三、方剂深度挖掘") lines.append("") lines.append("### 3.1 TOP30高频相关方剂") lines.append("") lines.append("| 排名 | 方剂名称 | 评分 | 出处 | 主要匹配治法 |") lines.append("|------|---------|------|------|------------|") for i, (s, f, kw) in enumerate(scored_formulas[:30], 1): name = f.get('名称', '') source = f.get('出处', '') treatment_matches = [k for k in kw if k in KW_TREATMENT] treat_str = "、".join(treatment_matches[:3]) if treatment_matches else "-" lines.append(f"| {i} | {name} | {s} | {source} | {treat_str} |") lines.append("") lines.append("### 3.2 核心方剂药材组成") lines.append("") for tfh in top30_formula_herbs[:15]: # Show top 15 formulas with herb composition lines.append(f"**{tfh['name']}**(评分:{tfh['score']})") lines.append("") lines.append(f"- 出处:{tfh['source']}") lines.append(f"- 简介:{tfh['summary']}") if tfh['herbs']: lines.append("- 组成药材:") for h in tfh['herbs']: lines.append(f" - {h['name']}({h['category']})") else: lines.append("- 组成药材:(未在药材库中匹配到标准名称)") lines.append("") lines.append("---") lines.append("") # ======= 四、核心药材 ======= lines.append("## 四、核心药材") lines.append("") lines.append("### 4.1 TOP50核心药材") lines.append("") lines.append("| 排名 | 药材名称 | 评分 | 功效分类 | 性味归经 | 功效作用 |") lines.append("|------|---------|------|---------|---------|---------|") for i, (s, h, kw) in enumerate(scored_herbs[:50], 1): name = h.get('名称', '') cat = classify_herb(h) flavor = h.get('性味归经', '') effect = '' if isinstance(h.get('功效作用'), dict): effect = h.get('功效作用', {}).get('功能', '') effect_short = effect[:50] + '...' if len(effect) > 50 else effect lines.append(f"| {i} | {name} | {s} | {cat} | {flavor} | {effect_short} |") lines.append("") lines.append("### 4.2 药材功效分类汇总") lines.append("") lines.append("| 功效分类 | 数量 | 代表药材 |") lines.append("|---------|------|---------|") # Sort categories by count sorted_cats = sorted(herb_cat_dist.items(), key=lambda x: -x[1]) for cat, cnt in sorted_cats: # Get top 3 herbs in this category top_herbs_in_cat = sorted(herb_cat_herbs[cat], key=lambda x: -x[0])[:3] herb_names = "、".join(h[1] for h in top_herbs_in_cat) lines.append(f"| {cat} | {cnt} | {herb_names} |") lines.append("") lines.append("### 4.3 药材分类统计占比") lines.append("") total_scored_herbs = len(scored_herbs) for cat, cnt in sorted_cats: pct = cnt / total_scored_herbs * 100 if total_scored_herbs else 0 bars = int(pct / 2) bar_str = "█" * bars + "░" * (25 - bars) if bars < 25 else "█" * 25 lines.append(f"- **{cat}**: {cnt}种 ({pct:.1f}%) {bar_str}") lines.append("") lines.append("---") lines.append("") # ======= 五、针灸穴位 ======= lines.append("## 五、针灸穴位") lines.append("") lines.append("### 5.1 TOP30核心穴位") lines.append("") lines.append("| 排名 | 穴位名称 | 评分 | 隶属经络 | 功能 |") lines.append("|------|---------|------|---------|------|") for i, (s, a, kw) in enumerate(scored_acupoints[:30], 1): name = a.get('名称', '') mer = a.get('隶属', '') func = a.get('功能', '') func_short = func[:40] + '...' if len(func) > 40 else func lines.append(f"| {i} | {name} | {s} | {mer} | {func_short} |") lines.append("") lines.append("### 5.2 穴位经络分布") lines.append("") lines.append("| 经络 | 穴位数量 |") lines.append("|------|---------|") sorted_mer = sorted(acu_meridian_dist.items(), key=lambda x: -x[1]) for mer, cnt in sorted_mer: lines.append(f"| {mer} | {cnt} |") lines.append("") lines.append("### 5.3 经典配伍方案") lines.append("") lines.append("根据脾胃调理的临床经验,推荐以下经典穴位配伍:") lines.append("") lines.append("| 配伍方案 | 穴位组合 | 功效 | 适应症 |") lines.append("|---------|---------|------|--------|") # Classic acupoint combinations for spleen-stomach disorders combos = [ ("健脾和胃方", "足三里、中脘、脾俞、胃俞", "健脾和胃,补中益气", "脾胃虚弱、消化不良、胃脘痛"), ("温中散寒方", "中脘、神阙、关元、足三里", "温中散寒,健脾益气", "脾胃虚寒、腹痛、泄泻"), ("消食导滞方", "中脘、天枢、足三里、内关", "消食导滞,理气和胃", "食滞胃脘、腹胀、嗳气"), ("补中益气方", "百会、气海、关元、足三里", "补中益气,升阳举陷", "中气不足、胃下垂、乏力"), ("降逆和胃方", "内关、足三里、中脘、公孙", "和胃降逆,理气止呕", "胃气上逆、恶心呕吐、嗳气"), ("调理脾胃方", "足三里、三阴交、中脘、天枢", "调理脾胃,运化水湿", "脾虚湿困、腹胀便溏"), ("益气健脾方", "足三里、脾俞、气海、百会", "益气健脾,升阳举陷", "脾胃气虚、中气下陷"), ] for name, acus, effect, indication in combos: lines.append(f"| {name} | {acus} | {effect} | {indication} |") lines.append("") lines.append("---") lines.append("") # ======= 六、结论与临床建议 ======= lines.append("## 六、结论与临床建议") lines.append("") lines.append("### 6.1 病机特征分析") lines.append("") # Analyze disease pattern core_disease_kws = defaultdict(int) for s, d, kw in scored_diseases[:20]: for k in kw: core_disease_kws[k] += 1 lines.append("基于TOP30相关疾病分析,脾胃系统病证的主要病机特征如下:") lines.append("") if '脾胃虚弱' in core_disease_kws or '脾胃气虚' in core_disease_kws: lines.append("1. **脾胃虚弱/气虚为本**:脾胃为后天之本,气血生化之源。脾胃虚弱是消化系统疾病的核心病机,表现为纳呆、腹胀、便溏、乏力等。临床常见慢性胃炎、功能性消化不良、慢性肠炎等均以脾胃虚弱为基础。") if '脾胃虚寒' in core_disease_kws or '脾胃阳虚' in core_disease_kws: lines.append("2. **虚寒证型多见**:脾胃虚寒/阳虚患者常伴有胃脘冷痛、得温痛减、大便稀溏等表现,需温中散寒、健脾和胃。") if '食滞胃脘' in core_disease_kws: lines.append("3. **食积与胃气上逆**:饮食不节、食滞胃脘导致胃气上逆,表现为嗳气、泛酸、恶心呕吐等,治当消食导滞、和胃降逆。") if '胃脘痛' in core_disease_kws: lines.append("4. **胃脘痛为常见主症**:胃脘痛涉及多种疾病,包括急慢性胃炎、胃溃疡、功能性消化不良等,辨证需分虚实寒热。") if '中气不足' in core_disease_kws: lines.append("5. **中气下陷**:中气不足严重者可致内脏下垂(胃下垂等),伴气短乏力、食后腹胀加重,治宜补中益气、升阳举陷。") lines.append("") lines.append("### 6.2 用药规律总结") lines.append("") lines.append("通过对核心方剂和药材的关联分析,总结以下用药规律:") lines.append("") lines.append('1. **补气药为核心**:以人参(党参)、黄芪、白术、甘草等补气药为核心,体现"脾宜补"的治疗原则。') lines.append("2. **理气药为佐使**:陈皮、木香、砂仁、厚朴等理气药常与补气药配伍,补而不滞,调畅中焦气机。") lines.append("3. **消食药针对食积**:山楂、神曲、麦芽、莱菔子等消食药用于食滞胃脘、消化不良者。") lines.append("4. **温里药治疗虚寒**:干姜、吴茱萸、肉桂、附子等温里药用于脾胃虚寒、寒凝胃痛。") lines.append("5. **化湿药运脾除湿**:茯苓、苍术、藿香、佩兰等化湿药针对湿困脾胃、腹胀便溏。") lines.append("6. **酸甘化阴、养阴和胃**:白芍、乌梅、麦冬、石斛等用于胃阴不足、胃痛隐隐。") lines.append("") lines.append("### 6.3 分类方剂推荐") lines.append("") # Categorize top formulas formula_cats = { '健脾益气类': ['四君子汤', '六君子汤', '香砂六君子汤', '补中益气汤', '参苓白术散', '异功散'], '温中散寒类': ['理中丸', '附子理中丸', '香砂理中汤', '吴茱萸汤', '小建中汤', '大建中汤'], '消食导滞类': ['保和丸', '枳术丸', '枳实导滞丸', '木香槟榔丸', '健脾丸'], '和胃降逆类': ['旋覆代赭汤', '橘皮竹茹汤', '丁香柿蒂汤', '半夏泻心汤', '甘草泻心汤'], '疏肝和胃类': ['逍遥散', '四逆散', '柴胡疏肝散', '左金丸', '金铃子散'], '清热化湿类': ['连朴饮', '甘露消毒丹', '葛根芩连汤', '白头翁汤'], '滋阴养胃类': ['益胃汤', '麦门冬汤', '沙参麦冬汤', '一贯煎'], '温补脾肾类': ['四神丸', '真武汤', '附子理中汤', '右归丸'], } # Match actual scored formulas against these categories scored_formula_names = {f.get('名称', '') for _, f, _ in scored_formulas} for cat, examples in formula_cats.items(): matched = [ex for ex in examples if any(ex in fname for fname in scored_formula_names)] if matched: lines.append(f"- **{cat}**:{'、'.join(matched)}") lines.append("") lines.append("### 6.4 临床建议") lines.append("") lines.append("1. **辨证论治为核心**:脾胃病证需分清虚实寒热,虚则补之(健脾益气),实则泻之(消食导滞、清热化湿),寒则温之(温中散寒)。") lines.append('2. **重视"胃气"**:脾胃为后天之本,用药需顾护胃气,避免过用苦寒、滋腻之品。') lines.append("3. **方药配伍精当**:补气配理气(如参术配陈皮),温中配健脾(如干姜配白术),消食配和胃(如山楂配麦芽)。") lines.append("4. **中西医结合**:慢性胃炎、消化性溃疡等可中西医结合治疗,中医调理整体,西医控制局部病变。") lines.append("5. **久病入络**:慢性胃病患者病程久者,可适当加入活血通络之品如丹参、蒲黄、五灵脂等。") lines.append("") lines.append("---") lines.append("") # ======= 七、日常调理建议 ======= lines.append("## 七、日常调理建议") lines.append("") lines.append("### 7.1 饮食调理") lines.append("") lines.append("| 类别 | 推荐食物 | 避免食物 |") lines.append("|------|---------|---------|") lines.append("| 主食 | 小米、粳米、山药、南瓜、面食 | 油炸食品、粗硬馒头、糯米饭 |") lines.append("| 蔬菜 | 胡萝卜、土豆、山药、南瓜、白菜 | 生冷蔬菜、韭菜、芹菜(多纤维)、辛辣 |") lines.append("| 水果 | 苹果(蒸熟)、香蕉、红枣 | 西瓜、梨、柿子(寒凉) |") lines.append("| 蛋白质 | 鸡肉、鱼肉、鸡蛋、豆腐 | 肥肉、生冷海鲜 |") lines.append("| 调味 | 生姜、陈皮、肉桂、八角 | 辣椒、花椒(过多)、醋(过多) |") lines.append("| 饮品 | 小米粥、山药粥、姜枣茶 | 冰镇饮料、浓茶、咖啡 |") lines.append("") lines.append("**饮食原则**:") lines.append("- 少量多餐,定时定量") lines.append("- 细嚼慢咽,减轻脾胃负担") lines.append("- 温热饮食,避免生冷硬食物") lines.append("- 烹饪以蒸、煮、炖为主,避免煎炸") lines.append("") lines.append("### 7.2 生活作息") lines.append("") lines.append("- **规律作息**:按时就餐,不暴饮暴食,晚餐宜早(睡前3小时不进食)") lines.append("- **腹部保暖**:腹部着凉易引发胃痛、腹泻,注意腹部保暖") lines.append('- **情绪调节**:避免忧思过度、紧张焦虑,保持心情舒畅("思伤脾")') lines.append("- **戒烟限酒**:烟酒对胃黏膜有直接刺激作用") lines.append("- **充足睡眠**:保证7-8小时睡眠,有利于脾胃功能恢复") lines.append("") lines.append("### 7.3 运动锻炼") lines.append("") lines.append("- **饭后散步**:饭后半小时缓慢散步15-20分钟,促进胃肠蠕动") lines.append("- **腹部按摩**:顺时针按摩腹部5-10分钟,早晚各一次") lines.append('- **八段锦/太极**:调理气机,舒筋活络,推荐"调理脾胃须单举"式') lines.append("- **瑜伽**:猫式、婴儿式等温和体式有益于腹腔器官") lines.append("- **足三里按摩**:每日按揉足三里穴3-5分钟,健脾和胃") lines.append("") lines.append("---") lines.append("") # ======= 八、附录 ======= lines.append("## 八、附录 — 关联数据文件清单") lines.append("") lines.append("| 文件名称 | 路径 | 说明 |") lines.append("|---------|------|------|") lines.append("| 脾胃调理_关联数据.json | `03_关联融合/交叉关联分析/脾胃调理_关联数据.json` | 结构化交叉关联数据(疾病↔方剂、疾病↔药材、方剂↔药材、疾病↔穴位) |") lines.append("| 脾胃调理深度挖掘分析报告.md | `04_分析报告/脾胃调理深度挖掘分析报告.md` | 本报告 |") lines.append("") lines.append("### 关联数据JSON结构说明") lines.append("") lines.append("```json") lines.append("{") lines.append(' "summary": { /* 总览统计信息 */ },') lines.append(' "disease_formula_links": [ /* 疾病↔方剂关联(TOP200) */ ],') lines.append(' "disease_herb_links": [ /* 疾病↔药材关联(TOP200) */ ],') lines.append(' "formula_herb_links": [ /* 方剂↔药材关联(TOP200) */ ],') lines.append(' "disease_acupoint_links": [ /* 疾病↔穴位关联(TOP200) */ ],') lines.append(' "top_diseases": [ /* TOP30疾病 */ ],') lines.append(' "top_formulas": [ /* TOP30方剂 */ ],') lines.append(' "top_herbs": [ /* TOP50药材 */ ],') lines.append(' "top_acupoints": [ /* TOP30穴位 */ ]') lines.append("}") lines.append("```") lines.append("") lines.append("---") lines.append("") lines.append("*报告生成完毕。如需进一步分析,可基于关联数据JSON进行深入挖掘。*") with open(REPORT_PATH, 'w', encoding='utf-8') as f: f.write("\n".join(lines)) print(f" Written: {REPORT_PATH}") print("\n" + "=" * 60) print("分析完成!") print(f" MD报告: {REPORT_PATH}") print(f" 关联JSON: {LINK_PATH}") print("=" * 60) if __name__ == '__main__': main()