synthEHRella 完整教學

Repository: https://github.com/chenxran/synthEHRella Stars: 18 | Language: Python | License: MIT Tags: EHR, benchmark, synthetic 論文: Chen X, Wu Z et al. (2025). Generating synthetic electronic health record data: a methodological scoping review with benchmarking on phenotype data and open-source software. JAMIA, 32(7), 1227-1240. 最後更新: 2026-04-09

2. 核心架構

2.1 四步驟 Pipeline

SynthEHRella 的核心設計是一條四步驟的標準化 pipeline,每個步驟都有獨立的 CLI 入口:


flowchart TD
    subgraph INPUT["輸入資料"]
        MIMIC3["MIMIC-III v1.4
ICD-9 診斷碼"] MIMIC4["MIMIC-IV v3.1
ICD-10 診斷碼"] end subgraph STEP1["Step 1: Preprocessing
run_preprocessing.py"] P1["讀取 ADMISSIONS.csv
DIAGNOSES_ICD.csv
PATIENTS.csv"] P2["建立 patient-admission mapping"] P3["建立 admission-diagnosis mapping"] P4["輸出 binary matrix
+ PhecodeX 編碼"] end subgraph STEP2["Step 2: Generation
run_generation.py"] G1["CorGAN / MedGAN / VAE"] G2["EHRDiff / PromptEHR"] G3["Synthea / Plasmode"] G4["Resample / PBR"] end subgraph STEP3["Step 3: Post-Processing
run_postprocessing.py"] PP1["ICD-9 → ICD-10 mapping"] PP2["ICD-10 → PhecodeX mapping"] PP3["PhecodeX → PhecodeXm
higher hierarchy"] end subgraph STEP4["Step 4: Evaluation
run_evaluation.py"] E1["Fidelity 保真度
prevalence / correlation / discriminative"] E2["Utility 效用
TRTR / TSTR / TSRTR"] E3["Privacy 隱私
MIA / AIA"] end MIMIC3 --> P1 MIMIC4 --> P1 P1 --> P2 --> P3 --> P4 P4 -->|"binary matrix"| STEP2 G1 & G2 & G3 & G4 -->|"synthetic .npy"| STEP3 PP1 --> PP2 --> PP3 PP3 -->|"phecodexm .npy"| STEP4 E1 & E2 & E3 -->|"JSON results"| RESULT["evaluation.json"] style INPUT fill:#e8f4fd,stroke:#1976d2 style STEP1 fill:#fff3e0,stroke:#f57c00 style STEP2 fill:#e8f5e9,stroke:#388e3c style STEP3 fill:#fce4ec,stroke:#c62828 style STEP4 fill:#f3e5f5,stroke:#7b1fa2

2.2 三維評估體系


flowchart LR
    subgraph FIDELITY["Fidelity 保真度"]
        F1["MMD
Max Mean Discrepancy"] F2["RMSPE
Root Mean Square
Percentage Error"] F3["MAPE
Mean Absolute
Percentage Error"] F4["Correlation Frobenius
相關矩陣距離"] F5["Co-appearance Frobenius
共現矩陣距離"] F6["Discriminative AUC
判別器 AUC"] F7["Discriminative Accuracy
判別器準確率"] end subgraph UTILITY["Utility 效用"] U1["TRTR
Train Real, Test Real
基線表現"] U2["TSTR
Train Synthetic, Test Real
合成替代真實"] U3["TSRTR
Train Syn+Real, Test Real
合成增強真實"] end subgraph PRIVACY["Privacy 隱私"] P1["MIA
Membership Inference Attack
成員推論攻擊"] P2["AIA
Attribute Inference Attack
屬性推論攻擊"] end style FIDELITY fill:#e3f2fd,stroke:#1565c0 style UTILITY fill:#e8f5e9,stroke:#2e7d32 style PRIVACY fill:#ffebee,stroke:#c62828

2.3 編碼轉換鏈

整個框架的核心技術決策是使用 PhecodeX 作為統一的比較座標系:

1ICD-9 (MIMIC-III) ──→ ICD-10 ──→ PhecodeX ──→ PhecodeXm (higher hierarchy)
23SNOMED-CT (Synthea) ──→ ICD-10 ──────┘

這確保了不同方法使用不同編碼系統 (ICD-9, SNOMED-CT) 產出的合成資料可以在同一個特徵空間裡比較。

2.4 專案檔案結構

 1synthEHRella/
 2├── environment.yaml              # Conda 環境定義 (Python 3.10 + CUDA 12.1)
 3├── setup.py                      # pip install 入口
 4├── example_commands/             # 範例 shell script
 5│   ├── run_preprocessing.sh
 6│   ├── run_generation.sh
 7│   ├── run_postprocessing.sh
 8│   ├── run_evaluation_mimic3.sh
 9│   └── run_evaluation_mimic4.sh
10└── synthEHRella/
11    ├── run_preprocessing.py      # Step 1 CLI
12    ├── run_generation.py         # Step 2 CLI (方法分派器)
13    ├── run_postprocessing.py     # Step 3 CLI
14    ├── run_evaluation.py         # Step 4 CLI
15    ├── data/
16    │   └── methods/              # 各方法的原始碼
17    │       ├── cor-gan/          # CorGAN + MedGAN + VAE
18    │       ├── EHRDiff/          # Score-based Diffusion
19    │       ├── PromptEHR/        # LLM-based 生成
20    │       ├── plasmode/         # R 統計方法
21    │       └── synthea/          # (需自行下載 .jar)
22    ├── evaluation/
23    │   ├── fidelity.py           # 保真度指標
24    │   ├── utility.py            # 效用指標 (TRTR/TSTR/TSRTR)
25    │   └── privacy.py            # 隱私攻擊 (MIA/AIA)
26    └── utils/
27        ├── data_transform.py     # 編碼轉換引擎
28        ├── ICD9toICD10Mapping.json
29        ├── icd10_to_phecodex_mapping.json
30        ├── phecodex_to_phecodexm_mapping.json
31        └── snomed2icd10.json

3. 安裝與設定

3.1 系統需求

項目需求
Python3.10+
GPUNVIDIA GPU + CUDA 12.1 (深度學習方法需要)
R4.2+ (僅 Plasmode 需要)
JavaOpenJDK 18+ (僅 Synthea 需要)
磁碟~10 GB (含 MIMIC 資料 + 模型 checkpoint)
RAM16 GB+ (建議 32 GB)

3.2 安裝步驟

 1# 1. 取得原始碼
 2git clone https://github.com/chenxran/synthEHRella.git
 3cd synthEHRella
 4
 5# 2. 建立 Conda 環境 (含 PyTorch + CUDA + scikit-learn + transformers 等)
 6conda env create -f environment.yaml
 7conda activate synthEHRella
 8
 9# 3. 安裝套件
10pip install .
11
12# 4. (選用) 下載 Synthea JAR
13# 從 https://github.com/synthetichealth/synthea/releases 下載 synthea-with-dependencies.jar
14# 放至 synthEHRella/synthEHRella/data/methods/synthea/

3.3 取得 MIMIC 資料

SynthEHRella 以 MIMIC-III/IV 作為真實 EHR (Real EHR) 基準。需先在 PhysioNet 取得授權存取:

取得後,將 CSV 檔案放至你的工作目錄。核心需要三個檔案:

  • ADMISSIONS.csv — 住院紀錄
  • DIAGNOSES_ICD.csv — 診斷碼
  • PATIENTS.csv — 病患人口學資料

3.4 環境核心依賴

environment.yaml 中的關鍵依賴:

依賴版本用途
torch2.3.1+cu121深度學習方法 (CorGAN, MedGAN, VAE, EHRDiff)
transformers4.19.0PromptEHR (BART 模型)
scikit-learn1.5.0評估指標 (Logistic Regression, Random Forest, KNN)
omegaconf2.1.1設定管理
icd-mappings0.4.0ICD 碼映射
xgboost2.1.1額外分類器
rdkit2023.9.6化學資訊工具 (原始依賴,非必要)

4. 使用方式與程式碼範例

4.1 範例一:完整 Pipeline — 從 MIMIC-III 到評估報告

這是最典型的使用場景:用 MIMIC-III 真實資料訓練多個方法,然後統一評估。

 1# ========================================
 2# Step 1: 前處理 MIMIC-III
 3# ========================================
 4MIMIC_III_ADMISSION="data/physionet.org/files/mimiciii/1.4/ADMISSIONS.csv"
 5MIMIC_III_DIAGNOSIS="data/physionet.org/files/mimiciii/1.4/DIAGNOSES_ICD.csv"
 6MIMIC_III_PATIENTS="data/physionet.org/files/mimiciii/1.4/PATIENTS.csv"
 7OUTPUT="testing_output/"
 8
 9python -m synthEHRella.run_preprocessing \
10    $MIMIC_III_ADMISSION \
11    $MIMIC_III_DIAGNOSIS \
12    $MIMIC_III_PATIENTS \
13    $OUTPUT binary mimic3
14
15# 輸出檔案:
16#   testing_output/processed_mimic3.matrix   ← binary matrix (訓練用)
17#   testing_output/processed_mimic3.pid      ← patient ID list
18#   testing_output/processed_mimic3.types    ← ICD-9 code → column index mapping
19#   testing_output/mimic3-real-phecodex.npy  ← PhecodeX 編碼 (視覺化用)
20#   testing_output/mimic3-real-phecodexm.npy ← PhecodeXm 編碼 (量化評估用)
21
22# ========================================
23# Step 2: 用 CorGAN 生成 50,000 筆合成資料
24# ========================================
25NUM_GEN_SAMPLES=50000
26mkdir -p testing_output/corgan
27
28python -m synthEHRella.run_generation \
29    corgan \
30    --real_training_data_path testing_output/processed_mimic3.matrix \
31    --ckpt_dir testing_output/corgan \
32    --num_gen_samples $NUM_GEN_SAMPLES \
33    --params "--n_epochs 1000"
34
35# 輸出:testing_output/corgan/synthetic-50000.npy
36
37# ========================================
38# Step 3: 後處理 — ICD-9 → PhecodeXm
39# ========================================
40python -m synthEHRella.run_postprocessing corgan \
41    --data_path testing_output/corgan/synthetic-50000.npy \
42    --output_path testing_output/postprocessed/corgan-synthetic-phecodexm.npy
43
44# ========================================
45# Step 4: 三維評估
46# ========================================
47python -m synthEHRella.run_evaluation corgan \
48    --synthetic_data_path testing_output/postprocessed/corgan-synthetic-phecodexm.npy \
49    --real_eval_data_path testing_output/mimic3-real-phecodexm.npy \
50    --output_dir testing_output/evaluation/corgan-mimic3-evaluation.json
51
52# 輸出 JSON 包含所有 Fidelity + Utility + Privacy 指標

4.2 範例二:批次比較所有方法

以下腳本示範如何用同一份 MIMIC-III 資料批次執行所有 9 種方法,最後集中比較。

 1#!/bin/bash
 2# batch_benchmark.sh — 批次基準測試
 3
 4NUM_GEN_SAMPLES=50000
 5REAL_DATA="testing_output/processed_mimic3.matrix"
 6REAL_EVAL="testing_output/mimic3-real-phecodexm.npy"
 7METHODS=("corgan" "medgan" "vae" "promptehr" "resample" "pbr")
 8
 9# 需要額外環境的方法另外處理:
10# - ehrdiff: 需要自己的訓練資料格式
11# - synthea: 需要 Java + synthea-with-dependencies.jar
12# - plasmode: 需要 R 4.2+
13
14for METHOD in "${METHODS[@]}"; do
15    echo "=== Processing $METHOD ==="
16    mkdir -p testing_output/$METHOD
17
18    # Step 2: 生成
19    python -m synthEHRella.run_generation \
20        $METHOD \
21        --real_training_data_path $REAL_DATA \
22        --ckpt_dir testing_output/$METHOD \
23        --num_gen_samples $NUM_GEN_SAMPLES
24
25    # Step 3: 後處理
26    # 不同方法的輸出路徑不同,需要對應調整
27    case $METHOD in
28        corgan|vae)
29            SYNTH_PATH="testing_output/$METHOD/synthetic-${NUM_GEN_SAMPLES}.npy" ;;
30        medgan)
31            SYNTH_PATH="testing_output/$METHOD/synthetic.npy" ;;
32        promptehr)
33            SYNTH_PATH="testing_output/$METHOD/promptehr-synthetic.npy" ;;
34        resample|pbr)
35            SYNTH_PATH="testing_output/$METHOD/${METHOD}-synthetic.npy" ;;
36    esac
37
38    python -m synthEHRella.run_postprocessing $METHOD \
39        --data_path $SYNTH_PATH \
40        --output_path testing_output/postprocessed/${METHOD}-synthetic-phecodexm.npy
41
42    # Step 4: 評估
43    python -m synthEHRella.run_evaluation $METHOD \
44        --synthetic_data_path testing_output/postprocessed/${METHOD}-synthetic-phecodexm.npy \
45        --real_eval_data_path $REAL_EVAL \
46        --output_dir testing_output/evaluation/${METHOD}-mimic3-evaluation.json
47done
48
49echo "=== All evaluations complete ==="
50echo "Results in testing_output/evaluation/"

