RETAIN est un modèle prédictif interprétable pour les applications de santé. À partir des dossiers des patients, il peut faire des prédictions tout en expliquant comment chaque code médical (codes de diagnostic, codes de médicaments ou codes de procédure) à chaque visite contribue à la prédiction. L’interprétation est possible grâce à l’utilisation du mécanisme d’attention neuronale.
En utilisant RETAIN, vous pouvez calculer la contribution positive/négative de chaque code médical (diagnostic, médicament ou code de procédure) lors de différentes visites au score final. Dans ce cas, nous prédisons si le patient donné recevra un diagnostic d'insuffisance cardiaque (IC). Vous pouvez voir que les codes fortement liés à HF apportent des contributions positives. RETAIN apprend également à accorder plus d’attention aux nouvelles informations qu’aux anciennes. Vous pouvez constater que la dysrythmie cardiaque (CD) apporte une plus grande contribution car elle survient lors de la visite la plus récente.
RETAIN implémente un algorithme présenté dans l'article suivant :
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
L'article RETAIN formule le modèle comme étant capable de faire des prédictions à chaque pas de temps (par exemple, essayer de prédire quels diagnostics le patient recevra à chaque visite) et traite la classification des séquences (par exemple, à partir d'un dossier patient, recevra-t-il un diagnostic d'insuffisance cardiaque dans le futur ?) comme un cas particulier, puisque la classification des séquences effectue la prédiction au dernier pas de temps uniquement.
Ce code est cependant implémenté pour effectuer la tâche de classification de séquence. Par exemple, vous pouvez utiliser ce code pour prédire si le patient donné est un patient souffrant d'insuffisance cardiaque ou non. Ou bien, vous pouvez prédire si ce patient sera réadmis à l’avenir. La version plus générale de RETAIN sera publiée ultérieurement.
ÉTAPE 1 : Installation
Installez Python, Theano. Nous utilisons Python 2.7, Theano 0.8. Theano peut être facilement installé dans Ubuntu comme suggéré ici
Si vous envisagez d'utiliser le calcul GPU, installez CUDA
Téléchargez/clonez le code RETAIN
ÉTAPE 2 : Un moyen rapide de tester RETAIN avec MIMIC-III
Cette étape décrit comment entraîner RETAIN, avec un nombre minimum d'étapes à l'aide de MIMIC-III, pour prédire la mortalité des patients à l'aide de leurs dossiers de visite.
Vous devrez d'abord demander l'accès à MIMIC-III, un dossier de santé électronique accessible au public collecté auprès de patients en soins intensifs sur 11 ans.
Vous pouvez utiliser "process_mimic.py" pour traiter l'ensemble de données MIMIC-III et générer un ensemble de données de formation approprié pour RETAIN. Placez le script au même emplacement où se trouvent les fichiers CSV MIMIC-III et exécutez le script. La commande d'exécution est python process_mimic.py ADMISSIONS.csv DIAGNOSES_ICD.csv PATIENTS.csv <output file>
.
Exécutez RETAIN en utilisant les fichiers ".seqs" et ".morts" générés par process_mimic.py. Le fichier ".seqs" contient la séquence de visites pour chaque patient. Chaque visite comprend plusieurs codes de diagnostic. Cependant, nous vous recommandons d'utiliser plutôt le fichier ".3digitICD9.seqs", car les résultats seront beaucoup plus interprétables. (Ou vous pouvez utiliser le logiciel de classification clinique à un seul niveau pour la CIM9 pour réduire le nombre de codes à quelques centaines, ce qui améliorera encore les performances.) Le fichier ".morts" contient la séquence d'étiquettes de mortalité pour chaque patient. La commande est 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
est le nombre total de codes ICD9 à 3 chiffres utilisés dans l'ensemble de données.
Pour tester l'interprétation du modèle, veuillez vous référer à l'étape 6. J'ai personnellement constaté que l'ictère périnatal (ICD9 774) a une forte corrélation avec la mortalité.
Le modèle atteint une AUC supérieure à 0,8 avec la commande ci-dessus, mais les interprétations ne sont pas très claires. Vous pouvez régler les hyper-paramètres, mais je doute que les choses s'améliorent considérablement. Après tout, seuls 7 500 patients ont effectué plus d’une seule visite à l’hôpital, et la plupart d’entre eux n’ont eu que deux visites.
ÉTAPE 3 : Comment préparer votre propre ensemble de données
L'ensemble de données de formation de RETAIN doit être une liste de listes Python cPickled. La liste la plus externe correspond aux patients, la liste intermédiaire à la séquence de visites effectuée par chaque patient et la liste la plus interne aux codes médicaux (par exemple, codes de diagnostic, codes de médicaments, codes de procédure, etc.) qui ont eu lieu lors de chaque visite. Tout d’abord, les codes médicaux doivent être convertis en nombre entier. Une seule visite peut alors être considérée comme une liste d’entiers. Un patient peut alors être vu sous forme d'une liste de visites. Par exemple, [5,8,15] signifie que les codes 5, 8 et 15 ont été attribués au patient lors d'une certaine visite. Si un patient a effectué deux visites [1,2,3] et [4,5,6,7], il peut être converti en une liste de listes [[1,2,3], [4,5,6,7 ]]. Plusieurs patients peuvent être représentés par [[[1,2,3], [4,5,6,7]], [[2,4], [8,3,1], [3]]], ce qui signifie il y a deux patients où le premier patient a effectué deux visites et le deuxième patient a effectué trois visites. Cette liste de listes doit être sélectionnée à l’aide de cPickle. Nous appellerons ce fichier le « dossier de visite ».
Le nombre total de codes médicaux uniques est requis pour exécuter RETAIN. Par exemple, si l'ensemble de données utilise 14 000 codes de diagnostic et 11 000 codes de procédure, le nombre total est de 25 000.
L'ensemble de données d'étiquette (appelons cela "fichier d'étiquette") doit être une liste Python cPickled. Chaque élément correspond à la véritable étiquette de chaque patient. Par exemple, 1 peut être le patient cas et 0 peut être le patient témoin. S'il y a deux patients pour lesquels seul le premier patient est un cas, alors nous devrions avoir [1,0].
Le « fichier de visite » et le « fichier d'étiquettes » doivent avoir respectivement 3 ensembles : ensemble de formation, ensemble de validation et ensemble de test. L'extension du fichier doit être respectivement ".train", ".valid" et ".test".
Par exemple, si vous souhaitez utiliser un fichier nommé « my_visit_sequences » comme « fichier de visite », alors RETAIN essaiera de charger « my_visit_sequences.train », « my_visit_sequences.valid » et « my_visit_sequences.test ».
Ceci est également vrai pour le "fichier d'étiquettes"
Vous pouvez utiliser les informations horaires concernant les visites comme source d’informations supplémentaire. Appelons cela « fichier temporel ». Notez que les informations temporelles peuvent être n'importe quoi : durée entre des visites consécutives, nombre cumulé de jours depuis la première visite, etc. Le "fichier horaire" doit être préparé sous la forme d'une liste de listes Python cPickled. La liste la plus externe correspond aux patients, et la plus interne aux informations horaires de chaque visite. Par exemple, étant donné un "fichier de visite" [[[1,2,3], [4,5,6,7]], [[2,4], [8,3,1], [3]]] , son "fichier temporel" correspondant pourrait ressembler à [[0, 15], [0, 45, 23]], si nous utilisons la durée entre les visites consécutives. (bien sûr, les chiffres sont faux et j'ai fixé la durée de la première visite à zéro.) Utilisez l'option --time_file <path to time file>
pour utiliser "time file". N'oubliez pas que ".train", ". valide", la règle ".test" s'applique également au "fichier temporel".
Supplémentaire : Utilisation de vos propres représentations du code médical
RETAIN apprend en interne la représentation vectorielle des codes médicaux pendant la formation. Ces vecteurs sont bien entendu initialisés avec des valeurs aléatoires.
Toutefois, vous pouvez également utiliser vos propres représentations du code médical, si vous en disposez. (Ils peuvent être formés à l'aide d'algorithmes de type Skip-gram. Reportez-vous à Med2Vec ou à ceci pour plus de détails.) Si vous souhaitez fournir les représentations du code médical, il doit s'agir d'une liste (essentiellement une matrice) de N lignes et M colonnes où N est le nombre de codes uniques dans votre « fichier de visite » et M est la taille des représentations de codes. Spécifiez le chemin d'accès à votre fichier de représentation de code à l'aide de --embed_file <path to embedding file>
. De plus, même si vous utilisez vos propres représentations de code médical, vous pouvez les recycler (c'est-à-dire les affiner) au fur et à mesure que vous entraînez RETAIN. Utilisez l'option --embed_finetune
pour ce faire. Si vous ne fournissez pas vos propres représentations de code médical, RETAIN en utilisera une initialisée de manière aléatoire, ce qui nécessite évidemment ce processus de réglage fin. Puisque la valeur par défaut consiste à utiliser le réglage fin, vous n'avez pas à vous en soucier.
ÉTAPE 4 : Exécuter RETAIN
L'entrée minimale dont vous avez besoin pour exécuter RETAIN est le « fichier de visite », le nombre de codes médicaux uniques dans le « fichier de visite », le « fichier d'étiquettes » et le chemin de sortie. Le chemin de sortie est l’endroit où les poids appris et le journal seront enregistrés.
python retain.py <visit file> <# codes in the visit file> <label file> <output path>
La spécification de l'option --verbose
imprimera le processus de formation après chaque 10 mini-lots.
Vous pouvez spécifier la taille de l'intégration W_emb, la taille de la couche cachée du GRU qui génère l'alpha et la taille de la couche cachée du GRU qui génère la version bêta. Les commandes respectives sont --embed_size <integer>
, --alpha_hidden_dim_size <integer>
et --beta_hidden_dim_size <integer>
. Par exemple --alpha_hidden_dim_size 128
dira à RETAIN d'utiliser un GRU avec une couche cachée à 128 dimensions pour générer de l'alpha.
Les abandons sont appliqués à deux endroits : 1) à l'intégration d'entrée, 2) au vecteur de contexte c_i. Les taux d'abandon respectifs peuvent être ajustés en utilisant --keep_prob_embed {0.0, 1.0}
et --keep_prob_context {0.0, 1.0}
. Les valeurs d'abandon affectent les performances, il est donc recommandé de les ajuster en fonction de vos données.
Les régularisations L2 peuvent être appliquées à W_emb, w_alpha, W_beta et w_output.
Des options supplémentaires peuvent être spécifiées telles que la taille du lot, le nombre d'époques, etc. Des informations détaillées sont accessibles via python retain.py --help
Ma recommandation personnelle : utilisez une régularisation légère (0,0001 ~ 0,001) sur les quatre poids et utilisez un abandon modéré sur le vecteur de contexte uniquement. Mais cela dépend entièrement de vos données, vous devez donc toujours régler les hyperparamètres vous-même.
ÉTAPE 5 : Obtenir vos résultats
RETAIN vérifie l'AUC de l'ensemble de validation après chaque époque, et si elle est supérieure à toutes les valeurs précédentes, il enregistrera le modèle actuel. Le fichier modèle est généré par numpy.savez_compressed.
Étape 6 : tester votre modèle
A l'aide du fichier "test_retain.py", vous pouvez calculer les contributions de chaque code médical à chaque visite. Vous devez d’abord disposer d’un modèle entraîné qui a été enregistré par numpy.savez_compressed. Notez que vous devez connaître la configuration avec laquelle vous avez entraîné RETAIN (par exemple, utilisation de --time_file
, utilisation de --use_log_time
.)
Encore une fois, vous avez besoin du « dossier de visite » et du « dossier d’étiquette » préparés de la même manière. Cette fois, cependant, vous n'avez pas besoin de suivre la règle ".train", ".valid", ".test". Le script de test tentera de charger le nom de fichier tel qu'indiqué.
Vous avez également besoin des informations de mappage entre les codes médicaux de chaîne réels et leurs codes entiers. (par exemple, "Hypertension" est mappé à 24) Ce fichier (appelons ce "fichier de mappage") doit être un dictionnaire Python cPickled où les clés sont les codes médicaux de chaîne et les valeurs sont les entiers correspondants. (par exemple, le fichier de mappage généré par process_mimic.py est le fichier ".types") Ce fichier est nécessaire pour imprimer les contributions de chaque code médical dans un format convivial.
Pour les options supplémentaires telles que --time_file
ou --use_log_time
, vous devez utiliser exactement la même configuration avec laquelle vous avez entraîné le modèle. Pour des informations plus détaillées, utilisez l'option "--help".
L'entrée minimale pour exécuter le script de test est le « fichier modèle », le « fichier de visite », le « fichier d'étiquette », le « fichier de mappage » et le « fichier de sortie ». Le "fichier de sortie" est l'endroit où les contributions seront stockées. python test_retain.py <model file> <visit file> <label file> <mapping file> <output file>