Repository: mims-harvard/TxGNN Stars: 276 · Language: Jupyter Notebook · License: MIT 論文預印本:medRxiv 2023.03.19.23287458 線上 Explorer:txgnn.org 出處實驗室:Harvard MIMS Lab(Marinka Zitnik 實驗室)


1. 專案概述 (Project Overview)

1.1 這個專案在解決什麼問題?

想像一位罕見疾病 (rare disease; 罕見疾病) 患者去看醫生。醫生翻遍藥典,發現目前「正式核准」治療這種病的藥物是零——不是因為沒有藥可能有效,而是因為:

  1. 這種病太罕見,藥廠沒有動機做臨床試驗 (clinical trial; 臨床試驗) 去申請適應症;
  2. 這種病的分子機制 (molecular mechanism; 分子機制) 研究不足,沒人知道該從哪個基因、哪個蛋白質下手找藥;
  3. 傳統的藥物重新定位 (drug repurposing; 藥物再利用) 方法多半是「有一點點資料才能學」——如果一個疾病在資料庫裡連一筆「藥物-疾病」關聯都沒有,模型根本無從學習。

TxGNN 要解決的正是第三點:當一個疾病完全沒有已知治療藥物時,該怎麼預測哪些藥可能有效? 這在機器學習裡叫做零樣本學習 (zero-shot learning; 零樣本學習)——模型從沒見過這個疾病和任何藥物的正向配對,卻要在推論階段直接給出有意義的預測,不需要額外微調 (fine-tuning; 微調) 或重新訓練。

一個生活化的比喻:假設你是一位新來的圖書館員,圖書館裡有 17,080 種疾病的「病歷卡」和 7,957 種藥物的「說明書」,彼此之間用各種關係連接(哪些藥治療哪些病、哪些疾病共享哪些基因、哪些藥物作用在哪些蛋白質上……)。現在來了一位得了「罕見自體免疫疾病 X」的患者,這張病歷卡上完全沒有寫過「哪種藥曾經治好過它」。傳統做法是攤手說「沒資料,無法查」。但一位經驗豐富的圖書館員會說:「雖然沒有直接記錄,但我知道 X 病跟另外三種比較常見的自體免疫疾病 Y、Z、W 有相似的發炎路徑 (inflammatory pathway; 發炎路徑),而治療 Y、Z、W 的藥物中,有幾種可能也對 X 有效。」這種「借用相似疾病的知識來推論」的能力,正是 TxGNN 內建的核心機制。

1.2 為什麼這是難題,而不是隨便套個模型就能解決?

一般的推薦系統 (recommendation system; 推薦系統)、連結預測 (link prediction; 連結預測) 模型(例如電商的「你可能也喜歡」)依賴的是「這個使用者/商品過去有沒有互動記錄」。但在零樣本藥物再利用的場景裡:

  • 目標疾病在訓練集中完全沒有正樣本(沒有任何藥物被標記為對它有效);
  • 一般圖神經網路 (graph neural network, GNN; 圖神經網路) 的連結預測在面對「零度」節點(degree=0 的節點,也就是這個節點在特定關係型下沒有任何邊)時,訊息傳遠 (message passing; 訊息傳遞) 機制會失效——沒有邊可以傳遞訊息,模型等於瞎猜;
  • 傳統做法(協同過濾、矩陣分解)在這種極端稀疏 (extreme sparsity; 極端稀疏) 情境下幾乎必然失敗。

TxGNN 的解法結合了兩個關鍵設計:異質知識圖譜預訓練 (heterogeneous knowledge graph pretraining; 異質知識圖譜預訓練) + 疾病相似度度量學習模組 (metric learning module; 度量學習模組)。前者讓模型先在整張知識圖譜上學會「一般的生物醫學關係模式」(不侵入具體的藥物-疾病標籤),後者則是在細調 (finetuning; 細調) 階段,明確地教模型「當某疾病沒有直接藥物證據時,去找相似疾病,把相似疾病的訊號借過來」。這個設計巧妙地把「零樣本」問題轉化成「有母群體可以類推的少樣本問題」。

1.3 在生物醫學 AI 領域的重要性與地位

TxGNN 發表於 2023 年(medRxiv 預印本),是幾何深度學習 (geometric deep learning; 幾何深度學習) 在藥物發現 (drug discovery; 藥物發現) 領域的代表性工作之一,也是 Harvard MIMS Lab(Multimodal Intelligence for Molecular Science,由 Marinka Zitnik 教授主持)「知識圖譜 + 精準醫學」系列研究的核心成果。它的重要性體現在幾個層面:

  1. 規模化的疾病覆蓋:預訓練知識圖譜涵蓋 17,080 個臨床已識別疾病與 7,957 個治療候選物,這個規模讓它可以系統性地對「孤兒疾病」(orphan disease; 孤兒疾病,即缺乏治療的疾病) 做批次篩選,而不是逐一人工分析。
  2. 人本中心設計 (human/clinician-centered design; 以臨床醫師為中心的設計):TxGNN 不只是輸出一個分數,還搭配了圖形解釋性 (graph explainability; 圖解釋性) 模組(GraphMask),能標示出「模型認為哪些邊/哪些鄰居疾病對這個預測貢獻最大」,這對臨床醫師的信任建立至關重要——黑盒子的預測分數在臨床場景幾乎沒有採用價值。
  3. 開源生態系的示範作用:MIT 授權、PyPI 可安裝(pip install TxGNN)、有線上 Explorer 網站(txgnn.org)可以互動式查詢,這種「論文 + 套件 + 網站」三位一體的交付方式,成為後續同類型知識圖譜藥物發現工作(例如同實驗室的 TxGemma、PrimeKG 系列)效法的範本。
  4. 統一任務formulation:TxGNN 把「適應症預測 (indication prediction; 適應症預測)」和「禁忌症預測 (contraindication prediction; 禁忌症預測)」用同一套模型架構統一處理——這在藥物安全性評估上很有意義,因為「這個藥不該用在這個病人身上」和「這個藥可能對這個病人有效」本質上是同一張知識圖譜上的不同邊類型 (edge type; 邊類型),值得共享表徵學習。

1.4 相關發表論文與引用

主論文

1Huang, K., Chandak, P., Wang, Q., Havaldar, S., Vaid, A., Leskovec, J.,
2Nadkarni, G., Glicksberg, B., Gehlenborg, N., & Zitnik, M. (2023).
3Zero-shot Prediction of Therapeutic Use with Geometric Deep Learning
4and Clinician Centered Design. medRxiv.
5doi: 10.1101/2023.03.19.23287458

這篇論文後來發表於 Nature Medicine(正式期刊版),是 Harvard MIMS Lab 在知識圖譜藥物發現領域被引用最廣的工作之一。TxGNN 所使用的底層知識圖譜衍生自同實驗室建構的 PrimeKG(Precision Medicine Knowledge Graph)——一個整合了 20 種生物醫學實體類型與數百萬條邊的大型異質知識圖譜,這點對於理解 TxGNN 的資料來源很關鍵:TxGNN 本身不建構知識圖譜,而是「消費」PrimeKG 這種現成的知識圖譜資源。

1.5 在 mims-harvard 實驗室生態系中的角色

Harvard MIMS Lab 的研究方向可以粗略分成三條主線:(1) 知識圖譜建構與表徵學習(PrimeKG、TxGNN 屬於這條線)、(2) 分子/蛋白質幾何深度學習(如藥物-靶點交互作用預測)、(3) 多模態醫學基礎模型。TxGNN 在生態系中扮演「知識圖譜 → 臨床決策」的橋接角色:它一手依賴 PrimeKG 的圖結構,另一手輸出對臨床醫師可解釋、可操作的藥物再利用候選清單。