4.3 範例三:Python API 直接呼叫評估模組

如果你已經有自己的合成資料 (例如從 synthcity 或自建模型產出的 .npy 矩陣),可以直接呼叫 SynthEHRella 的評估模組:

 1import numpy as np
 2from synthEHRella.evaluation.fidelity import (
 3    compute_prevalence,
 4    compute_correlation,
 5    coappearance_matrix,
 6    discriminative_score
 7)
 8from synthEHRella.evaluation.utility import trtr, tstr, tsrtr
 9from synthEHRella.evaluation.privacy import (
10    membership_inference_attack,
11    attribute_inference_attack
12)
13
14# 載入資料 — 假設已轉換為 PhecodeXm 編碼的 binary matrix
15real_data = np.load("testing_output/mimic3-real-phecodexm.npy")
16synthetic_data = np.load("testing_output/postprocessed/corgan-synthetic-phecodexm.npy")
17
18# ── Fidelity 保真度 ──
19real_prev = compute_prevalence(real_data)
20synth_prev = compute_prevalence(synthetic_data)
21
22# 最大平均差異
23mmd = np.abs(real_prev - synth_prev).max()
24print(f"MMD (Max Mean Discrepancy): {mmd:.4f}")
25
26# 相關矩陣 Frobenius 距離
27real_corr = compute_correlation(real_data.astype(float))
28synth_corr = compute_correlation(synthetic_data.astype(float))
29corr_dist = np.linalg.norm(real_corr - synth_corr, 'fro')
30print(f"Correlation Frobenius Distance: {corr_dist:.4f}")
31
32# 判別器分數 (越接近 0.5 越好 → 無法區分真假)
33disc = discriminative_score(real_data, synthetic_data)
34print(f"Discriminative AUC: {disc['auc']:.4f}")
35
36# ── Utility 效用 ──
37# TRTR: 用真實資料訓練,真實資料測試 (基線)
38# TSTR: 用合成資料訓練,真實資料測試 (核心指標)
39# TSRTR: 用合成+真實訓練,真實資料測試 (資料增強)
40trtr_res = trtr(real_data, index=0)
41tstr_res = tstr(real_data, synthetic_data, index=0)
42tsrtr_res = tsrtr(real_data, synthetic_data, index=0)
43
44print(f"\nTRTR AUC: {trtr_res['auc']:.4f} (baseline)")
45print(f"TSTR AUC: {tstr_res['auc']:.4f} (synthetic only)")
46print(f"TSRTR AUC: {tsrtr_res['auc']:.4f} (synthetic + real)")
47print(f"TSTR-TRTR gap: {tstr_res['auc'] - trtr_res['auc']:.4f}")
48
49# ── Privacy 隱私 ──
50# Membership Inference Attack (MIA; 成員推論攻擊)
51mia = membership_inference_attack(real_data, synthetic_data)
52print(f"\nMIA - Mean min L2 distance: {mia['mean_min_distances']:.4f}")
53
54# Attribute Inference Attack (AIA; 屬性推論攻擊)
55# 選 10 個最平衡 + 10 個最不平衡的特徵作為未知屬性
56prevalence = compute_prevalence(real_data)
57sorted_idx = np.argsort(np.abs(prevalence - 0.5))
58unknown_idx = sorted_idx[:10].tolist() + sorted_idx[-10:].tolist()
59known_idx = list(set(range(real_data.shape[1])) - set(unknown_idx))
60
61aia_f1 = attribute_inference_attack(real_data, synthetic_data, known_idx, unknown_idx)
62print(f"AIA F1 Score: {aia_f1:.4f} (lower = better privacy)")

