RETAIN 是一種用於醫療保健應用的可解釋的預測模型。根據患者記錄,它可以做出預測,同時解釋每次就診時的每個醫療代碼(診斷代碼、藥物代碼或程序代碼)如何對預測做出貢獻。由於神經注意機制的使用,這種解釋是可能的。
使用 RETAIN,您可以計算每個醫療代碼(診斷、藥物或手術代碼)在不同就診時對最終得分的正面/負面影響。在本例中,我們正在預測給定患者是否會被診斷為心臟衰竭 (HF)。可以看到與HF高度相關的程式碼做出了積極的貢獻。 RETAIN 也學會了更專注於新資訊而不是舊資訊。您可以看到心律不整 (CD) 的貢獻更大,因為它發生在最近的訪問中。
RETAIN 實作了以下論文中介紹的演算法:
RETAIN: An Interpretable Predictive Model for Healthcare using Reverse Time Attention Mechanism
Edward Choi, Mohammad Taha Bahadori, Joshua A. Kulas, Andy Schuetz, Walter F. Stewart, Jimeng Sun,
NIPS 2016, pp.3504-3512
RETAIN 論文將模型製定為能夠在每個時間步進行預測(例如,嘗試預測患者每次就診時將收到什麼診斷),並處理序列分類(例如,給定患者記錄,他會在以下時間被診斷為心臟衰竭)未來?
然而,該程式碼是為了執行序列分類任務而實現的。例如,您可以使用此代碼來預測給定患者是否為心臟衰竭患者。或者您可以預測該患者將來是否會再次入院。更通用的 RETAIN 版本將在未來發布。
第 1 步:安裝
安裝Python、Theano。我們使用Python 2.7,Theano 0.8。按照此處的建議,Theano 可以輕鬆安裝在 Ubuntu 中
如果您打算使用 GPU 運算,請安裝 CUDA
下載/克隆 RETAIN 程式碼
第 2 步:使用 MIMIC-III 測試 RETAIN 的快速方法
此步驟描述如何使用 MIMIC-III 以最少的步驟訓練 RETAIN,以使用患者的就診記錄預測患者的死亡率。
您首先需要要求訪問 MIMIC-III,這是從 11 年來從 ICU 患者收集的公開電子健康記錄。
您可以使用「process_mimic.py」來處理 MIMIC-III 資料集並為 RETAIN 產生適當的訓練資料集。將腳本放置到 MIMIC-III CSV 檔案所在的相同位置,然後執行該腳本。執行指令為python process_mimic.py ADMISSIONS.csv DIAGNOSES_ICD.csv PATIENTS.csv <output file>
。
使用 process_mimic.py 產生的「.seqs」和「.morts」檔案執行 RETAIN。 「.seqs」文件包含每位患者的就診順序。每次就診都包含多個診斷代碼。不過,我們建議使用「.3digitICD9.seqs」文件,因為結果將更容易解釋。 (或者您可以使用 ICD9 的單級臨床分類軟體將代碼數量減少到數百個,這將進一步提高效能)「.morts」檔案包含每個患者的死亡標籤序列。指令為python retain.py <3digitICD9.seqs file> 942 <morts file> <output path> --simple_load --n_epochs 100 --keep_prob_context 0.8 --keep_prob_emb 0.5
。 942
是資料集中使用的完整 3 位元 ICD9 代碼的數量。
要測試模型的解釋,請參考步驟6。
使用上述指令,模型的 AUC 達到 0.8 以上,但解釋不是非常清楚。你可以調整超參數,但我懷疑事情會顯著改善。畢竟,只有 7,500 名患者曾多次到醫院就診,而且大多數人只就診過兩次。
第 3 步:如何準備自己的資料集
RETAIN的訓練資料集需要是一個Python cPickled list of list of list。最外面的列表對應於患者,中間的列表對應於每個患者進行的就診順序,最裡面的列表對應於每次就診中發生的醫療代碼(例如診斷代碼、藥物代碼、程序代碼等)。首先,醫療代碼需要轉換為整數。那麼單次存取就可以看成是整數列表。然後可以將患者視為就診清單。例如,[5,8,15] 表示患者在某次就診時被分配了代碼 5、8 和 15。如果病人兩次就診[1,2,3]和[4,5,6,7],可以轉換為清單[[1,2,3],[4,5,6,7] ]] 。多位患者可表示為[[[1,2,3], [4,5,6,7]], [[2,4], [8,3,1], [3]]],這意味著有兩名患者,第一個患者就診兩次,第二個患者就診三次。這個清單清單需要使用 cPickle 進行醃製。我們將此文件稱為「存取文件」。
運行 RETAIN 需要唯一醫療代碼的總數。例如,如果資料集使用 14,000 個診斷代碼和 11,000 個程式代碼,則總數為 25,000。
標籤資料集(我們稱為「標籤檔案」)需要是一個 Python cPickled 清單。每個元素對應於每個患者的真實標籤。例如,1 可以是病例患者,0 可以是對照組患者。如果有兩個患者,而只有第一個患者是病例,那麼我們應該有[1,0]。
「存取文件」和「標籤檔案」分別需要有3組:訓練集、驗證集和測試集。檔案副檔名必須分別為「.train」、「.valid」和「.test」。
例如,如果要使用名為“my_visit_sequences”的檔案作為“存取檔案”,則 RETAIN 將嘗試載入“my_visit_sequences.train”、“my_visit_sequences.valid”和“my_visit_sequences.test”。
對於“標籤文件”也是如此
您可以使用有關訪問的時間資訊作為附加資訊來源。我們稱之為「時間文件」。請注意,時間資訊可以是任何內容:連續訪問之間的持續時間、自第一次訪問以來的累積天數等。最外面的列表對應於患者,最裡面的是每次就診的時間資訊。例如,給定一個「存取文件」 [[[1,2,3], [4,5,6,7]], [[2,4], [8,3,1], [3]]] ,如果我們使用連續存取之間的持續時間,則其對應的「時間文件」可能類似於[[0, 15], [0, 45, 23]]。 (當然這些數字是假的,我已將第一次訪問的持續時間設為零。)使用--time_file <path to time file>
選項來使用“時間文件” 請記住“.train”、“. valid 」、「.test」規則也適用於「時間文件」。
附加:使用您自己的醫療代碼表示
RETAIN 在訓練時內部學習醫療程式碼的向量表示。當然,這些向量是用隨機值初始化的。
不過,如果您有醫療代碼表示形式,您也可以使用自己的醫療代碼表示形式。 (可以使用Skip-gram 之類的演算法來訓練它們。有關更多詳細信息,請參閱Med2Vec 或此。)如果您想提供醫療代碼表示形式,它必須是N 行列表(基本上是矩陣)的列表,且M 列,其中 N 是「存取檔案」中唯一代碼的數量,M 是代碼表示的大小。使用--embed_file <path to embedding file>
指定程式碼表示檔案的路徑。此外,即使您使用自己的醫療代碼表示,您也可以在訓練 RETAIN 時重新訓練(也稱為微調)它們。使用--embed_finetune
選項來執行此操作。如果您不提供自己的醫療代碼表示形式,RETAIN 將使用隨機初始化的表示形式,這顯然需要這一微調過程。由於預設是使用微調,因此您無需擔心這一點。
第 4 步:運行 RETAIN
執行 RETAIN 所需的最小輸入是「存取檔案」、「存取檔案」中唯一醫療代碼的數量、「標籤檔案」和輸出路徑。輸出路徑是保存學習到的權重和日誌的位置。
python retain.py <visit file> <# codes in the visit file> <label file> <output path>
指定--verbose
選項將在每 10 個小批量後列印訓練過程。
您可以指定嵌入 W_emb 的大小、產生 alpha 的 GRU 隱藏層的大小以及產生 beta 的 GRU 隱藏層的大小。對應的指令是--embed_size <integer>
、 --alpha_hidden_dim_size <integer>
和--beta_hidden_dim_size <integer>
。例如--alpha_hidden_dim_size 128
將告訴 RETAIN 使用具有 128 維隱藏層的 GRU 來產生 alpha。
Dropout 套用於兩個位置:1)輸入嵌入,2)上下文向量 c_i。可以使用--keep_prob_embed {0.0, 1.0}
和--keep_prob_context {0.0, 1.0}
調整各自的遺失率。 Dropout 值會影響效能,因此建議根據您的資料調整它們。
L2 正規化可應用於 W_emb、w_alpha、W_beta 和 w_output。
可以指定其他選項,例如批量大小的python retain.py --help
、epoch 的數量等。
我個人的建議:對所有四個權重使用輕度正則化(0.0001 ~ 0.001),並僅對上下文向量使用適度的 dropout。但這完全取決於您的數據,因此您應該始終自行調整超參數。
第 5 步:取得結果
RETAIN 在每個 epoch 後檢查驗證集的 AUC,如果它高於所有先前的值,它將保存當前模型。模型檔案由numpy.savez_compressed產生。
第 6 步:測試您的模型
使用檔案“test_retain.py”,您可以計算每次就診時每個醫療代碼的貢獻。首先,您需要有一個由 numpy.savez_compressed 保存的經過訓練的模型。請注意,您需要知道訓練 RETAIN 所使用的配置(例如使用--time_file
、使用--use_log_time
。)
同樣,您需要以相同的方式準備“存取文件”和“標籤文件”。不過,這次,您不需要遵循「.train」、「.valid」、「.test」規則。測試腳本將嘗試載入給定的檔案名稱。
您還需要實際字串醫療代碼與其整數代碼之間的映射資訊。 (例如「Hypertension」映射到24)該檔案(我們稱之為「映射檔案」)需要是一個Python cPickled 字典,其中鍵是字串醫療代碼,值是對應的整數。 (例如,process_mimic.py 產生的映射檔案是「.types」檔案)需要此檔案以使用者友好的格式列印每個醫療程式碼的貢獻。
對於諸如--time_file
或--use_log_time
之類的其他選項,您應該使用與訓練模型完全相同的配置。有關更多詳細信息,請使用“--help”選項。
執行測試腳本的最小輸入是「模型檔案」、「存取檔案」、「標籤檔案」、「映射檔案」和「輸出檔案」。 「輸出檔案」是儲存貢獻的地方。 python test_retain.py <model file> <visit file> <label file> <mapping file> <output file>