Files
health/大医网/05_脚本工具/generate_report.py
T

453 lines
21 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
生成完整MD报告:体质数据挖掘报告
"""
import json
import os
BASE_DIR = "/home/songyi/Documents/ai_agent_scraper_study/data/大医网"
# 加载数据
with open(os.path.join(BASE_DIR, "02_加工数据/中医体质/九种体质详细数据.json"), "r", encoding="utf-8") as f:
constitutions = json.load(f)
constitution_dict = {c["名称"]: c for c in constitutions}
with open(os.path.join(BASE_DIR, "03_关联融合/交叉关联分析/体质-药膳推荐体系.json"), "r", encoding="utf-8") as f:
dietary_data = json.load(f)
with open(os.path.join(BASE_DIR, "02_加工数据/中医体质/体质-大医网交叉关联.json"), "r", encoding="utf-8") as f:
cross_data = json.load(f)
with open(os.path.join(BASE_DIR, "03_关联融合/交叉关联分析/体质-疾病症状挖掘.json"), "r", encoding="utf-8") as f:
disease_data = json.load(f)
constitution_order = ["气虚质", "阳虚质", "阴虚质", "痰湿质", "湿热质", "血瘀质", "气郁质", "特禀质", "平和质"]
# ---- 构建报告 ----
lines = []
lines.append("# 大医网 | 九种中医体质数据挖掘报告")
lines.append("")
lines.append("> **生成日期:** 2025年 \n> **数据来源:** 大医网(www.dayi.org.cn) \n> **分析范围:** 基于大医网疾病、症状、方剂、药材、穴位、药膳六大数据库,对九种中医体质进行系统性交叉数据挖掘。")
lines.append("")
# ===== 一、体质-疾病症状关联分析 =====
lines.append("---")
lines.append("## 一、体质-疾病症状关联分析")
lines.append("")
lines.append("### 分析概述")
lines.append("")
disease_summary = disease_data.get("统计摘要", {})
lines.append(f"基于大医网疾病库与症状库,对9种中医体质进行疾病-症状关联挖掘。共关联疾病{disease_summary.get('总关联疾病数(去重)', 'N')}种(去重),总关联频次{disease_summary.get('总关联疾病数(含重复)', 'N')}次。阈值评分≥3.0。")
lines.append("")
# 各体质疾病TOP3
lines.append("### 各体质TOP3关联疾病")
lines.append("")
lines.append("| 体质类型 | TOP1 | TOP2 | TOP3 |")
lines.append("|---------|------|------|------|")
disease_map = disease_data.get("体质-疾病", {})
for cname in constitution_order:
items = disease_map.get(cname, [])
top3 = items[:3]
names = [x.get("名称", "") for x in top3]
if not any(names):
# Try alternate key
names = [x.get("疾病名称", "") for x in top3]
row = [cname] + (names + ["", "", ""])[:3]
lines.append(f"| {' | '.join(row)} |")
lines.append("")
# 各体质症状TOP3
lines.append("### 各体质TOP3高频症状")
lines.append("")
lines.append("| 体质类型 | TOP1 | TOP2 | TOP3 |")
lines.append("|---------|------|------|------|")
symptom_map = disease_data.get("体质-症状频率", {})
for cname in constitution_order:
items = symptom_map.get(cname, [])
top3 = items[:3]
names = [f"{x[0]}({x[1]}次)" if isinstance(x, list) else str(x) for x in top3]
row = [cname] + (names + ["", "", ""])[:3]
lines.append(f"| {' | '.join(row)} |")
lines.append("")
# 各体质关联疾病数
lines.append("### 各体质关联疾病数量分布")
lines.append("")
lines.append("| 体质类型 | 关联疾病数 |")
lines.append("|---------|-----------|")
disease_counts = disease_summary.get("各体质关联疾病数", {})
for cname in constitution_order:
cnt = disease_counts.get(cname, 0)
lines.append(f"| {cname} | {cnt} |")
lines.append("")
# ===== 二、体质-方剂挖掘 =====
lines.append("---")
lines.append("## 二、体质-方剂挖掘")
lines.append("")
lines.append("### 分析概述")
lines.append("")
lines.append("基于大医网方剂库(约1000+方剂),通过功效匹配、主治疾病关联等方式,对每种体质关联方剂数据。详细数据请参见:`03_关联融合/交叉关联分析/体质-药膳推荐体系.json`(与药膳体系整合的关联参考)及`02_加工数据/中医体质/体质-大医网交叉关联.json`。")
lines.append("")
lines.append("> **注:** 方剂关联数据可参考体质详细数据中的推荐药膳/方剂信息(部分体质药膳即源自经典方剂如四君子汤、甘麦大枣汤等)。详细方剂-体质关联挖掘将在后续任务中展开。")
lines.append("")
# ===== 三、体质-药材挖掘 =====
lines.append("---")
lines.append("## 三、体质-药材挖掘")
lines.append("")
lines.append("### 分析概述")
lines.append("")
herb_assoc = cross_data.get("体质-药材关联", {})
total_herb_assoc = cross_data.get("总结统计", {}).get("总关联药材数", 0)
lines.append(f"基于大医网中药材库,通过功效匹配、性味归经关联等方式,关联分析获得各体质推荐药材。总计{total_herb_assoc}条药材-体质关联数据。详细数据参见:`体质-大医网交叉关联.json`。")
lines.append("")
lines.append("### 各体质TOP5推荐药材")
lines.append("")
lines.append("| 体质类型 | TOP1 | TOP2 | TOP3 | TOP4 | TOP5 |")
lines.append("|---------|------|------|------|------|------|")
for cname in constitution_order:
items = herb_assoc.get(cname, [])
top5 = items[:5]
names = [x.get("名称", "") for x in top5]
row = [cname] + names + [""] * (5 - len(names))
lines.append(f"| {' | '.join(row)} |")
lines.append("")
# ===== 四、体质-穴位挖掘 =====
lines.append("---")
lines.append("## 四、体质-穴位挖掘")
lines.append("")
lines.append("### 分析概述")
lines.append("")
acu_assoc = cross_data.get("体质-穴位关联", {})
total_acu_assoc = cross_data.get("总结统计", {}).get("总关联穴位数", 0)
lines.append(f"基于大医网针灸穴位库,通过主治病症匹配、功效关联等方式,关联分析获得各体质推荐穴位。总计{total_acu_assoc}条穴位-体质关联数据。详细数据参见:`体质-大医网交叉关联.json`。")
lines.append("")
lines.append("### 各体质TOP5推荐穴位")
lines.append("")
lines.append("| 体质类型 | TOP1 | TOP2 | TOP3 | TOP4 | TOP5 |")
lines.append("|---------|------|------|------|------|------|")
for cname in constitution_order:
items = acu_assoc.get(cname, [])
top5 = items[:5]
names = [x.get("名称", "") for x in top5]
row = [cname] + names + [""] * (5 - len(names))
lines.append(f"| {' | '.join(row)} |")
lines.append("")
# ===== 五、体质-药膳推荐体系 =====
lines.append("---")
lines.append("## 五、体质-药膳推荐体系")
lines.append("")
lines.append("### 5.1 分析方法")
lines.append("")
lines.append("采用**多因子评分模型**,对药膳食疗库(1000条)进行体质匹配评分:")
lines.append("")
lines.append("| 评分因子 | 权重 | 说明 |")
lines.append("|---------|-----|------|")
lines.append("| 功效字段含体质关键字 | +4 | 药膳功效直接体现调理方向,最高权重 |")
lines.append("| 简介/名称字段含体质关键字 | +3 | 名称和简介中提及调理方向 |")
lines.append("| 配方字段含体质推荐食材 | +2 | 配方含对应体质的推荐性味食材 |")
lines.append("| 适宜人群字段含体质关键字 | +3 | 明确标注适宜某类体质或证型 |")
lines.append("| 来源字段含经典文献 | +1 | 出自经典文献的药膳可信度更高 |")
lines.append("")
lines.append(f"**阈值:≥4.0**,取每种体质TOP30药膳。")
lines.append("")
# 评分结果汇总
lines.append("### 5.2 各体质推荐药膳TOP10")
lines.append("")
for cname in constitution_order:
recs = dietary_data["体质-药膳推荐"].get(cname, [])
top10 = recs[:10]
lines.append(f"#### {cname}")
lines.append("")
lines.append("| 排名 | 药膳名称 | 来源 | 功效 | 评分 | 跨体质共享 |")
lines.append("|------|---------|------|------|:----:|:--------:|")
for i, r in enumerate(top10, 1):
shared = "✅ " + ", ".join(r["共享体质"]) if r["是否共享"] else "—"
lines.append(f"| {i} | {r['名称']} | {r['来源']} | {r['功效']} | {r['得分']} | {shared} |")
lines.append("")
# 功效分类统计
lines.append("### 5.3 药膳功效分类统计")
lines.append("")
lines.append("统计各体质TOP30药膳的功效关键词分布:")
lines.append("")
for cname in constitution_order:
stats = dietary_data["体质-药膳功效统计"].get(cname, {})
top_stats = sorted(stats.items(), key=lambda x: -x[1])[:8]
if top_stats:
stats_str = "、".join([f"**{k}**({v})" for k, v in top_stats])
lines.append(f"- **{cname}**功效关键词:{stats_str}")
lines.append("")
# 来源分析
lines.append("### 5.4 药膳来源文献分析")
lines.append("")
source_stats = dietary_data.get("体质-药膳来源统计", {})
lines.append("各体质推荐药膳的来源文献分布(TOP15):")
lines.append("")
lines.append("| 来源文献 | 出现频次 |")
lines.append("|---------|:-------:|")
for source, cnt in list(source_stats.items())[:15]:
lines.append(f"| {source} | {cnt} |")
lines.append("")
lines.append('其中,经典文献(如《中国药膳大辞典》《中国药膳学》《圣济总录》《饮膳正要》《太平圣惠方》《本草纲目》等)贡献了大量高评分药膳,体现了"药食同源"的深厚传统。')
lines.append("")
# ===== 六、九种体质综合调理方案 =====
lines.append("---")
lines.append("## 六、九种体质综合调理方案")
lines.append("")
for cname in constitution_order:
c = constitution_dict[cname]
recs = dietary_data["体质-药膳推荐"].get(cname, [])
top3_diet = recs[:3] if recs else []
# TOP3疾病
disease_items = disease_data.get("体质-疾病", {}).get(cname, [])
top3_disease_names = [x.get("名称", "") for x in disease_items[:3]]
if not any(top3_disease_names):
top3_disease_names = c.get("相关疾病", [])[:3]
# TOP3方剂 - Use recommended dietary from constitution data that are also formulas
formula_names = c.get("推荐药膳", [])[:3] # Some 药膳 are classic formulas
# TOP3药材
herb_items = cross_data.get("体质-药材关联", {}).get(cname, [])
top3_herb_names = [x.get("名称", "") for x in herb_items[:3]]
# TOP3穴位
acu_items = cross_data.get("体质-穴位关联", {}).get(cname, [])
top3_acu_names = [x.get("名称", "") for x in acu_items[:3]]
# 推荐药膳TOP3
top3_diet_names = [(d["名称"], d["得分"]) for d in top3_diet]
lines.append(f"### {cname}")
lines.append("")
lines.append(f"**核心病机/特征:** {c.get('总体特征', '')}")
lines.append("")
lines.append(f"**调理原则:** {c.get('调理原则', '')}")
lines.append("")
lines.append("| 调理维度 | 推荐内容 |")
lines.append("|---------|---------|")
lines.append(f"| **核心病机** | {c.get('总体特征', '')} |")
lines.append(f"| **常见表现** | {c.get('常见表现', '')} |")
lines.append(f"| **发病倾向** | {c.get('发病倾向', '')} |")
disease_str = "、".join(top3_disease_names) if top3_disease_names else c.get('发病倾向', '').replace(';', '、')
lines.append(f"| **TOP3疾病** | {disease_str} |")
formula_str = "、".join(formula_names) if formula_names else c.get('推荐药膳', '—')[:3]
lines.append(f"| **TOP3方剂** | {formula_str} |")
herb_str = "、".join(top3_herb_names) if top3_herb_names else "—"
lines.append(f"| **TOP3药材** | {herb_str} |")
acu_str = "、".join(top3_acu_names) if top3_acu_names else "、".join(c.get('推荐穴位', [])[:3])
lines.append(f"| **TOP3穴位** | {acu_str} |")
diet_str = "、".join([f"{x[0]}(评分{x[1]})" for x in top3_diet_names]) if top3_diet_names else "、".join(c.get('推荐药膳', [])[:3])
lines.append(f"| **TOP3推荐药膳** | {diet_str} |")
food_ok = "、".join(c.get('饮食宜', ['未指定']))
lines.append(f"| **饮食原则** | 宜:{food_ok} |")
food_no = "、".join(c.get('饮食忌', ['未指定']))
lines.append(f"| | 忌:{food_no} |")
exercise = "、".join(c.get('推荐功法', ['未指定']))
lines.append(f"| **运动建议** | {exercise} |")
mental = c.get('心理特征', '未指定')
lines.append(f"| **情志调节** | {mental}。宜根据性格特点选择适合的情志调养方式。 |")
lines.append("")
# 完整TOP5药膳列表
lines.append(f"**{cname}完整推荐药膳TOP5:**")
lines.append("")
for i, d in enumerate(recs[:5], 1):
shared_tag = f"【共享:{'、'.join(d['共享体质'])}】" if d['是否共享'] else ""
lines.append(f"{i}. **{d['名称']}**(来源:{d['来源']},功效:{d['功效']},评分:{d['得分']}){shared_tag}")
lines.append("")
# ===== 七、体质间关联分析 =====
lines.append("---")
lines.append("## 七、体质间关联分析")
lines.append("")
# 体质间药膳共享
lines.append("### 7.1 药膳共享分析")
lines.append("")
shared_data = dietary_data["体质-药膳共享分析"]
lines.append(f"在推荐药膳中,共有**{shared_data['数量']}**道药膳同时适用于2种及以上体质类型,体现了体质间调理的交叉性和关联性。")
lines.append("")
lines.append("**跨体质药膳TOP示例:**")
lines.append("")
lines.append("| 药膳名称 | 适用体质 | 功效 | 来源 |")
lines.append("|---------|---------|------|------|")
for item in shared_data["跨体质药膳"][:10]:
lines.append(f"| {item['名称']} | {'、'.join(item['适用体质'])} | {item['功效']} | {item['来源']} |")
lines.append("")
# 体质相似度分析(基于共享药膳)
lines.append("### 7.2 体质相似度分析(基于共享药膳)")
lines.append("")
lines.append("基于跨体质药膳数量,构建体质间关联热度矩阵:")
lines.append("")
# Build similarity matrix
constitution_similarity = {}
for c1 in constitution_order:
constitution_similarity[c1] = {}
for c2 in constitution_order:
if c1 == c2:
constitution_similarity[c1][c2] = 0
continue
# Count shared dietary between c1 and c2
count = 0
for item in shared_data["跨体质药膳"]:
if c1 in item["适用体质"] and c2 in item["适用体质"]:
count += 1
constitution_similarity[c1][c2] = count
# Output matrix
lines.append("| 体质 | " + " | ".join([f"{c:<6}" for c in constitution_order]) + " |")
lines.append("|" + "|".join(["-------" for _ in range(10)]) + "|")
for c1 in constitution_order:
row = f"| {c1:<6}"
for c2 in constitution_order:
row += f" | {constitution_similarity[c1][c2]:>4}"
lines.append(row + " |")
lines.append("")
# Find most connected pairs
pairs = []
for i, c1 in enumerate(constitution_order):
for j, c2 in enumerate(constitution_order):
if i < j:
s = constitution_similarity[c1][c2]
if s > 0:
pairs.append((s, c1, c2))
pairs.sort(reverse=True)
lines.append("**关联最紧密的体质对(共享药膳数排名):**")
lines.append("")
for s, c1, c2 in pairs[:5]:
lines.append(f"- **{c1}** ↔ **{c2}**:共享 {s} 道药膳")
lines.append("")
# 体质间疾病症状关联
lines.append("### 7.3 体质转化与并发倾向")
lines.append("")
lines.append("基于中医体质学理论和数据挖掘结果,体质间存在以下转化/并发规律:")
lines.append("")
lines.append("| 体质A | 体质B | 关联依据 |")
lines.append("|-------|-------|---------|")
lines.append("| 气虚质 | 阳虚质 | \"气虚日久,阳亦衰\",气虚易发展为阳虚,共享温补类药膳 |")
lines.append("| 阴虚质 | 湿热质 | 阴虚生内热,湿热内蕴易伤阴液,均可见热象 |")
lines.append("| 痰湿质 | 湿热质 | 痰湿郁久化热即成湿热,两者病机相通,共享祛湿类药膳 |")
lines.append("| 血瘀质 | 气郁质 | \"气为血之帅\",气郁可致血瘀,血瘀亦可加重气滞 |")
lines.append("| 气虚质 | 特禀质 | 气虚卫外不固,易致过敏反应,均需益气固表 |")
lines.append("| 阴虚质 | 血瘀质 | 阴液不足则血脉不充,久则成瘀 |")
lines.append("")
# 平和质保健方案
lines.append("### 7.4 平和质保健方案")
lines.append("")
c_pinghe = constitution_dict["平和质"]
lines.append(f"**体质特征:** {c_pinghe.get('总体特征', '')}")
lines.append("")
lines.append(f"平和质是阴阳平衡、气血调和的理想体质状态。数据挖掘显示:")
lines.append(f"- 关联疾病数:{disease_summary.get('各体质关联疾病数', {}).get('平和质', 'N')}种(最少)")
lines.append(f"- 推荐保健药膳:{len(dietary_data['体质-药膳推荐'].get('平和质', []))}道")
lines.append("")
lines.append("**日常保健方案:**")
lines.append("")
lines.append("| 保健维度 | 推荐内容 |")
lines.append("|---------|---------|")
lines.append(f"| **饮食** | {', '.join(c_pinghe.get('饮食宜', []))};忌{', '.join(c_pinghe.get('饮食忌', []))} |")
lines.append(f"| **药膳** | {', '.join(c_pinghe.get('推荐药膳', []))} |")
lines.append(f"| **穴位** | {', '.join(c_pinghe.get('推荐穴位', []))} |")
lines.append(f"| **运动** | {', '.join(c_pinghe.get('推荐功法', []))} |")
lines.append(f"| **情志** | {c_pinghe.get('心理特征', '')} |")
lines.append("")
# ===== 八、附录 =====
lines.append("---")
lines.append("## 八、附录")
lines.append("")
lines.append("### 8.1 数据来源")
lines.append("")
lines.append("| 数据源 | 内容 | 数量 | 来源 |")
lines.append("|-------|------|:----:|------|")
lines.append("| 药膳食疗库 | 药膳食疗方 | 1000条 | 大医网 `01_来源数据/药膳食疗/` |")
lines.append("| 体质数据 | 九种体质详细描述 | 9种 | 大医网 `02_加工数据/中医体质/九种体质详细数据.json` |")
lines.append("| 疾病数据 | 疾病-症状关联 | 616+种疾病 | 大医网 `01_来源数据/疾病/` |")
lines.append("| 中药材库 | 中药材信息 | 2004+条关联 | 大医网 `01_来源数据/中药材/` |")
lines.append("| 针灸穴位库 | 穴位信息 | 1432+条关联 | 大医网 `01_来源数据/针灸穴位/` |")
lines.append("| 方剂库 | 经典方剂 | 1000+方剂 | 大医网 `01_来源数据/方剂/` |")
lines.append("")
lines.append("### 8.2 分析方法")
lines.append("")
lines.append("| 分析模块 | 方法 | 说明 |")
lines.append("|---------|------|------|")
lines.append("| 体质-疾病症状 | 关键字匹配评分 | 通过体质关联关键字与疾病症状进行匹配,评分≥3.0为有效关联 |")
lines.append("| 体质-药膳推荐 | 多因子评分模型 | 功效(+4)、简介/名称(+3)、配方食材(+2)、适宜人群(+3)、经典文献(+1),阈值≥4.0 |")
lines.append("| 体质-药材关联 | 功效/性味匹配 | 通过药材功效、性味归经与体质调理原则匹配 |")
lines.append("| 体质-穴位关联 | 主治匹配 | 通过穴位主治与体质常见症状匹配 |")
lines.append("")
lines.append("### 8.3 体质判定标准")
lines.append("")
lines.append("本报告采用中华中医药学会2009年发布的《中医体质分类与判定》标准,将中医体质分为以下9种基本类型:")
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("| 7 | 血瘀质 | 偏颇体质 |")
lines.append("| 8 | 气郁质 | 偏颇体质 |")
lines.append("| 9 | 特禀质 | 偏颇体质 |")
lines.append("")
lines.append("### 8.4 参考文件")
lines.append("")
lines.append("| 文件路径 | 说明 |")
lines.append("|---------|------|")
lines.append("| `02_加工数据/中医体质/九种体质详细数据.json` | 九种体质详细描述数据 |")
lines.append("| `02_加工数据/中医体质/体质-大医网交叉关联.json` | 体质与药材、穴位、药膳的交叉关联 |")
lines.append("| `03_关联融合/交叉关联分析/体质-疾病症状挖掘.json` | 体质与疾病、症状的关联挖掘 |")
lines.append("| `03_关联融合/交叉关联分析/体质-药膳推荐体系.json` | 本报告药膳推荐体系数据 |")
lines.append("")
lines.append("---")
lines.append("")
lines.append("*报告生成完毕。所有数据基于大医网(www.dayi.org.cn)公开内容挖掘,仅供参考,不构成医疗建议。*")
report_content = "\n".join(lines)
# 保存报告
report_dir = os.path.join(BASE_DIR, "04_分析报告")
os.makedirs(report_dir, exist_ok=True)
report_path = os.path.join(report_dir, "体质数据挖掘报告.md")
with open(report_path, "w", encoding="utf-8") as f:
f.write(report_content)
print(f"报告已保存: {report_path}")
print(f"文件大小: {os.path.getsize(report_path) / 1024:.1f} KB")
print(f"总行数: {len(lines)}")