5. 在醫療結構化資料合成生態系中的定位

5.1 Domain 1 生態系定位

SynthEHRella 在 Bio-SDG Domain 1 (醫療結構化資料合成) 中扮演的是 「評估層」 的角色,它不是一個生成器,而是生成器的裁判:

子領域代表工具與 SynthEHRella 的關係
A. Patient SimulationSyntheaSynthEHRella 收錄 Synthea 作為受評方法之一
B. Privacy-Preserving SDGdp_cgans, OpenDPSynthEHRella 的 Privacy 模組可補充 DP 工具的隱私評估
C. Medical Tabular SDGsynthcity, COR-GANSynthEHRella 收錄 CorGAN; synthcity 的輸出可接入 SynthEHRella 評估
D. Clinical Trial DataVICTRE, TrialSynthSynthEHRella 的評估框架可推廣至 trial data
E. Medical Time SeriesTemporAI不同資料型態,SynthEHRella 專注表格 (tabular)

5.2 獨特價值

SynthEHRella 在生態系中的獨特貢獻是 「公平比較的方法論」

  1. 統一編碼座標系 (PhecodeX/PhecodeXm): 解決了不同方法使用不同 ICD 版本的不可比問題
  2. 三維評估不可偏廢: Fidelity 高不代表 Privacy 安全,Utility 好不代表 Fidelity 好
  3. 發表在 JAMIA: 方法論經同行評審認可,適合在論文中引用作為基準測試依據