flowchart TB
    subgraph SG_DATA["資料層:生物醫學知識來源"]
        A1["PrimeKG
異質知識圖譜"] A2["臨床資料庫
疾病本體/藥典"] end subgraph SG_REP["表徵學習層"] B1["TxGNN
零樣本藥物再利用"] B2["分子性質預測
GNN 模型群"] B3["蛋白質結構
幾何深度學習模型群"] end subgraph SG_APP["應用與臨床介接層"] C1["TxGNN Explorer
互動式網站"] C2["GraphMask XAI
解釋性模組"] C3["臨床決策輔助
醫師端工具"] end subgraph SG_ECO["同類型/相鄰生醫 AI 專案"] D1["AlphaFold 系列
蛋白質結構預測"] D2["ChemBERTa 系列
分子表徵學習"] D3["其他 GNN 藥物
發現框架"] end A1 --> B1 A2 --> B1 B1 --> C1 B1 --> C2 C1 --> C3 C2 --> C3 B1 -.相同幾何深度學習範式.-> D1 B1 -.互補的分子層級模型.-> D2 B1 -.圖神經網路架構借鑑.-> D3 style A1 fill:#DBEAFE,color:#0F172A style A2 fill:#DBEAFE,color:#0F172A style B1 fill:#FDE68A,color:#0F172A style B2 fill:#E5E7EB,color:#0F172A style B3 fill:#E5E7EB,color:#0F172A style C1 fill:#BBF7D0,color:#0F172A style C2 fill:#BBF7D0,color:#0F172A style C3 fill:#BBF7D0,color:#0F172A

從上圖可以看出,TxGNN 是「知識圖譜資料」與「臨床應用」之間的關鍵轉換器。它不做分子的三維結構預測(那是 AlphaFold 這類工具的領域),也不做分子指紋層級的性質預測(那是 ChemBERTa 這類化學語言模型的領域);它的定位非常明確——在疾病與藥物的關係網路層級做推論,這是它與同生態系其他工具最大的分工差異。

1.6 為什麼選擇「知識圖譜 + GNN」而不是純粹的統計方法?

如果只用傳統的統計方法(比如疾病共病率、藥物化學結構相似度打分),你能捕捉到的訊號非常有限,因為這些方法只看「一步」的關係。而知識圖譜的價值在於,它允許模型透過多跳 (multi-hop; 多跳) 推理捕捉到「疾病 A 和疾病 B 共享某個基因 → 這個基因被藥物 C 的靶點蛋白調控 → 因此藥物 C 可能對疾病 A 也有效」這種間接、但生物學上合理的路徑。GNN 的訊息傳遞機制正好是專門為了「聚合多跳鄰居資訊」而設計的,這就是為什麼 TxGNN(以及整個知識圖譜藥物發現領域)幾乎都收斂到用 GNN 作為底層架構。

1.7 目標使用者與團隊組成

TxGNN 不是給一般開發者「拿來就能用」的通用工具,它假設使用者具備一定的生物醫學背景與機器學習工程能力。典型的使用團隊組成通常包含:

  • 計算生物學家 / 生物資訊分析師 (bioinformatics analyst; 生物資訊分析師):負責準備領域特定的疾病清單、驗證知識圖譜切分是否符合研究問題、解讀模型輸出的生物學合理性;
  • 機器學習工程師:負責環境設定(尤其是 DGL 0.5.2 這類舊版相依)、超參數調校、訓練管線的穩定性維護;
  • 臨床顧問或藥理學專家:在候選藥物清單產出後,判斷哪些候選具備臨床合理性、哪些明顯不合理(例如藥物本身的已知禁忌症與目標疾病衝突);
  • (可選)法規事務/智財專員:若篩選出的候選藥物-疾病配對具有專利佈局或新適應症申請的潛力,需要及早介入評估。

這種多角色協作的需求,也是本文件第 6 節要討論「AIKT 如何補上工作流最後一哩路」的重要背景——單靠 TxGNN 本身的輸出,往往還需要一層跨角色的知識整合才能真正產生行動。

1.8 與傳統藥物再利用方法的對照

在 TxGNN 出現之前,藥物再利用領域常見的幾種方法路線各有其侷限,理解這些侷限有助於掌握 TxGNN 的貢獻定位:

傳統方法核心邏輯主要侷限
化學結構相似度篩選找化學結構相似的藥物,假設結構相似則作用機制也相似忽略了「結構不同但機制互補」的候選,也無法處理全新化學骨架
基因表達訊號比對 (如 CMap/L1000 反向連結)比對疾病訊號與藥物擾動訊號的反相關程度高度依賴特定細胞株的表達資料,跨組織/跨疾病的泛化能力有限
傳統知識圖譜嵌入 (TransE/RotatE 等)用嵌入向量的幾何關係表示三元組合理性對「零度」節點(無訓練邊的目標疾病)基本無法產生有意義嵌入
電子病歷共病分析從真實世界資料中挖掘藥物使用與疾病結果的統計關聯混雜因子 (confounding factor; 混雜因子) 難以完全排除,因果推論薄弱
TxGNN(本文重點)異質 GNN 預訓練 + 疾病相似度度量學習,專門設計零樣本推理機制仍依賴知識圖譜中存在可類推的相似疾病;仍是統計相關性,非因果證據

可以看到,TxGNN 並非「發明了一種全新的資料來源」,而是在既有的知識圖譜結構化資料上,設計了一套專門針對零度節點的推論機制——這正是它相對於前四種傳統方法的核心增量貢獻。

1.9 專案快速事實卡

在深入架構細節之前,先用一張表整理本專案的關鍵事實,方便日後快速查閱:

項目內容
核心任務藥物-疾病關係的零樣本連結預測(indication / contraindication / off-label use)
知識圖譜規模17,080 個疾病節點、7,957 個治療候選物節點,衍生自 PrimeKG
底層模型異質圖神經網路 + DistMult 打分函數 + 度量學習原型模組
訓練框架PyTorch + DGL 0.5.2
解釋性機制GraphMask(邊層級重要性遮罩,基於 Hard Concrete 分佈 + 拉格朗日優化)
API 套件pip install TxGNN,三個核心類別:TxData / TxGNN / TxEval
授權MIT License
論文狀態medRxiv 預印本,後續發表於同行評審期刊
線上互動介面txgnn.org(供非程式背景使用者查詢預測結果)
主要作者單位Harvard Medical School, Brigham and Women’s Hospital, Mount Sinai, Stanford

1.10 一句話總結專案定位

如果只能用一句話向沒有機器學習背景的同事解釋這個專案,可以這樣說:「TxGNN 是一套能在『完全沒有現成藥物』的疾病上,透過學習疾病與藥物在一張巨大生物醫學關係地圖中的位置,找出最可能有效的候選藥物,並附上證據說明的工具。」 這句話濃縮了零樣本學習(沒有現成藥物)、知識圖譜(生物醫學關係地圖)、以及可解釋性(附上證據說明)三個核心特徵,也是貫穿本教學文件後續所有章節的主軸。


2. 核心架構 (Core Architecture)

2.1 系統架構總覽

TxGNN 的程式碼結構分成三個核心類別(對應 txgnn/ 目錄下的三個主要模組),彼此職責清晰分離:

類別檔案職責
TxDataTxData.py下載/載入知識圖譜資料、產生訓練/驗證/測試切分 (split)
TxGNNTxGNN.py模型初始化、預訓練 (pretrain)、細調 (finetune)、GraphMask 解釋性訓練、模型存取
TxEvalTxEval.py疾病中心式評估 (disease-centric evaluation)、指標計算

底層的異質圖神經網路實作在 txgnn/model.pyDistMultPredictor 類別),解釋性模組則在 txgnn/graphmask/ 子目錄下獨立實作。


