neuralNet annScore

Prédiction de Réadmission avec Gestion des Données Manquantes

Scénario de test & Cas d'usage

Contexte Métier

Un hôpital cherche à prédire le risque de réadmission d'un patient dans les 30 jours. Les dossiers médicaux sont souvent incomplets. Le test vise à valider le comportement de l'action `annScore` face à des données d'entrée contenant des valeurs manquantes, un cas d'usage très fréquent en santé.
À propos du Set : neuralNet

Entraînement de réseaux de neurones artificiels classiques.

Découvrir toutes les actions de neuralNet
Préparation des Données

Création d'une table de patients avec des données médicales, dont certaines sont volontairement manquantes. Un modèle de prédiction de réadmission est également simulé.

Copié !
1PROC CAS;
2 LOADACTIONSET 'dataStep';
3 LOADACTIONSET 'neuralNet';
4 
5 /* 1. Création des données patients avec valeurs manquantes */
6 ACTION dataStep.runCode / code='
7 data patients_a_scorer_mv (caslib="casuser");
8 call streaminit(99);
9 do id_patient = 1 to 500;
10 age = 40 + int(rand("Uniform") * 45);
11 duree_sejour_j = 2 + rand("Normal", 5, 2);
12 /* Introduction de valeurs manquantes */
13 if rand("Uniform") < 0.2 then score_gravite = .; else score_gravite = 1 + rand("Uniform")*10;
14 if rand("Uniform") < 0.15 then bmi = .; else bmi = rand("Normal", 28, 4);
15 /* La cible est manquante pour certains, pour tester `impute` */
16 if id_patient > 450 then readmission_30j = .; else readmission_30j = (duree_sejour_j > 8 or score_gravite > 8);
17 output;
18 end;
19 run;';
20 
21 /* 2. Entraînement d''un modèle sur des données complètes */
22 ACTION dataStep.runCode / code='
23 data readmission_train_data (caslib="casuser");
24 call streaminit(55);
25 do i = 1 to 1000;
26 age = 40 + int(rand("Uniform") * 45);
27 duree_sejour_j = 2 + rand("Normal", 5, 2);
28 score_gravite = 1 + rand("Uniform")*10;
29 bmi = rand("Normal", 28, 4);
30 readmission_30j = (duree_sejour_j > 8 or score_gravite > 8);
31 output;
32 end;
33 run;';
34 ACTION neuralNet.annTrain /
35 TABLE={name='readmission_train_data', caslib='casuser'},
36 target='readmission_30j',
37 inputs={'age', 'duree_sejour_j', 'score_gravite', 'bmi'},
38 hiddens={15},
39 modelTable={name='model_readmission_nn', caslib='casuser', replace=true};
40QUIT;

Étapes de réalisation

1
Test 1: Scoring en excluant les lignes avec des valeurs manquantes dans les prédicteurs (`includeMissing=false`).
Copié !
1PROC CAS;
2 LOADACTIONSET 'neuralNet';
3 ACTION neuralNet.annScore /
4 TABLE={name='patients_a_scorer_mv', caslib='casuser'},
5 modelTable={name='model_readmission_nn', caslib='casuser'},
6 includeMissing=false,
7 casOut={name='readmission_scores_nomiss', caslib='casuser', replace=true};
8 ACTION TABLE.rowCount / TABLE={name='readmission_scores_nomiss', caslib='casuser'};
9QUIT;
2
Test 2: Scoring en incluant les lignes avec manquants (comportement par défaut). La prédiction sera manquante pour ces lignes.
Copié !
1PROC CAS;
2 ACTION neuralNet.annScore /
3 TABLE={name='patients_a_scorer_mv', caslib='casuser'},
4 modelTable={name='model_readmission_nn', caslib='casuser'},
5 includeMissing=true,
6 casOut={name='readmission_scores_withmiss', caslib='casuser', replace=true};
7 ACTION TABLE.fetch / TABLE={name='readmission_scores_withmiss', caslib='casuser'}, where='_NN_PredName_ is null';
8QUIT;
3
Test 3: Utilisation de `impute=true` pour ne scorer que les patients dont la variable cible `readmission_30j` est manquante.
Copié !
1PROC CAS;
2 ACTION neuralNet.annScore /
3 TABLE={name='patients_a_scorer_mv', caslib='casuser'},
4 modelTable={name='model_readmission_nn', caslib='casuser'},
5 impute=true,
6 casOut={name='readmission_scores_imputed', caslib='casuser', replace=true};
7 ACTION TABLE.rowCount / TABLE={name='readmission_scores_imputed', caslib='casuser'};
8QUIT;

Résultat Attendu


Étape 1: La table `readmission_scores_nomiss` contiendra moins de 500 lignes. Étape 2: La table `readmission_scores_withmiss` contiendra 500 lignes, mais les lignes avec des manquants dans `score_gravite` ou `bmi` auront une prédiction `_NN_PredName_` nulle. Étape 3: La table `readmission_scores_imputed` contiendra 500 lignes, mais seules les 50 dernières (celles avec `readmission_30j` manquant) auront une prédiction calculée par le modèle ; les 450 premières auront leur valeur `readmission_30j` d'origine comme prédiction.