5.3 藥物開發場景應用

對 pre-IND (Investigational New Drug; 研究用新藥) 階段的生物資訊分析師而言,SynthEHRella 的價值在於:

  • 選型決策: 當你需要合成 EHR 來做回顧性研究 (Retrospective Study) 時,SynthEHRella 幫你選最適合的方法
  • 隱私合規佐證: MIA/AIA 的量化結果可以作為 HIPAA / GDPR / 台灣個資法合規的技術佐證
  • 資料增強評估: TSRTR 指標直接回答「加入合成資料是否能提升下游預測任務」

6. 與其他工具的整合

6.1 與 synthcity 整合

synthcity 提供更多生成方法 (TVAE, CTGAN, DPGAN 等),但缺乏統一的 EHR 專用評估。你可以用 synthcity 生成、SynthEHRella 評估:

 1# 1. 用 synthcity 生成合成資料
 2from synthcity.plugins import Plugins
 3plugin = Plugins().get("tvae")
 4plugin.fit(real_dataframe)
 5synthetic_df = plugin.generate(count=50000)
 6
 7# 2. 轉換為 SynthEHRella 需要的 binary numpy matrix
 8synthetic_matrix = synthetic_df.values.astype(float)
 9
10# 3. 確保編碼與 SynthEHRella 的 PhecodeXm 一致後,直接呼叫評估
11from synthEHRella.run_evaluation import fidelity_evaluation, utility_evaluation, privacy_evaluation
12fidelity = fidelity_evaluation(real_phecodexm, synthetic_phecodexm)