flowchart LR
    subgraph SG_INPUT["輸入層"]
        I1["kg.csv
知識圖譜三元組"] I2["node.csv
節點屬性表"] I3["edges.csv
邊屬性表"] end subgraph SG_TXDATA["TxData 模組"] T1["prepare_split()
依策略切分資料"] T2["create_dgl_graph()
建構 DGL 異質圖"] end subgraph SG_TXGNN["TxGNN 模組(核心模型)"] M1["model_initialize()
建構 DistMultPredictor"] M2["pretrain()
全邊型連結預測"] M3["finetune()
藥物_疾病關係 + 度量學習"] M4["train_graphmask()
解釋性訓練"] end subgraph SG_TXEVAL["TxEval 模組"] E1["eval_disease_centric()
疾病中心式評估"] E2["retrieve_disease_idxs_test_set()"] end subgraph SG_OUTPUT["輸出"] O1["排序後的藥物候選清單"] O2["graphmask_output.pkl
解釋性權重"] O3["評估指標
AUPRC / AUROC"] end I1 --> T1 I2 --> T1 I3 --> T1 T1 --> T2 T2 --> M1 M1 --> M2 M2 --> M3 M3 --> M4 M3 --> E1 M4 --> O2 E1 --> O1 E1 --> O3 E1 --> E2 style I1 fill:#DBEAFE,color:#0F172A style I2 fill:#DBEAFE,color:#0F172A style I3 fill:#DBEAFE,color:#0F172A style M1 fill:#FDE68A,color:#0F172A style M2 fill:#FDE68A,color:#0F172A style M3 fill:#FDE68A,color:#0F172A style M4 fill:#FDE68A,color:#0F172A style O1 fill:#BBF7D0,color:#0F172A style O2 fill:#BBF7D0,color:#0F172A style O3 fill:#BBF7D0,color:#0F172A

2.2 知識圖譜的結構:節點與邊型

TxGNN 使用的知識圖譜是異質圖 (heterogeneous graph; 異質圖),意味著圖上有多種節點類型與多種邊類型,而不是像普通社交網路那樣所有節點都是同一種「人」。核心節點類型包括:

  • drug(藥物)
  • disease(疾病)
  • gene/protein(基因/蛋白質)
  • effect/phenotype(效應/表型)
  • exposure(暴露因子,如環境毒素)
  • 其他還有 anatomy(解剖部位)、biological_process(生物過程)、pathway(訊息路徑)等

核心的藥物-疾病關係邊型(也就是模型最終要預測的目標)定義在程式碼中,一共 6 種(3 種正向 + 3 種反向,因為 DGL 異質圖需要雙向邊來支援訊息傳遞):

1self.etypes_dd = [
2    ('drug', 'contraindication', 'disease'),
3    ('drug', 'indication', 'disease'),
4    ('drug', 'off-label use', 'disease'),
5    ('disease', 'rev_contraindication', 'drug'),
6    ('disease', 'rev_indication', 'drug'),
7    ('disease', 'rev_off-label use', 'drug'),
8]

這裡有三個關係型很值得注意:

  • indication(適應症):藥物被核准或有證據支持用於治療該疾病;
  • contraindication(禁忌症):藥物不應該用在該疾病患者身上(例如會加重病情或有嚴重副作用);
  • off-label use(仿單標示外使用):藥物臨床上被使用於該疾病,但沒有正式核准(這正是「藥物再利用」最常發生的灰色地帶)。

把這三種關係放在同一套模型裡學習有個好處:模型可以學到「治療性」訊號和「危險性」訊號之間的對比結構,這對後續臨床應用的安全性判斷很有幫助。

2.3 資料流向:從原始 CSV 到最終預測


flowchart TD
    A["kg.csv 原始三元組
(head, relation, tail)"] --> B["preprocess_kg()
清洗+編碼節點ID"] B --> C{"選擇切分策略
split 參數"} C -->|complex_disease| D1["隨機取一批疾病
移除其全部治療邊"] C -->|disease_area 系列| D2["用疾病本體 HumanDO.obo
移除某疾病領域+局部鄰域"] C -->|random| D3["隨機打散藥物_疾病配對"] C -->|full_graph| D4["95% 訓練 / 5% 驗證
不留測試集(部署模式)"] D1 --> E["create_dgl_graph()
建構異質圖 G"] D2 --> E D3 --> E D4 --> E E --> F["DistMultPredictor
初始化節點/關係嵌入"] F --> G["pretrain(): 全部邊型
連結預測(自監督)"] G --> H["finetune(): drug_disease 邊
+ 疾病相似度度量學習"] H --> I{"目標疾病訓練時
有無正樣本邊?"} I -->|有| J1["直接用學到的
節點嵌入做內積打分"] I -->|零樣本情境: 無| J2["取得該疾病 profile
找 k 個最相似的疾病
聚合其嵌入做打分"] J1 --> K["DistMult 打分函數
score = h_u^T diag(W_r) h_v"] J2 --> K K --> L["排序候選藥物清單"] L --> M["TxEval 疾病中心式評估
AUPRC/AUROC/Recall@K"] style A fill:#DBEAFE,color:#0F172A style E fill:#FDE68A,color:#0F172A style F fill:#FDE68A,color:#0F172A style G fill:#FDE68A,color:#0F172A style H fill:#FDE68A,color:#0F172A style K fill:#FDE68A,color:#0F172A style L fill:#BBF7D0,color:#0F172A style M fill:#BBF7D0,color:#0F172A

2.4 關鍵演算法:兩階段訓練

TxGNN 採用兩階段訓練 (two-stage training; 兩階段訓練) 策略,這是理解整個系統最關鍵的一環。

階段一:預訓練 (pretraining)——TxGNN.pretrain()

這個階段的目標不是學藥物-疾病的關係,而是學「整張知識圖譜的一般結構」。做法是對圖上所有邊型(不只是藥物-疾病,還包括基因-蛋白質、疾病-表型、藥物-副作用等等所有數十種關係)做連結預測的自監督學習 (self-supervised learning; 自監督學習):隨機遮蔽 (mask) 一些邊,讓模型從剩下的圖結構去預測被遮蔽的邊是否存在。

1TxGNN.pretrain(
2    n_epoch = 2,
3    learning_rate = 1e-3,
4    batch_size = 1024,
5    train_print_per_n = 20
6)

這一步的意義好比:在讓學生做「藥物再利用」這種困難的專業題之前,先讓他把整本生物醫學教科書的知識結構(哪些概念彼此有關聯)都內化成直覺。這樣即使碰到教科書裡沒直接寫過「這個罕見病該用什麼藥」的題目,學生仍然能用底層的知識結構去類推。

階段二:細調 (finetuning)——TxGNN.finetune()

這個階段才專門針對 drug-disease 的三種關係型(indication / contraindication / off-label use)做監督式細調,並且啟用度量學習模組 (metric learning module; 度量學習模組) 來處理零樣本情境。

1TxGNN.finetune(
2    n_epoch = 500,
3    learning_rate = 5e-4,
4    train_print_per_n = 5,
5    valid_per_n = 20,
6    save_name = finetune_result_path
7)

2.5 度量學習模組:零樣本推理的核心機制

這是 TxGNN 最有巧思的部分,對應到 model.pyDistMultPredictor 類別裡 proto=True 時啟用的邏輯。運作原理可以拆成四步:

  1. 建立疾病特徵剖面 (disease profile; 疾病剖面):對每個疾病節點,根據它在圖上連結的其他節點(例如它連到哪些基因、哪些表型),彙整出一個特徵向量。程式碼中 sim_measure 參數控制怎麼建這個剖面,可選:

    • all_nodes_profile:綜合疾病-疾病邊 + 疾病-蛋白質邊
    • protein_profile:只用疾病關聯的蛋白質集合
    • protein_random_walk:在蛋白質-蛋白質交互作用網路上做隨機漫步 (random walk; 隨機漫步) 取樣出的分佈特徵
    • bert / profile+bert:用疾病名稱或定義文字的 BERT 語言模型嵌入
  2. 計算疾病相似度矩陣:用餘弦相似度 (cosine similarity; 餘弦相似度) 等方法(sim_matrix() 函數),對所有疾病的剖面向量兩兩計算相似度,得到一個疾病 × 疾病的相似度矩陣。

  3. 檢索 k 個最相似的疾病:當要預測疾病 D 時,如果 D 在訓練圖上是零度(沒有藥物邊),模型會從相似度矩陣中找出 proto_num(預設為 3 或 5)個與 D 最相似的疾病,取這些疾病的嵌入做加權聚合。

  4. 依「罕見度」加權聚合agg_measure 參數控制聚合方式,rarity(預設)代表根據疾病的罕見程度動態調整權重——越罕見的疾病,越依賴相似疾病的訊號補強;越常見(訓練樣本充足)的疾病,越依賴自己直接學到的嵌入。

這個機制用一句話總結:「當直接證據不足時,去問跟我最像的『同學』考得怎麼樣,並按情況決定要參考多少。」


flowchart LR
    subgraph SG_TARGET["目標:零樣本罕見病 D"]
        D0["疾病 D
訓練圖中無藥物邊"] end subgraph SG_PROFILE["剖面建構"] P1["取得 D 的鄰居
(基因/蛋白質/表型)"] P2["obtain_disease_profile()
建構特徵向量"] end subgraph SG_SIM["相似度檢索"] S1["sim_matrix()
對所有疾病算餘弦相似度"] S2["取 Top_k 相似疾病
(proto_num)"] end subgraph SG_AGG["聚合與打分"] AG1["取相似疾病的嵌入"] AG2{"agg_measure"} AG3["rarity 加權聚合"] AG4["簡單平均 avg"] AG5["融合目標疾病自身嵌入
(若有部分邊)"] AG6["DistMult 打分
對每個候選藥物"] end D0 --> P1 --> P2 --> S1 --> S2 --> AG1 AG1 --> AG2 AG2 -->|rarity| AG3 AG2 -->|avg| AG4 AG3 --> AG5 AG4 --> AG5 AG5 --> AG6 style D0 fill:#FCA5A5,color:#0F172A style P2 fill:#DBEAFE,color:#0F172A style S2 fill:#FDE68A,color:#0F172A style AG6 fill:#BBF7D0,color:#0F172A

2.6 打分函數:DistMult

模型用來計算「藥物-疾病配對合理程度」的打分函數是 DistMult(一種張量分解式的知識圖譜嵌入方法):

1score(h, r, t) = h^T · diag(W_r) · t

其中 h 是頭節點(例如藥物)的嵌入向量,t 是尾節點(疾病)的嵌入向量,W_r 是關係 r(indication / contraindication / off-label use)專屬的可學習對角矩陣。DistMult 的優點是計算便宜、參數量小,且在知識圖譜補全 (knowledge graph completion; 知識圖譜補全) 文獻中被廣泛驗證有效;缺點是它假設關係是對稱的(score(h,r,t) = score(t,r,h)),這對於本質上不對稱的「藥物治療疾病」關係其實不完全合理,但在異質圖 + 反向邊 (rev_indication 等) 的設計下,這個限制被部分緩解。

2.7 解釋性模組:GraphMask

訓練好連結預測模型後,可以進一步訓練 GraphMask 模組(train_graphmask())來產生邊層級的重要性遮罩——也就是「模型在做這個預測時,圖上哪些邊被認為是關鍵證據」。技術上這是用一個可微分的硬具體分佈 (Hard Concrete distribution; 硬具體分佈,見 graphmask/hard_concrete.py) 學習一個介於 0~1 的「保留機率」給每條邊,再用拉格朗日優化 (Lagrangian optimization; 拉格朗日優化,見 graphmask/lagrangian_optimization.py) 在「保留最少邊」與「維持預測準確度」之間找平衡。這一步是 TxGNN「人本中心設計」訴求的技術落地:模型不只給答案,還給「為什麼」。

2.8 資料切分策略如何影響零樣本能力的驗證

理解 TxGNN 的一個關鍵是它的多種資料切分 (split) 策略如何模擬不同程度的「資料稀缺」情境:

  • complex_disease:論文中的主要系統性切分。先抽樣一批疾病,把它們所有的藥物治療邊都移到測試集——確保這些疾病在訓練時是真正的零樣本。
  • cell_proliferation / mental_health / cardiovascular 等 9 種疾病領域切分:用疾病本體 (Disease Ontology; 疾病本體,HumanDO.obo 檔案) 找出屬於某個疾病大類的所有疾病,不只移除治療邊,還進一步移除局部鄰域的一部分邊,模擬「連分子機制都研究不足」的情境——這是比 complex_disease 更嚴苛的測試。
  • random:對照組,隨機打散配對,大多數疾病仍保有部分訓練訊號,用來確認模型在「正常」情境下的效能上限。
  • full_graph:不做任何遮蔽的部署模式,適合訓練「要真的拿去用」的最終模型。

這種切分設計本身就是論文方法論的重要貢獻——它讓「零樣本能力」不再只是定性宣稱,而是有可重現的量化評估協議。

2.9 元件互動關係總覽

把前面幾節提到的所有元件放進一張總覽表,方便日後對照程式碼時快速定位每個元件的職責與相依關係:

元件所在檔案依賴的上游元件提供給下游的介面
preprocess_kg() / create_split()utils.py原始 kg.csv清洗後的三元組表 + 切分好的 train/valid/test
create_dgl_graph()utils.py切分後的三元組表DGL 異質圖物件 G
DistMultPredictormodel.pyDGL 異質圖 Grel2idx節點嵌入、關係嵌入、打分函數 apply_edges()
obtain_disease_profile()utils.pyDGL 異質圖 G、疾病節點 ID疾病特徵剖面向量
sim_matrix()utils.py疾病剖面向量集合疾病 × 疾病相似度矩陣
TxGNN.pretrain()TxGNN.pyDistMultPredictor 初始化結果預訓練後的節點/關係嵌入
TxGNN.finetune()TxGNN.py預訓練嵌入 + 疾病相似度矩陣細調後的模型 + best_model
MovingAverage / LagrangianOptimizationgraphmask/細調後的模型GraphMask 訓練所需的優化狀態追蹤
TxGNN.train_graphmask()TxGNN.py細調後模型 + graphmask 優化元件邊層級重要性遮罩(gates)
TxEval.eval_disease_centric()TxEval.py細調後模型 + 測試集切分疾病中心式評估指標與排序結果

從這張表可以看出整個系統是一條清楚的單向依賴鏈:資料處理 → 圖建構 → 表徵學習 → 相似度檢索 → 打分與訓練 → 解釋性提取 → 評估。沒有任何元件之間存在循環依賴,這也是為什麼三個核心類別(TxData / TxGNN / TxEval)可以彼此獨立初始化,只在需要時透過建構子參數(如 TxEval(model=TxGNN))傳遞已完成的狀態。

2.10 為什麼把「相似度計算」放在模型初始化階段而非訓練迴圈中

一個容易被忽略但影響效能甚鉅的設計決策是:DistMultPredictor.__init__() 在建構時就一次性計算好所有疾病的相似度矩陣(self.sim_all_etypes),而不是在每次前向傳播 (forward pass; 前向傳播) 時動態計算。這個設計的取捨考量是:

  • 優點:疾病相似度矩陣在訓練過程中是固定不變的(疾病的鄰居結構不會因為模型參數更新而改變),預先計算並快取可以避免在數百個訓練 epoch 中重複計算同一份矩陣,大幅節省訓練時間;
  • 代價:這個設計假設了「用於計算相似度的圖結構」在訓練全程保持不變。如果你想要在訓練過程中動態更新知識圖譜(例如持續加入新的研究文獻產生的新邊),目前的架構不支援這種線上學習 (online learning; 線上學習) 模式,需要重新初始化整個模型才能反映圖結構的變化。

這個取捨對於「批次篩選、定期重新訓練」的使用模式(如本文件 §5.3 的批次管線)完全合理,但如果應用場景需要知識圖譜近乎即時更新,就需要在原始碼層級做額外的工程改動。


3. 安裝與設定 (Installation & Setup)

3.1 前置需求

TxGNN 對環境的要求相對嚴格,主要是因為底層依賴 DGL (Deep Graph Library; 深度圖形函式庫) 0.5.2 這個較舊的版本,以及 PyTorch。安裝前建議先確認:

項目要求
Python3.8(README 明確指定,較新版本相容性未經驗證)
PyTorch需搭配你的 CUDA 版本另外安裝
DGL精確版本 0.5.2(dgl-cuda{CUDA_VERSION}
PyG (PyTorch Geometric)僅在使用 disease_area 系列切分時需要(部分舊版資料處理邏輯用到)
硬體建議有 GPU;device 參數預設 cuda:0,CPU 也可跑但速度明顯較慢
磁碟空間知識圖譜檔案(kg.csv / node.csv / edges.csv)會自動從 Harvard Dataverse 下載,建議預留數百 MB 至數 GB 空間

依照本專案倉庫既有的容器化與工具鏈規範,建議用 conda 建立隔離環境(因為 DGL 0.5.2 這種舊版函式庫在系統層 Python 上容易與其他專案衝突):

3.2 逐步安裝指南

方法一:官方建議流程(conda + pip)

 1# Step 1: 建立獨立的 conda 環境,鎖定 Python 3.8
 2conda create --name txgnn_env python=3.8
 3conda activate txgnn_env
 4
 5# Step 2: 依照你的 CUDA 版本安裝 PyTorch
 6# 先查詢 https://pytorch.org/ 取得對應指令,例如 CUDA 11.3:
 7pip install torch==1.10.0+cu113 -f https://download.pytorch.org/whl/torch_stable.html
 8
 9# Step 3: 安裝 DGL 0.5.2(務必鎖定此版本,新版 API 已不相容)
10conda install -c dglteam dgl-cuda11.3==0.5.2
11
12# Step 4: 安裝 TxGNN 套件本體
13pip install TxGNN

方法二:從原始碼安裝(適合需要修改內部程式碼或想跑 reproduce/ 腳本的情境)

1git clone https://github.com/mims-harvard/TxGNN.git
2cd TxGNN
3conda create --name txgnn_env python=3.8 -y
4conda activate txgnn_env
5pip install -r requirements.txt
6pip install -e .

方法三(可選):需要 disease_area 切分時,額外安裝 PyTorch Geometric

1# 依照 PyG 官方安裝指引,需與已安裝的 torch/CUDA 版本精確對應
2pip install torch-scatter torch-sparse torch-cluster torch-spline-conv \
3    -f https://data.pyg.org/whl/torch-1.10.0+cu113.html
4pip install torch-geometric

3.3 環境設定要點

  • CUDA 裝置指定TxGNN(data=..., device='cuda:0') 中的 device 字串需與實際 GPU 編號一致;若無 GPU 可設為 'cpu',但預訓練階段(全邊型連結預測)在 CPU 上可能需要數小時甚至更久,實務上不建議。
  • 實驗追蹤(可選)weight_bias_track=True 會啟用 Weights & Biases (wandb) 追蹤訓練過程,需要額外 pip install wandb 並登入帳號;一般教學/驗證用途可保持 False
  • 資料下載位置TxData(data_folder_path='./data') 建構時會自動從 Harvard Dataverse 下載 kg.csvnode.csvedges.csv 到指定目錄;若網路受限,建議先確認可以連上 dataverse.harvard.edu
  • legacy 相依:README 特別註記 disease-area 切分依賴「舊版資料處理程式碼中用到的 PyG 工具函數」,這是一個歷史技術債的訊號——如果你只用 complex_diseaserandom 切分,可以完全跳過 PyG 安裝。

3.4 驗證安裝

安裝完成後,用以下最小指令驗證環境是否可用:

 1import dgl
 2import torch
 3from txgnn import TxData, TxGNN, TxEval
 4
 5print("DGL version:", dgl.__version__)      # 應顯示 0.5.2
 6print("Torch version:", torch.__version__)
 7print("CUDA available:", torch.cuda.is_available())
 8
 9# 驗證套件可正常初始化資料下載流程(會嘗試建立 ./data_verify 目錄並下載檔案)
10TxData_test = TxData(data_folder_path='./data_verify')
11print("TxData initialized OK, files at:", TxData_test.data_folder)

若上述程式沒有報錯且能看到三個檔案(kg.csv, node.csv, edges.csv)出現在 ./data_verify 目錄下,代表環境設定成功。若在 import dgl 時出現 ImportError 或版本不符警告,通常是 DGL 版本沒鎖定在 0.5.2,需要重新用 conda install -c dglteam dgl-cuda{CUDA_VERSION}==0.5.2 安裝正確版本。

3.5 常見安裝陷阱

  1. DGL 版本過新:DGL 從 0.6 之後 API 有較大改動(尤其是 dgl.function 與異質圖的操作介面),直接裝最新版會導致 model.py 中大量函式呼叫失敗。務必鎖定 0.5.2。
  2. CUDA 版本與 DGL/PyTorch 不匹配dgl-cuda{$CUDA_VERSION} 中的版本號要跟你實際安裝的 PyTorch CUDA 版本一致,否則會在載入 GPU tensor 時出現底層符號找不到的錯誤。
  3. goatools 相依requirements.txt 中列出 goatools(用於處理疾病本體/基因本體 (Gene Ontology; 基因本體) 相關的分析),這個套件在某些 Python 版本上編譯較慢,建議用 conda-forge 頻道安裝以減少編譯時間。

3.6 容器化安裝(符合本專案容器優先原則)

依照本專案「系統服務預設 Docker/Podman,避免原生安裝」的規範,若要讓 TxGNN 的環境可重建、可版本化,建議把整套安裝流程寫成 Dockerfile 而非直接在主機上動手裝:

 1FROM continuumio/miniconda3:latest
 2
 3WORKDIR /workspace
 4
 5# 建立鎖定 Python 3.8 的 conda 環境
 6RUN conda create -n txgnn_env python=3.8 -y
 7
 8SHELL ["conda", "run", "-n", "txgnn_env", "/bin/bash", "-c"]
 9
10# 依 CUDA 版本安裝 PyTorch(範例為 CPU 版本,GPU 版本需替換對應 wheel)
11RUN pip install torch==1.10.0
12
13# 鎖定 DGL 0.5.2
14RUN conda install -c dglteam dgl==0.5.2 -y
15
16# 安裝 TxGNN 套件本體
17RUN pip install TxGNN
18
19ENTRYPOINT ["conda", "run", "--no-capture-output", "-n", "txgnn_env", "python"]

建構與執行方式:

1docker build -t txgnn-env:0.0.3 .
2docker run --rm -it -v "$(pwd)/data:/workspace/data" txgnn-env:0.0.3 my_script.py

這種做法的好處是:環境設定被固化成一份可以 commit 進版本控制的文件,其他人(或未來的你)不需要重新摸索 DGL 版本相容性問題,只需要 docker build 就能重現完全一致的環境。若需要 GPU 支援,改用 nvidia/cuda 系列基底映像檔並搭配 --gpus all 執行參數即可。

3.7 安裝疑難排解對照表

錯誤現象可能原因解決方式
ImportError: cannot import name 'xxx' from 'dgl.function'DGL 版本過新,API 已變動確認 dgl.__version__ == '0.5.2',否則重新安裝指定版本
CUDA 相關的 undefined symbol 錯誤PyTorch 與 DGL 編譯時使用的 CUDA 版本不一致重新確認兩者都對應同一個 CUDA 版本(例如都用 11.3)
pip install TxGNN 卡在 goatools 編譯系統缺少對應的編譯工具鏈改用 conda install -c conda-forge goatools 後再裝 TxGNN
下載 kg.csv 時逾時或連線失敗無法連上 Harvard Dataverse檢查網路/防火牆設定,或改用手動下載後放入 data_folder_path 指定目錄
PyG 安裝時版本衝突torch-scatter 等擴充套件版本需與 torch 版本精確對應依照 PyG 官方安裝矩陣頁面查詢對應 wheel 網址,不要用泛用的 pip install torch-geometric

4. 基本使用 (Basic Usage)

4.1 快速入門:五分鐘理解核心工作流

TxGNN 的核心 API 遵循一個清楚的三段式流程:準備資料 (TxData) → 訓練模型 (TxGNN) → 評估與預測 (TxEval)。下面用一個完整、可以直接複製執行的最小範例來走一遍。

在動手寫程式之前,先看一下原始輸入資料 kg.csv 的格式長什麼樣子,這對理解後續所有 API 呼叫在操作什麼東西很有幫助:

x_idxx_typex_idrelationy_idxy_typey_id
101.0drugDB00001indication9907.0diseaseMONDO:0005267
101.0drugDB00001contraindication12787.0diseaseMONDO:0018874
205.0gene/protein3569rev_disease_protein9907.0diseaseMONDO:0005267

每一列代表知識圖譜中的一條邊:x_idx/x_type/x_id 是頭節點的內部索引、節點類型、外部資料庫 ID(藥物用 DrugBank ID,疾病用 MONDO 本體 ID),relation 是邊類型,y_idx/y_type/y_id 是尾節點對應資訊。TxData.prepare_split() 內部就是在這張表上做各種篩選/遮蔽操作,理解這個表格結構,後面看到 disease_idxs=[9907.0, 12787.0] 這種呼叫時就能明白這些數字究竟指向什麼。

範例場景:假設我們是一個藥物再利用研究團隊,想要系統性地為知識圖譜中「複雜疾病切分」下的所有零樣本疾病,找出可能有效的候選藥物。

 1from txgnn import TxData, TxGNN, TxEval
 2
 3# ---- Step 1: 準備資料與切分 ----
 4TxData = TxData(data_folder_path='./data')
 5TxData.prepare_split(split='complex_disease', seed=42)
 6
 7# ---- Step 2: 初始化模型 ----
 8TxGNN = TxGNN(
 9    data=TxData,
10    weight_bias_track=False,
11    proj_name='TxGNN_demo',
12    exp_name='complex_disease_run1',
13    device='cuda:0'          # 沒有 GPU 請改成 'cpu'
14)
15
16TxGNN.model_initialize(
17    n_hid=100,                     # 隱藏層維度
18    n_inp=100,                     # 輸入嵌入維度
19    n_out=100,                     # 輸出嵌入維度
20    proto=True,                    # 開啟度量學習模組(零樣本推理關鍵開關)
21    proto_num=3,                   # 檢索 3 個最相似的疾病
22    attention=False,                # 若之後要跑 GraphMask 解釋性,這裡必須是 False
23    sim_measure='all_nodes_profile', # 疾病相似度剖面建構方式
24    agg_measure='rarity',          # 依罕見度動態加權聚合
25    num_walks=200,
26    path_length=2
27)

4.2 從零開始的完整訓練範例

 1# ---- Step 3: 預訓練(在整張知識圖譜上做自監督連結預測) ----
 2TxGNN.pretrain(
 3    n_epoch=2,
 4    learning_rate=1e-3,
 5    batch_size=1024,
 6    train_print_per_n=20
 7)
 8
 9# ---- Step 4: 細調(針對藥物-疾病關係 + 啟用度量學習) ----
10TxGNN.finetune(
11    n_epoch=500,
12    learning_rate=5e-4,
13    train_print_per_n=5,
14    valid_per_n=20,
15    save_name='./finetune_result'
16)
17
18# ---- Step 5: 儲存訓練好的模型,供之後重複使用 ----
19TxGNN.save_model('./model_ckpt')

在真實研究情境中,n_epoch=2 的預訓練只是教學示範用的最小值;論文中實際使用的 epoch 數會依資料規模與收斂狀況調整,通常需要跑數十甚至上百個 epoch 才能讓全圖的連結預測任務充分收斂。細調階段的 valid_per_n=20 代表每 20 個 epoch 在驗證集上檢查一次效能,用於早停 (early stopping; 提前停止) 判斷。

4.3 載入預訓練模型(跳過訓練,直接推論)

如果你不想從頭訓練(訓練一次可能要數小時),官方提供了範例預訓練權重可以直接載入:

 1from txgnn import TxData, TxGNN, TxEval
 2
 3TxData = TxData(data_folder_path='./data')
 4TxData.prepare_split(split='complex_disease', seed=42)
 5
 6TxGNN = TxGNN(data=TxData, device='cuda:0')
 7
 8# 直接載入官方提供的預訓練 checkpoint(需先從 Google Drive 連結下載並解壓)
 9TxGNN.load_pretrained('./model_ckpt')
10
11print("模型載入完成,可直接進行評估或推論")

4.4 疾病中心式評估:對測試集所有零樣本疾病做批次評估

 1from txgnn import TxEval
 2
 3TxEval = TxEval(model=TxGNN)
 4
 5# 對整個測試集(所有被系統性移除治療邊的零樣本疾病)做評估
 6result = TxEval.eval_disease_centric(
 7    disease_idxs='test_set',
 8    show_plot=False,
 9    verbose=True,
10    save_result=True,
11    return_raw=False,
12    save_name='./eval_result.pkl'
13)
14
15print(result.keys())   # 通常包含各項排序指標,如 AUPRC、Recall@K 等

輸出格式範例result 物件的典型結構,實際欄位依 disease_centric_evaluation() 實作而定):

 1{
 2    'auprc': 0.87,          # 每個疾病的平均精確率-召回率曲線下面積
 3    'auroc': 0.91,
 4    'recall_at_1': 0.42,    # 排名第一的藥物是否命中真實治療藥物的比例
 5    'per_disease_scores': {
 6        9907.0: {'auprc': 0.90, 'top_drugs': [123, 456, 789]},
 7        12787.0: {'auprc': 0.81, 'top_drugs': [234, 567, 890]},
 8        # ... 每個疾病的個別分數與排序後的候選藥物 ID
 9    }
10}

4.5 針對特定疾病做預測:生物醫學實際應用場景

假設我們的臨床合作醫師特別關心「腎上腺 (adrenal gland; 腎上腺) 相關罕見疾病」——這是知識圖譜中疾病 idx 9907.012787.0(範例編號,實際需查表對應)——想知道模型對這兩種病的候選藥物排名:

 1# 只對特定疾病做「適應症 (indication)」關係的預測
 2result = TxEval.eval_disease_centric(
 3    disease_idxs=[9907.0, 12787.0],
 4    relation='indication',
 5    save_result=False,
 6    verbose=True
 7)
 8
 9for disease_idx, scores in result['per_disease_scores'].items():
10    print(f"疾病 {disease_idx} 的前 5 個候選藥物排名: {scores['top_drugs'][:5]}")

在真實的研究流程中,拿到候選藥物 ID 之後,下一步通常是:(1) 對照 node.csv 把 ID 轉換回藥物的實際名稱/化學結構,(2) 用文獻搜尋工具(如本專案 Layer 9 的 paper-search)交叉查證這些候選藥物是否已有相關的個案報告或臨床前證據,(3) 用解釋性模組(見 §4.6)檢視模型判斷背後的證據路徑,避免直接把黑盒子輸出當成臨床建議。

4.6 產生解釋性報告:GraphMask 訓練與提取

 1# 在已經細調完成的模型基礎上,針對 indication 關係訓練解釋性模組
 2TxGNN.train_graphmask(
 3    relation='indication',
 4    learning_rate=3e-4,
 5    allowance=0.005,       # 控制稀疏度的目標保留邊比例
 6    epochs_per_layer=3,
 7    penalty_scaling=1,
 8    valid_per_n=20
 9)
10
11# 提取每條邊的重要性遮罩(gate)並存成 pickle 檔
12gates = TxGNN.retrieve_save_gates('./explain_output')
13# 產出檔案類似: ./explain_output/graphmask_output_indication.pkl
14
15# 也可以單獨儲存/載入 GraphMask 模型權重,避免重複訓練
16TxGNN.save_graphmask_model('./graphmask_model_ckpt')
17TxGNN.load_pretrained_graphmask('./graphmask_model_ckpt')

拿到 gates 之後,每條邊會對應一個介於 0~1 的重要性分數,靠近 1 代表這條邊在模型做出該預測時是重要的支撐證據;把這些邊視覺化成子圖,就是論文中呈現給臨床醫師的「解釋圖」。

4.7 三個實際生物醫學情境的應用範例小結

情境使用的切分關鍵參數產出
罕見自體免疫疾病篩藥autoimmune 疾病領域切分proto=True, proto_num=3候選藥物排序 + 解釋子圖
系統性零樣本能力驗證(論文重現)complex_disease論文預設超參數AUPRC/AUROC 完整測試集報告
部署到臨床工具(不做測試集保留)full_graphonly_prediction=True(TxEval 內部自動處理)針對真實患者疾病的即時預測

這三種情境剛好對應到研究工作的三個不同階段:探索階段(用疾病領域切分快速驗證某個特定領域是否值得投入)、驗證階段(用 complex_disease 做嚴謹的方法論重現,確保結果可以在論文層級被檢驗)、以及部署階段(用 full_graph 訓練出真正要交給臨床端使用的最終模型,此時不再保留測試集,因為目標已經從「驗證方法有效」轉移到「最大化訓練資料利用率」)。實務上建議依序走完這三個階段,不要跳過驗證階段直接部署——這是避免把方法論尚未驗證過的模型直接推向臨床應用的基本紀律。


5. 進階功能與應用場景 (Advanced Features & Use Cases)

5.1 進階配置:疾病相似度度量的選擇策略

TxGNN 提供多種 sim_measure 選項,這不是隨意的超參數,而是對應到不同的生物學假設,選擇時應該考慮你的應用場景:

  • all_nodes_profile(預設,論文主結果採用):綜合考慮疾病間的直接關聯(disease-disease 邊)與疾病關聯的蛋白質集合。適合大多數一般用途,是最穩健的預設選擇。
  • protein_profile:只看疾病關聯的蛋白質集合的重疊程度。當你特別關心「分子機制相似性」而非表型相似性時(例如研究單基因罕見病),這個選項更聚焦。
  • protein_random_walk:在蛋白質-蛋白質交互作用網路上做隨機漫步取樣,捕捉更深層的網路拓樂特徵,而非僅看一階鄰居重疊。計算成本較高(num_walkspath_length 兩個超參數需要調整),適合蛋白質交互作用網路資料特別豐富的情境。
  • bert / profile+bert:結合疾病名稱或定義的語言模型嵌入。這代表 TxGNN 也允許把非結構化的文字知識(例如臨床描述)和結構化的圖譜知識融合,是一個值得注意的擴充方向——但注意程式碼中這個選項依賴寫死的絕對路徑(/n/scratch3/users/k/kh278/...,明顯是原作者的 HPC 叢集路徑),要用這個選項必須自行準備 BERT 嵌入檔案並修改程式碼中的路徑,屬於進階客製化用法。

5.2 客製化超參數搜尋:系統性調參範例

 1import itertools
 2from txgnn import TxData, TxGNN, TxEval
 3
 4TxData = TxData(data_folder_path='./data')
 5TxData.prepare_split(split='complex_disease', seed=42)
 6
 7# 系統性搜尋 proto_num 與 sim_measure 的組合對零樣本效能的影響
 8proto_nums = [1, 3, 5, 10]
 9sim_measures = ['all_nodes_profile', 'protein_profile']
10
11results_grid = {}
12for proto_num, sim_measure in itertools.product(proto_nums, sim_measures):
13    model = TxGNN(data=TxData, device='cuda:0')
14    model.model_initialize(
15        n_hid=100, n_inp=100, n_out=100,
16        proto=True, proto_num=proto_num,
17        sim_measure=sim_measure, agg_measure='rarity'
18    )
19    model.pretrain(n_epoch=2, learning_rate=1e-3, batch_size=1024)
20    model.finetune(n_epoch=200, learning_rate=5e-4, valid_per_n=20)
21
22    evaluator = TxEval(model=model)
23    res = evaluator.eval_disease_centric(disease_idxs='test_set', verbose=False)
24    results_grid[(proto_num, sim_measure)] = res['auprc']
25
26# 找出最佳組合
27best_config = max(results_grid, key=results_grid.get)
28print(f"最佳組合: proto_num={best_config[0]}, sim_measure={best_config[1]}, "
29      f"AUPRC={results_grid[best_config]:.4f}")

這種網格搜尋 (grid search; 網格搜尋) 在真實研究中通常需要搭配較短的 n_epoch 做快速篩選,找到候選組合後再用完整 epoch 數重跑驗證,避免每個組合都花費完整訓練時間。

5.3 應用案例:跨疾病領域的批次篩選管線

實際的藥物再利用研究常常不是只看一個疾病,而是要對「一整類罕見病」做系統性篩選。以下範例展示如何針對 TxGNN 內建的 9 種疾病領域切分逐一訓練與評估,產出一份跨領域的篩選報告:

 1from txgnn import TxData, TxGNN, TxEval
 2import pandas as pd
 3
 4disease_areas = [
 5    'cell_proliferation', 'mental_health', 'cardiovascular', 'anemia',
 6    'adrenal_gland', 'autoimmune', 'metabolic_disorder',
 7    'diabetes', 'neurodigenerative'
 8]
 9
10summary_rows = []
11for area in disease_areas:
12    data = TxData(data_folder_path='./data')
13    data.prepare_split(split=area, seed=42)
14
15    model = TxGNN(data=data, device='cuda:0')
16    model.model_initialize(n_hid=100, n_inp=100, n_out=100,
17                            proto=True, proto_num=3, agg_measure='rarity')
18    model.pretrain(n_epoch=2, learning_rate=1e-3, batch_size=1024)
19    model.finetune(n_epoch=300, learning_rate=5e-4, valid_per_n=20)
20
21    evaluator = TxEval(model=model)
22    res = evaluator.eval_disease_centric(disease_idxs='test_set', verbose=False)
23
24    summary_rows.append({
25        'disease_area': area,
26        'auprc': res.get('auprc'),
27        'auroc': res.get('auroc'),
28    })
29
30summary_df = pd.DataFrame(summary_rows)
31summary_df.to_csv('./disease_area_screening_summary.csv', index=False)
32print(summary_df.sort_values('auprc', ascending=False))

這種批次管線的產出,可以直接作為研究團隊向臨床合作方展示「哪些疾病領域的零樣本預測特別可靠、哪些領域模型信心較低(值得優先人工複核)」的量化依據。

5.4 與其他工具/函式庫的整合

  • 與 wandb 整合:設定 weight_bias_track=True 後,所有訓練過程的損失曲線、驗證指標會自動記錄到 Weights & Biases 儀表板,適合多組實驗的長期追蹤比較。
  • 與 DGL 生態系整合:因為底層圖結構是標準 DGL 異質圖物件(self.G),使用者可以直接用 DGL 的其他工具(如子圖採樣 dgl.sampling、圖視覺化)對 TxGNN 的知識圖譜做額外分析,不侵入 TxGNN 本身的訓練流程。
  • 與下游文獻驗證工具整合:TxGNN 輸出的是「候選藥物排序」,本質上是生成假設 (hypothesis generation; 假設生成) 的工具,而不是最終答案。在真實研究工作流中,通常會搭配文獻檢索/問答系統(例如語意搜尋跨資料庫論文、或本地 RAG 問答系統)去驗證 TxGNN 排名前幾位的候選藥物是否已有支持性的個案報告或臨床前證據——這正是第 6 節要討論的 AIKT 整合機會所在。

5.5 效能優化建議

  1. 批次大小調整pretrain(batch_size=1024, ...) 的批次大小直接影響 GPU 記憶體用量與訓練速度。在較小 GPU(如 8GB 顯存)上可能需要調降到 256 或 512。
  2. 減少 num_walkspath_length:若使用 protein_random_walk 相似度度量,這兩個參數是計算瓶頸;num_walks=200 在大型蛋白質網路上會顯著拖慢初始化速度,教學/原型驗證階段可先降到 50 做快速迭代。
  3. 快取疾病相似度矩陣DistMultPredictor 初始化時會計算並快取 sim_all_etypes(各邊型的疾病相似度矩陣),這一步只需要做一次;若要重複實驗不同的 proto_num,可以重複使用同一個已初始化的模型物件,只改推論邏輯,避免重複計算相似度矩陣造成不必要的等待。
  4. 早停策略finetune(valid_per_n=20, ...) 配合追蹤驗證集指標手動決定何時停止,避免過度訓練在小訓練集上造成過擬合 (overfitting; 過擬合),尤其在資料稀缺的疾病領域切分下這個風險更明顯。
  5. GPU 記憶體管理:訓練完一個疾病領域切分的模型後,若要接著跑下一個切分(如 §5.3 的批次篩選管線),建議在迴圈中適時呼叫 torch.cuda.empty_cache() 釋放記憶體,避免多次迭代後顯存累積耗盡。

5.6 應用案例:結合解釋性輸出做候選藥物的機制分群

單純看候選藥物的排序分數,很難判斷「這些候選藥物是不是因為相同的生物學理由被選中」。以下範例示範如何結合 GraphMask 的邊重要性輸出,把候選藥物依照它們「借用的證據路徑」做分群,這對臨床醫師理解「一群候選藥物背後是不是同一套機制」很有幫助:

 1import pickle
 2import numpy as np
 3from collections import defaultdict
 4
 5# 載入之前訓練好的 GraphMask 解釋性輸出
 6with open('./explain_output/graphmask_output_indication.pkl', 'rb') as f:
 7    gates = pickle.load(f)
 8
 9# 假設 gates 結構包含每條邊的 (src, etype, dst, importance) 資訊
10# 依照「哪些中介節點(如共享基因/表型)出現在高重要性邊上」做候選藥物分群
11mechanism_groups = defaultdict(list)
12
13for edge_info in gates:
14    src, etype, dst, importance = edge_info
15    if importance > 0.5 and etype in ('rev_disease_protein', 'disease_phenotype_positive'):
16        # 把「透過同一個中介節點被連結」的候選藥物歸為同一機制群組
17        mechanism_groups[dst].append((src, importance))
18
19for mediator_node, drugs in mechanism_groups.items():
20    if len(drugs) > 1:
21        print(f"中介節點 {mediator_node} 連結了 {len(drugs)} 個高信度候選路徑")

這種分群結果對臨床合作方特別有價值——如果十個候選藥物全部經由同一個蛋白質靶點被連結,代表模型其實只找到了「一種機制假說」的十種變體,而不是十種獨立的證據來源,這會直接影響後續驗證資源該如何分配。

5.7 應用案例:與多體學資料 (multi-omics data; 多體學資料) 交叉比對

TxGNN 的知識圖譜本身已包含基因/蛋白質節點,但若研究團隊手上有特定病人群體的體學資料(如轉錄體 (transcriptome; 轉錄體) 定序結果),可以把 TxGNN 的候選藥物輸出,與病人特異的分子特徵做交叉比對,篩選出「不只在知識圖譜層級合理,也在特定病人分子背景下合理」的候選:

 1import pandas as pd
 2
 3# candidate_drugs: 前面步驟 TxEval 輸出的候選藥物清單(含對應靶點蛋白 ID)
 4# patient_deg: 病人群體的差異表達基因 (differentially expressed genes) 分析結果
 5candidate_drugs = pd.read_csv('./candidate_drugs_with_targets.csv')
 6patient_deg = pd.read_csv('./patient_cohort_deg_results.csv')
 7
 8# 篩選出候選藥物的已知靶點蛋白,恰好也是病人群體中顯著上調/下調的基因
 9merged = candidate_drugs.merge(
10    patient_deg, left_on='target_protein_id', right_on='gene_id', how='inner'
11)
12prioritized = merged[merged['adj_p_value'] < 0.05].sort_values('txgnn_score', ascending=False)
13
14print(f"交叉比對後,優先驗證的候選藥物數量: {len(prioritized)}")
15print(prioritized[['drug_name', 'target_protein_id', 'txgnn_score', 'log2fc']].head(10))

這種「知識圖譜層級的候選 × 病人特異分子證據」雙重篩選,是把 TxGNN 從「通用疾病層級工具」落地到「特定病人群體精準醫學應用」的關鍵一步,也呼應了論文標題中「精準醫學」的訴求。


6. AIKT 整合分析與策略 (AIKT Integration & Strategy)

6.1 整合架構圖:TxGNN 如何嵌入 AIKT 27 層

TxGNN 本質上是一個演算法層 (algorithmic layer; 演算法層) 工具——它做的是圖神經網路的訓練與推論,這與 AIKT 的核心定位(知識工作流編排,而非直接科學計算)是互補而非重疊的關係。下圖展示 TxGNN 可能與 AIKT 各層的資訊流動方式:


flowchart TB
    subgraph SG_EXT["外部:TxGNN 演算法層(不屬於 AIKT)"]
        TX1["TxGNN 模型訓練/推論
(在獨立 Python/conda 環境執行)"] TX2["候選藥物排序清單
+ GraphMask 解釋子圖"] end subgraph SG_L2["L2 ai-gh-save"] L2A["gh: mims-harvard/TxGNN
→ inbox/ 教學 md"] end subgraph SG_L9L10["L9/L10 文獻驗證層"] L9A["paper-search: 針對候選藥物
+目標疾病做交叉查證"] L10A["paper-qa-lite: 本地文獻庫
問答驗證候選藥物證據"] end subgraph SG_L18["L18 research-pipeline-v2"] L18A["多輪研究:整合 TxGNN 輸出
+文獻證據+安全性評估"] end subgraph SG_L19["L19 tu-plan-generator"] L19A["若候選藥物值得推進
→產生藥物開發計畫"] end subgraph SG_L11L7["L11/L7 專業輸出層"] L7A["quarkdown: 篩選報告
md→PDF/HTML"] L11A["kami: 品牌化簡報
給臨床/內部決策者"] end subgraph SG_L4["L4 graphify"] L4A["知識圖譜索引
(AIKT 自身知識庫,非 PrimeKG)"] end TX1 --> TX2 L2A -.學習/引用TxGNN方法論.-> TX1 TX2 --> L9A TX2 --> L10A L9A --> L18A L10A --> L18A TX2 --> L18A L18A --> L19A L18A --> L7A L7A --> L11A L18A -.可選:寫入研究筆記.-> L4A style TX1 fill:#FCA5A5,color:#0F172A style TX2 fill:#FCA5A5,color:#0F172A style L2A fill:#DBEAFE,color:#0F172A style L9A fill:#FDE68A,color:#0F172A style L10A fill:#FDE68A,color:#0F172A style L18A fill:#BBF7D0,color:#0F172A style L19A fill:#BBF7D0,color:#0F172A style L7A fill:#E5E7EB,color:#0F172A style L11A fill:#E5E7EB,color:#0F172A style L4A fill:#E5E7EB,color:#0F172A

關鍵解讀:紅色節點(TxGNN 本體)明確畫在 AIKT 邊界之外——這是刻意的設計判斷,理由詳見 §6.4。AIKT 不吞入 TxGNN 的訓練/推論邏輯,而是在它的輸出(候選藥物清單)產生之後,接手做「文獻驗證 → 研究整合 → 專業報告輸出」這一段 AIKT 本來就擅長的知識工作流。

6.2 紅海分析 (Red Ocean Analysis):功能重疊的檢視

先誠實檢視哪裡確實存在功能重疊,避免自我膨脹 AIKT 的能力邊界:

重疊功能點TxGNN 現況AIKT 現況誰做得更好、為什麼
GitHub repo → 教學文件無此功能(TxGNN 本身不產生教學文件,只有 README)L2 ai-gh-save / L12 gh-tutorial-qd 直接處理AIKT 完勝——這根本不是 TxGNN 的職責範圍,TxGNN 沒有意圖做這件事,此格嚴格說不算真正的功能重疊,只是本教學文件本身就是 AIKT 能力的展示
知識圖譜索引/查詢有完整的異質知識圖譜(PrimeKG 衍生),但查詢介面是程式 API,非自然語言L4 graphify 建構的是「AIKT 自身文件庫」的圖譜索引,規模與領域完全不同(AIKT 索引的是研究筆記/程式碼,不是生物醫學實體)不算真正重疊——兩者的知識圖譜服務對象(生物醫學實體 vs. 個人知識庫文件)完全不同,規模差三個量級(TxGNN 數萬節點 vs. AIKT 個人知識庫節點數)
生成候選假設清單TxGNN 的核心產出正是這個AIKT 的 research-pipeline-v2 (L18) 也能透過文獻搜尋 + LLM 推理「生成候選假設」TxGNN 更好——TxGNN 的假設有量化的圖結構證據支撐(AUPRC 可驗證),AIKT 的 LLM 式假設生成缺乏這種可驗證的統計基礎,容易產生看似合理但缺乏結構性證據的幻覺 (hallucination; 幻覺) 候選
解釋性/證據呈現GraphMask 產生邊層級重要性分數,是結構化、可重現的解釋AIKT 目前沒有對應的「證據權重量化」機制,文獻驗證多是文字摘要式的TxGNN 更好——這是 TxGNN 論文的核心賣點(人本中心設計),AIKT 現有的知識組織層(graphify/NotebookLM)提供的是「文件關聯」而非「因果/機制層級的證據權重」

市場定位衝突判斷:整體而言,不存在真正意義上的市場定位衝突。TxGNN 是領域專精的科學計算工具(graph ML 演算法研究),AIKT 是通用的知識工作流編排系統。唯一容易被誤解為「重疊」的地方是兩者都可以產出「候選藥物/研究假設清單」,但產生機制的本質完全不同——一個是基於圖神經網路的結構化統計推論,另一個是基於 LLM 的文獻綜合推理。這兩種機制互補,而非互斥,這正是藍海策略的立足點。

用一張定位象限圖來呈現 TxGNN 與 AIKT 各層在「證據結構化程度」與「知識工作流整合廣度」兩個維度上的相對位置,可以更直觀地看出兩者為何是互補而非競爭:


quadrantChart
    title "證據結構化程度 vs 工作流整合廣度"
    x-axis "工作流整合廣度低" --> "工作流整合廣度高"
    y-axis "證據結構化程度低" --> "證據結構化程度高"
    quadrant-1 "深耕型工具"
    quadrant-2 "理想整合區"
    quadrant-3 "待補強區"
    quadrant-4 "廣度優先工具"
    TxGNN 本體: [0.20, 0.90]
    GraphMask 解釋輸出: [0.25, 0.85]
    L9 paper-search: [0.70, 0.45]
    L10 paper-qa-lite: [0.55, 0.55]
    L18 research-pipeline-v2: [0.80, 0.50]
    L19 tu-plan-generator: [0.75, 0.40]
    純 LLM 假設生成: [0.60, 0.15]
    AIKT 整合閉環-理想態: [0.85, 0.75]

從象限圖可以看出,TxGNN 本體落在「證據結構化程度高、工作流整合廣度低」的象限——這正是它作為專精科學計算工具的合理位置,不需要也不應該勉強往右移動(那不是它的專業)。而 AIKT 現有各層則普遍落在「整合廣度較高、但證據結構化程度中等」的區域。真正的機會缺口是右上角的「理想整合區」——這正是 §6.3 藍海策略要填補的空白,也是純 LLM 式假設生成(左下角,兩個維度都偏低)明顯不該被拿來取代 TxGNN 的視覺化證據。

6.3 藍海策略 (Blue Ocean Strategy):AIKT 的獨特切入機會

a) 此 repo 未滿足的需求

TxGNN 有三個明顯的「最後一哩路」缺口,全部是 AIKT 現有層級可以直接補上的:

  1. 候選藥物的文獻可信度驗證缺口:TxGNN 輸出一份排序好的候選藥物清單,但完全不會自動去檢查「這個候選藥物是否已有其他獨立證據支持」。研究者拿到清單後,必須手動一個個去查文獻——這正是 paper-search (L9) + paper-qa-lite (L10) 的拿手好戲。
  2. 跨研究批次管理缺口:TxGNN 本身沒有任何機制記錄「我上次對哪個疾病領域跑過篩選、參數是什麼、結果存在哪裡」。研究者若同時篩選 9 個疾病領域(如 §5.3 範例),管理這些實驗記錄、比較歷史結果的負擔全部落在使用者身上——這正是 graphify (L4) 知識圖譜索引 + research-pipeline-v2 (L18) 多輪研究管理的專長。
  3. 從假設到行動計畫的斷層:TxGNN 給出「候選藥物 X 對疾病 Y 可能有效」的假設之後,完全沒有下一步——沒有工具幫忙規劃「如果要驗證這個假設,該做什麼樣的實驗/申請流程」。這正是 tu-plan-generator (L19) 「藥物開發計畫生成」的定位。

b) 創造新價值的整合機會

真正的藍海不是「重做 TxGNN 已經做好的事」,而是把 TxGNN 的結構化輸出接上 AIKT 的知識工作流,形成一個 TxGNN 自己永遠不會做、但對研究者極有價值的閉環

1TxGNN 候選清單 → 自動文獻交叉驗證 → 排除已被否證的候選 → 對存活候選產生開發計畫 → 生成給臨床/內部決策者的簡報

這條閉環的每一段都是 AIKT 現有層級的組合,不需要新建任何演算法能力,純粹是編排。

c) 互補的 AIKT 層級

AIKT 層級在此整合中的角色
L9 paper-search對 TxGNN 輸出的每個候選藥物-疾病配對,跨 10+ 學術資料庫檢索是否已有支持/反對證據
L10 paper-qa-lite若研究者已有本地文獻庫(例如某疾病領域的系統性文獻收集),針對候選藥物做本地 RAG 問答
L18 research-pipeline-v2多輪迭代:TxGNN 初篩 → 文獻驗證 → 依信度分級 → 三輪迭代收斂到高信度候選子集
L19 tu-plan-generator對存活的高信度候選,產生 ADMET/安全性評估 + 藥物開發計畫草案
L7 quarkdown / L11 kami把整個篩選+驗證+計畫流程編譯成給臨床合作方或內部決策層看的正式報告

d) 具體的差異化策略

AIKT 不應該、也不可能重做 TxGNN 的圖神經網路訓練邏輯——這需要深厚的 geometric deep learning 專業知識與大量計算資源,不是知識工作流編排系統的能力範圍。AIKT 的差異化定位應該鎖定在:

  • 「圖神經網路輸出 → 人類可信、可行動的研究產出」的最後一哩路自動化,這是 TxGNN 論文明確承認自己不擅長(TxGNN 有 GraphMask 提供結構化解釋,但沒有文獻層級的外部驗證機制)、也不打算做的部分。
  • 多個知識圖譜藥物發現工具的橫向整合入口:TxGNN 只是這類工具中的一個(MIMS Lab 生態系裡至少還有其他知識圖譜相關工作)。AIKT 若能建立一個統一的「圖神經網路候選清單 → 驗證 → 報告」管線模板,未來遇到其他類似輸出格式的工具(新論文、新模型)時,可以複用同一套整合邏輯,而不必每次重新設計。

6.4 推薦整合方案

核心判斷:不建議把 TxGNN 的模型訓練/推論邏輯內嵌進 AIKT 的任何現有層,也不建議新開一個 Layer 專門跑 TxGNN 訓練(這違反 AIKT「編排知識,不是演算法」的核心定位,且 DGL 0.5.2 這種舊版相依對 AIKT 現有 Python 工具鏈是額外負擔)。