6.2 與 Differential Privacy (DP; 差分隱私) 工具整合

SynthEHRella 收錄的 EHRDiff 已支援 DP training。你也可以先用 dp_cgans / IBM Diffprivlib 的 DP-GAN 生成,再用 SynthEHRella 做 Privacy 評估,量化 epsilon 值與實際攻擊成功率的關係。

6.3 與 CDISC SDTM/ADaM 格式的差距

SynthEHRella 目前處理的是 diagnosis phenotype binary matrix,尚未涵蓋 CDISC SDTM (Study Data Tabulation Model) / ADaM (Analysis Data Model) 常見的:

  • 連續型實驗室數值 (Lab Values)
  • 時間序列 (Vital Signs, Longitudinal Records)
  • 用藥紀錄 (Concomitant Medications)
  • 不良事件 (Adverse Events)

這是一個 Blue Ocean (藍海) 機會——將 SynthEHRella 的三維評估框架擴展到 SDTM/ADaM 格式的合成資料評估。

6.4 與 MIMIC 生態系的依賴

SynthEHRella 強依賴 MIMIC-III/IV 作為真實資料來源。若你的場景使用其他 EHR 系統 (如 eICU, UK Biobank, 台灣健保資料庫),需要自行實作前處理模組,將資料轉為 SynthEHRella 要求的 binary matrix 格式。


7. 優缺點分析

7.1 優點

面向說明
方法覆蓋面廣9 種方法橫跨 GAN / VAE / Diffusion / LLM / Rule-based / Statistical / Baseline,是目前最完整的 EHR 合成基準測試
評估框架嚴謹Fidelity + Utility + Privacy 三維評估,特別是 TSTR/TSRTR 的效用比較極具實務價值
編碼統一PhecodeX/PhecodeXm 轉換鏈解決了跨方法不可比的長期痛點
JAMIA 發表經同行評審的方法論,可放心引用;在 FDA 或 PMDA 提交中具有可信度
MIT License完全開源,商業可用,適合企業內部部署
CLI 驅動四步驟都有清楚的 CLI 入口,適合整合進自動化 pipeline

7.2 缺點

面向說明
僅支援 binary phenotype只處理「有/無某診斷碼」的 binary matrix,不支援連續值、計數、時間序列
強依賴 MIMIC預設只支援 MIMIC-III/IV 的前處理,其他 EHR 資料需自行轉換
環境設定複雜environment.yaml 包含 CUDA 12.1、R、Java 等多種執行環境依賴
缺乏 DP 量化整合雖然 EHRDiff 支援 DP training,但評估面只有 MIA/AIA,沒有直接關聯 epsilon 值
無 GUI / 無視覺化輸出只有 JSON 指標,需自行建立圖表比較;論文中的圖表未包含在 repo
專案活躍度有限18 stars、最後更新 2026-04,社群規模小
不含 CDISC 格式對法規科學 (Regulatory Science) 場景,缺少 SDTM/ADaM 的原生支援

7.3 適用性判斷

場景適合建議
選擇 EHR 合成方法用於研究高度適合直接使用
論文中基準測試新方法高度適合引用 JAMIA 論文 + 使用其評估模組
企業內部合成資料品質把關適合需自行擴展前處理
CDISC 格式合成資料評估不適合需大幅客製化
即時 (Real-time) 合成不適合非設計目標
時間序列 EHR 生成評估不適合建議看 TemporAI

一行總結: SynthEHRella 是目前最完整的 EHR 合成方法 Benchmarking 框架,以 PhecodeX 統一編碼、Fidelity/Utility/Privacy 三維評估,收錄 9 種方法公平比較,特別適合在論文中引用或企業內部選型,但僅限 binary phenotype 且強依賴 MIMIC 資料。