推薦的整合路徑分三階段

階段一(文件化,低成本,立即可做):把本篇教學文件收錄進 inbox/,作為研究者理解 TxGNN 方法論的參考資料。當研究者需要用到 TxGNN 時,可以直接查閱這份文件而不需要重新啃一次原始 README,這是 L2 ai-gh-save 最基本、也最無風險的價值。

階段二(工作流串接,中等成本,建議下個研究週期評估):在 research-pipeline-v2 (L18) 或新建一個輕量腳本中,定義一個「TxGNN 輸出接文獻驗證」的標準格式約定——約定 TxGNN 產出的候選清單應該用什麼欄位格式(藥物名稱、疾病名稱、AUPRC 分數、GraphMask 證據摘要)存成 CSV/JSON,讓 paper-search / paper-qa-lite 可以直接讀取批次查詢,不需要每次手動轉換格式。這一步的產出是一個格式規範文件 + 一支轉接腳本,而不是把 TxGNN 訓練邏輯搬進 AIKT。

階段三(進階閉環,需先驗證階段二的實際使用需求後再評估):若團隊確實有持續性的藥物再利用篩選需求(例如針對特定罕見病領域的長期研究專案),可以評估是否值得在 research-pipeline-v2 中新增一個「圖神經網路候選驗證」的子流程範本,把 §6.3 提到的閉環(初篩 → 驗證 → 分級 → 計畫產生 → 報告編譯)固化成可重複執行的標準作業程序 (SOP)。這一步涉及新增研究方法論,屬於「兩個合理方案的抉擇會影響後續工作流」的必停必問情境,實施前應與研究團隊確認優先順序,不宜由單次任務自行決定。

不建議的整合方向:不建議嘗試用 AIKT 的 LLM 式推理去「模擬」或「取代」TxGNN 的圖神經網路推論——如前述紅海分析,LLM 推理缺乏 TxGNN 具備的結構化統計證據基礎,若用 LLM 生成看似合理的藥物再利用假設而缺乏圖結構驗證,在生醫場景下的幻覺風險遠高於一般文字任務,不應該作為 TxGNN 的替代品,只能作為互補的文獻驗證工具。

6.5 三階段整合方案的時程與成本評估

把 §6.4 的三階段整合方案,用時程/成本/風險三個維度攤開來看,方便研究團隊評估投入優先順序:

階段預估工作量需要的新能力風險等級觸發時機
一:文件化數小時(本文件即為產出)無,完全用現有 L2/L9 能力極低立即可做,無需額外核准
二:格式規範 + 轉接腳本1-2 個工作日定義候選清單的標準 schema;撰寫一支格式轉換腳本低——不觸碰機密邊界、不改動核心架構建議在下一個有實際藥物再利用篩選需求的研究週期評估啟動
三:SOP 固化的驗證閉環依複雜度數週不等在 research-pipeline-v2 新增子流程範本;可能需要新的中間資料格式規範中——涉及新增研究方法論,屬於必停必問情境需先確認階段二有持續性使用需求後才評估,且需與研究團隊明確討論優先順序

6.6 整合方案的風險與緩解措施

即便階段一、二風險低,仍有幾點在實作前值得注意:

  1. 文獻驗證結果不應該被誤讀為「已證實」:paper-search / paper-qa-lite 找到的支持性文獻,本質上仍是相關性證據的補強,不是臨床驗證。轉接腳本與後續報告產出時,措辭上需要清楚區分「TxGNN 統計預測」「文獻佐證程度」「臨床驗證狀態」三個不同層級的確定性,避免報告使用者混淆。
  2. DGL 版本問題可能隨時間惡化:若三階段整合方案要長期維運,需要有人定期確認 TxGNN 上游是否更新了相依版本(例如遷移到更新的 DGL),否則環境重建的難度會隨著時間推移而增加,這是純外部依賴帶來的維運成本,不是 AIKT 可以控制的變數。

7. 效能、限制與替代方案 (Performance, Limitations & Alternatives)

7.1 效能數據與基準測試

根據論文與 README 提供的資訊,TxGNN 在論文的系統性零樣本切分(complex_disease)下,於疾病中心式評估 (disease-centric evaluation) 上取得優於當時多個基準模型(包括傳統的知識圖譜嵌入方法如 TransE、RotatE,以及未特別設計零樣本機制的一般 GNN 連結預測基線)的表現,尤其是在訓練集中完全沒有正樣本的零樣本疾病子集上優勢最明顯——這正是度量學習模組被設計出來要解決的場景,也是論文的核心貢獻聲稱。需要注意的是,具體的數值指標(AUPRC/AUROC 絕對數字)會隨切分策略、隨機種子、超參數設定而變動,若要引用具體數字做決策,應直接查閱論文原文的表格,而非依賴二手轉述。

在計算效能方面,兩階段訓練中預訓練階段(對全圖所有邊型做連結預測)通常是耗時的主要來源,因為要處理的邊數遠多於細調階段只關注的 3+3 種藥物-疾病關係邊;細調階段本身相對輕量,但如果啟用 protein_random_walk 相似度度量,初始化階段建構所有疾病的隨機漫步剖面會顯著拖慢起始時間。

7.2 已知限制

  1. 舊版依賴鎖定:DGL 0.5.2 這個版本發布於 2020 年前後,已經是相對過時的函式庫版本,且與更新的 PyTorch/CUDA 生態系相容性需要仔細對齊,長期維護風險較高(若原作者不持續更新相容性,未來在新硬體/新驅動上安裝會越來越困難)。
  2. DistMult 打分函數的對稱性假設:如 §2.6 所述,DistMult 本質上假設關係對稱,這對「藥物治療疾病」這種方向性明確的關係並非完全貼合的建模假設,儘管用反向邊部分緩解了這個問題。
  3. BERT 相似度選項依賴寫死路徑sim_measure='bert''profile+bert' 選項在原始碼中依賴原作者的 HPC 叢集絕對路徑(/n/scratch3/users/k/kh278/...),這代表這個功能對一般使用者實質上不可直接使用,除非自行重新產生 BERT 嵌入並修改程式碼。
  4. 零樣本能力仍依賴「有相似疾病存在」的假設:度量學習模組的前提是「知識圖譜中存在與目標疾病相似的其他疾病」。如果目標疾病在生物學上極度獨特、找不到任何相似疾病(相似度矩陣中的最高分都很低),模型的零樣本預測品質會明顯下降——這是方法論的根本限制,不是實作瑕疵。
  5. 知識圖譜資料本身的時效性:TxGNN 依賴的 PrimeKG 衍生資料是特定時間點的快照,生物醫學知識(尤其是新興的藥物-疾病關聯研究)持續更新,若知識圖譜沒有定期更新,模型的預測會逐漸偏離最新的科學認知。
  6. 臨床採用門檻:儘管有 GraphMask 解釋性模組,模型輸出終究是統計相關性層級的假設,不能取代嚴謹的臨床前驗證與臨床試驗,論文與 README 都沒有宣稱這是可以直接用於處方決策的工具。

7.3 與同類工具比較

工具/方法核心方法零樣本能力解釋性部署便利度
TxGNN異質 GNN + 度量學習有專門設計的機制(本文核心)有 GraphMask 結構化解釋中(DGL 0.5.2 相依較重)
傳統知識圖譜嵌入 (TransE/RotatE 等)張量分解式嵌入弱(零度節點基本無法推論)高(實作簡單)
化學結構相似度打分 (如 Tanimoto 相似度)分子指紋比對中(不需疾病訓練標籤,但忽略疾病層級的圖結構資訊)中(結構相似性本身可解釋)
純 LLM 式假設生成(如用大型語言模型直接問「哪些藥可能治療 X 病」)語言模型的隱式知識表面上「零樣本」,但缺乏結構化證據低(幻覺風險高,難以追溯依據)極高(幾乎零安裝成本)

7.4 何時使用 vs 何時不使用

適合使用 TxGNN 的情境

  • 研究對象是罕見病或分子機制研究不足的疾病,且需要系統性、可重現的候選藥物篩選;
  • 團隊具備 GPU 資源與圖神經網路相關的工程能力,能承擔 DGL 舊版依賴的維護成本;
  • 需要結構化、可追溯的解釋(而非純粹的黑盒分數)來說服臨床合作方或審查委員會;
  • 目標是產生假設供後續實驗/文獻驗證,而非直接的臨床決策。

不適合使用 TxGNN 的情境

  • 目標疾病資料充足、已有大量已知治療藥物——此時傳統的監督式學習方法(甚至更簡單的統計方法)可能已經足夠,不需要 TxGNN 專門為零樣本情境設計的複雜度;
  • 團隊沒有 GPU 資源或不熟悉 DGL/PyTorch 生態系,且訓練/維護成本超出專案時程許可;
  • 需要的是分子層級(原子/化學結構)的性質預測而非疾病-藥物關係層級的預測——這種情境應該用 ChemBERTa、分子指紋方法或分子性質預測 GNN,而非 TxGNN;
  • 只是想要「快速產生一份候選藥物腦力激盪清單」,不需要結構化證據支撐——這種情境用 LLM 式的假設生成配合文獻搜尋可能更省時間,只是需要更謹慎地標註這類輸出的不確定性。

7.5 重現論文結果的實務建議

若目標是重現論文中的量化結果(而非只是拿來做探索性篩選),需要注意幾件事:

  1. 使用 reproduce/ 目錄下的官方腳本:repo 中的 reproduce/train.pyreproduce/run_txgnn.sh 是作者提供的重現實驗腳本,包含論文報告數字所使用的完整超參數設定,比自行從 README 範例拼湊參數更可靠。
  2. 固定隨機種子並多次重複TxData.prepare_split(seed=42) 只固定了資料切分的隨機性,模型初始化與訓練過程中仍有其他隨機性來源(如 dropout、批次抽樣順序),論文報告的數字通常是多次重複實驗的平均值,單次執行結果會有一定波動,不應該用單次結果直接與論文數字比較。
  3. 注意 reproduce/result_more_metrics.csv:這個檔案是作者提供的參考結果,可以用來對照自己重現的結果是否落在合理範圍內,是驗證環境設定是否正確的實用捷徑。
  4. 疾病領域切分的結果變異較大:由於 9 個疾病領域切分各自的疾病數量、圖結構稀疏程度不同,跨領域的效能數字不能直接比較高低——領域 A 分數低於領域 B,不代表模型在領域 A「表現較差」,也可能只是領域 A 本身零樣本推論的難度天生更高。

8. 總結與建議 (Summary & Recommendations)

8.1 關鍵要點回顧

TxGNN 是 Harvard MIMS Lab 針對「零樣本藥物再利用預測」這個高價值但技術上棘手的問題,提出的一套完整解決方案。它的核心創新可以濃縮成三句話:

  1. 用異質知識圖譜的多跳結構,捕捉傳統統計方法看不到的間接生物學關聯
  2. 用度量學習模組,把「完全沒有直接證據的零樣本疾病」轉化為「向相似疾病借用訊號的少樣本問題」,這是整個方法論最核心的技術貢獻;
  3. 用 GraphMask 解釋性模組,讓黑盒子的圖神經網路預測變成臨床醫師可以檢視、可以質疑的結構化證據,體現了論文標題中「clinician centered design」的實踐承諾。

從工程角度看,TxGNN 是一個相對成熟、有清晰 API 設計(TxDataTxGNNTxEval 三段式)的研究型套件,但也帶著典型學術程式碼的技術債(DGL 舊版鎖定、部分功能依賴寫死的叢集路徑),使用前需要對這些限制有清楚認知。

8.2 最佳使用場景總結

TxGNN 最有價值的落地場景,是研究機構或製藥公司內部的罕見病/未滿足醫療需求 (unmet medical need; 未滿足醫療需求) 篩選團隊——這類團隊通常同時具備:(1) 對特定疾病領域的臨床/生物學專業知識,可以對模型輸出做合理性判斷;(2) 基本的機器學習工程能力,可以處理 DGL/PyTorch 環境;(3) 後續驗證候選假設的文獻研究或濕實驗室 (wet lab; 濕實驗室) 資源。三者缺一,TxGNN 的價值都會打折——沒有臨床判斷,篩選結果無法被合理篩選;沒有工程能力,連環境都裝不起來;沒有後續驗證資源,篩選出的假設只能停留在紙上。

8.3 對 AIKT 使用者的具體建議

若你在 AIKT 環境中遇到需要藥物再利用/罕見病篩藥的研究需求:

  1. 先用 gh-save (L2) 或本篇教學文件,理解 TxGNN 的方法論邊界,避免把它當成萬能的「輸入疾病名稱、輸出正確答案」黑盒子;
  2. 在獨立的 conda 環境中執行 TxGNN 本身的訓練/推論,不要嘗試把它塞進 AIKT 的主要工具鏈——這是刻意的架構決策,保持 AIKT「編排」與「演算法執行」的清晰分工;
  3. 把 TxGNN 的輸出(候選清單)當作研究工作流的「輸入」,而非「輸出」——真正有價值的下一步,是接上 paper-search (L9) / paper-qa-lite (L10) 做文獻交叉驗證,讓假設經得起檢驗;
  4. 謹慎對待解釋性輸出:GraphMask 的邊重要性分數是「模型認為重要」,不等於「生物學上確實重要」,仍需要領域專家判斷。

8.4 未來發展方向

從整個知識圖譜藥物發現領域的演進趨勢來看,幾個值得關注的方向包括:(1) 知識圖譜本身的持續更新機制——PrimeKG 這類靜態快照式的知識圖譜終究需要有更新策略,否則預測品質會隨時間退化;(2) 多模態融合——把分子結構層級的表徵(如 ChemBERTa 類方法)與疾病-藥物關係層級的圖結構表徵融合,可能進一步提升零樣本場景下的表現;(3) 解釋性方法的標準化——GraphMask 只是圖神經網路解釋性方法中的一種,隨著這個子領域的發展,未來可能出現對臨床醫師更友善的解釋呈現方式;(4) 對於 AIKT 這類知識工作流系統而言,隨著越來越多結構化科學計算工具(不只 TxGNN,還包括同類的知識圖譜藥物發現模型)產出格式逐漸趨同,建立一套通用的「科學計算輸出 → 文獻驗證 → 決策報告」整合範本,會是比針對單一工具做深度整合更具長期槓桿效益的投資方向。

8.5 使用前自我檢查清單

在真正投入時間安裝與訓練 TxGNN 之前,建議先用以下清單快速自我確認,避免投入成本後才發現方向不合適:

  • 我的研究問題是否真的屬於「零樣本」情境(目標疾病在現有資料中完全沒有已知治療藥物),而不是「資料稍少但仍有一些已知治療」的一般少樣本情境?(若是後者,一般監督式方法可能已經足夠)
  • 我是否有 GPU 資源,或至少能接受 CPU 訓練的較長等待時間?
  • 我是否能接受 DGL 0.5.2 這種舊版相依帶來的環境維護成本,或已規劃用容器化方式隔離這個風險?
  • 我是否已經準備好「候選藥物清單產出之後」的下一步驗證資源(文獻查證、領域專家複核、甚至濕實驗室驗證)?
  • 我是否清楚 TxGNN 的輸出是統計相關性層級的假設,而非可以直接採用的臨床結論?
  • 若涉及特定罕見病領域的長期研究計畫,我是否已經考慮好如何用 AIKT 現有層級(paper-search / research-pipeline-v2)去補強 TxGNN 本身不提供的文獻驗證與工作流管理能力?

若以上多數項目的答案是「否」,代表在投入 TxGNN 之前,可能需要先補齊環境、資源或流程規劃,而不是急著開始訓練模型。

8.6 延伸閱讀與相關資源

  • 論文預印本:medRxiv 2023.03.19.23287458——完整的方法論細節、基準比較與消融實驗 (ablation study; 消融實驗) 結果
  • 線上互動查詢:txgnn.org——不寫程式碼也能查詢模型對特定疾病的預測結果與解釋圖
  • 官方 GitHub Notebook:TxGNN_Demo.ipynb——repo 內建的互動式示範,適合初次接觸時對照本文件一起操作
  • PrimeKG 相關資源——理解 TxGNN 底層知識圖譜的建構方法論,是進一步客製化知識圖譜內容(例如加入自有的病人資料)的必要背景知識

8.7 文件版本資訊

本教學文件依據 mims-harvard/TxGNN 倉庫於撰寫當下的 README、原始碼結構(txgnn/ 目錄下的 TxData.pyTxGNN.pyTxEval.pymodel.py)與 setup.py/requirements.txt 內容整理而成。若原始倉庫後續更新了 API 介面或相依版本(例如升級到更新的 DGL 版本),本文件中的程式碼範例可能需要對應調整——建議在實際使用前,先對照當時的 README 確認 API 簽名是否有變動,尤其是 model_initialize()finetune() 的參數清單。

本文件的撰寫目標,是讓一位具備基礎機器學習背景、但未必熟悉知識圖譜或幾何深度學習的研究者,能在讀完之後判斷「這個工具是否適合我的研究問題」,並在判斷適合的情況下,有足夠的操作細節可以直接開始動手,而不需要從零散的 README 片段中自行拼湊完整工作流。