{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![Urgences - Image CC0 - pexels.com](img/pexels-pixabay-263402.jpg \"Urgences\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Biology Order Prescription\n",
    "*Levi-Dan Azoulay*  \n",
    "*Shana Zirah*  \n",
    "*Nathane Berrebi*  \n",
    "*Gaspard André*  \n",
    "*Jona Benhamou*    \n",
    "*Ali Bellamine*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Plan du document"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Les étapes clés de ce projet sont les suivantes :\n",
    "\n",
    "- I. Introduction\n",
    "- II. Téléchargement des données et transformation\n",
    "- III. Exploration et visualisation les données\n",
    "- IV. Sélection des variables d'interêts\n",
    "- V. Définition et entrainement d'une solution d'apprentissage statistique"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# I. Introduction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    " ## I.1 Contexte"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Chaque jour, environ 50 000 personnes se présentent dans un service d'accueil des urgences (SAU) en France. En moyenne, 75% des patients retournent à domicile, et 20% sont hospitalisés. La durée moyenne de présence au SAU est longue. On estime que seulement 20% attendront moins d'une heure, tandis que ~30% attendront entre 1h et 2H et ~30% attendront en 2 et 4H. Enfin, un peu plus de 10% resteront au SAU entre 4 et 6H. Dans un contexte de pénurie de soignants, le recours à la consultation au SAU est en constante augmentation depuis plusieurs années. L'optimisation du circuit des urgences est une problématique centrale. Le cout humain et financier des dysfonctionnements du circuit et de l'offre de soin est important. \n",
    "\n",
    "Le parcours classique du circuit des urgences est le suivant :  \n",
    "1. **Premier contact d'ordre administratif**\n",
    "2. **Premier contact soignant avec une infirmière d'accueil et d'orientation (IAO) (~M30) avec**  :\n",
    "    - Recueil du motif de consultation\n",
    "    - Prise des constantes\n",
    "    - Recueil de quelques antécédents et de l'ordonnance du patient \n",
    "    - Eventuellement ECG  \n",
    "\n",
    "\n",
    "Le patient est classé selon un score de gravité (bleu, vert, jaune, orange, rouge, ou 1-2-3-4-5)\n",
    "\n",
    "3. **Premier contact médical avec un médecin (~H1)** :\n",
    "    - Interrogatoire\n",
    "    - Examen clinique\n",
    "\n",
    "    \n",
    "A la suite de cette consultation, plusieurs cas de figures selon la situation.\n",
    "Le patient peut sortir avec ou sans ordonnance si le diagnostic est posé par l'examen clinique et ne nécéssite ni examen, ni hospitalisation.\n",
    "Le patient peut nécéssiter la réalisation d'examens (prise de sang, radiographie, scanner) ou motiver un avis d'un spécialiste. Auquel cas il doit attendre\n",
    "\n",
    "4. **Réalisation des examens complémentaire ou d'un avis (prescription, réalisation, récupération)**\n",
    "5. **Décision finale : Conclusion une fois les examens récupérés. (~H3)**\n",
    "\n",
    "Entre chaque étape, le patient attend pendant une durée plus ou moins longue. Le médecin lui « jongle » avec plusieurs patients à la fois à des étapes différentes. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# I.2 Objectifs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nous proposons d'aider à **raccourcir le temps entre l'arrivée du patient et sa sortie**, en ne subordonnant pas la décision de réaliser un examen biologique à l'examen clinique du médecin. Nous savons que le temps entre l'arrivée au SAU et la première visite avec le médecin est le temps le plus long et le plus mal vécu par les patients. \n",
    "\n",
    "**Nous proposons à l'aide d'un algorithme d'apprentissage statistique de prédire, dès les données fournies par l'IAO, la nécéssité de réaliser un examen de biologie médicale, afin de permettre aux IDE de prélever cet examen juste après l'IAO, de sorte que le médecin dès sa première visite peut conclure avec les résultats de la biologie, qu'il aurait sans cela, demandé et attendu de récuperer avant de conclure et de prendre en charge le patient.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<table markdown=\"1\">\n",
    "     <TR>\n",
    "       <TH>Données d'entrée</TH>\n",
    "       <TH>Algorithme</TH>\n",
    "       <TH>Données de sortie</TH>\n",
    "     </TR>\n",
    "     <TR>\n",
    "          <TD></TD>\n",
    "          <TD></TD>\n",
    "          <TD>Vecteur {0,1}^d d'examens de biologie associée à sa réalisation (1) ou non (0)</TD>\n",
    "     </TR>\n",
    "     <TR>\n",
    "          <TD>Age</TD>\n",
    "          <TD ROWSPAN=\"6\">MLP<br \\>NLP (Embeddings, Word2Vec ...) <br \\>Autres</TD>\n",
    "          <TD>Ionogramme Complet - {0,1}</TD>\n",
    "     </TR>\n",
    "     <TR>\n",
    "          <TD>Sexe</TD>\n",
    "          <TD>Bilan hépato-biliaire - {0,1}</TD>\n",
    "     </TR>\n",
    "     <TR>\n",
    "          <TD>Motif de consultation</TD>\n",
    "          <TD>Numération sanguine (NFS) - {0,1}</TD>\n",
    "     </TR>\n",
    "     <TR>\n",
    "          <TD>Paramètres vitaux (FC, SpO2, PA, T°, FR, EVA)</TD>\n",
    "          <TD>Glycémie - {0,1}</TD>\n",
    "     </TR>\n",
    "     <TR>\n",
    "          <TD>Ordonnance d'entrée du patient</TD>\n",
    "          <TD>Hémostase - {0,1}</TD>\n",
    "     </TR>\n",
    "     <TR>\n",
    "          <TD></TD>\n",
    "          <TD>...</TD>\n",
    "     </TR>\n",
    "</table>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# I.3 Définition des métriques"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nous proposons d'effectuer la tache suivante : **prédire les examens biologiques qui seront réalisés lors de l'arrivé d'un patient aux urgences**  \n",
    "Les métriques d'évaluation des performances seront :\n",
    "- L'**accuracy**\n",
    "- La **precision**\n",
    "- L'**aire sous la courbe (AUC)**\n",
    "\n",
    "La métrique d'évaluation d'un algorithme de machine learning est particulièrement sensible dans le cadre d'une application médicale. \n",
    "Nous attachons une importance particulière à la **précision**. En effet, une sur-prescription d'examen biologique non indiqué (faux positif) pourrait entrainer un effet contraire à l'effet escompté, en prolongant le temps de prise en charge des personnes concernées, posant, outre un problème financier et un allongement du temps d'attente, un problème éthique."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# II.  Téléchargement des données et transformation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Les données sont issus du projet MIMIC-IV.  \n",
    "Le projet MIMIC est un projet d'open-data médical initié par l'hopital _Beth Israel Deaconess_ à Boston.  \n",
    "Initialement, seul des données de réanimation été accessible.\n",
    "\n",
    "Pour sa 4ème édition, a été mis à disposition un jeu de données couvrant un spectre bien plus large :\n",
    "- Données relatives aux passages aux urgences\n",
    "- Données relatives aux hospitalisations\n",
    "- Données relatives aux séjour en réanimation\n",
    "- Données de radiographie thoracique avec compte rendu associé"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "L'ensemble de ces données ont été mis à disposition dans le cadre de projets complémentaires :\n",
    "- [MIMIC-IV](https://physionet.org/content/mimiciv/0.4/) : hospitalisation et réanimation\n",
    "- [MIMIC-IV-ED](https://physionet.org/content/mimic-iv-ed/1.0/) : urgences\n",
    "- [MIMIC-IV-CXR](https://physionet.org/content/mimic-cxr/2.0.0/) : radiographie thoracique\n",
    "\n",
    "Ces bases sont complémentaires dans le sens où chaque collecte a été faite durant une période temporelle spécifique, qui se recoupe plus où moins.  \n",
    "Certains éléments nécessaires à l'exploitation de MIMIC-IV-ED sont présent dans MIMIC-IV.  \n",
    "La lecture de la documentation de MIMIC-IV et de MIMIC-IV-ED est vivement recommandé (lien ci-dessus).\n",
    "\n",
    "En complément, un certains nombre de ressources est disponible sur le site du projet [MIMIC-IV](https://mimic.mit.edu/)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## II.1 Téléchargement des données"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La base de données de biologie étant volumineuse (nous y reviendrons plus bas), un pré-traitement des données a été effectué.  \n",
    "Le pré-traitement est le suivant :\n",
    "- Intégration de l'ensemble des données utiles au sein d'une base de données SQLITE\n",
    "- Tri des lignes de biologies afin de ne conserver que celles répondant au critères suivants :\n",
    "  - Date de réalisation >= date de début du passage aux urgences\n",
    "  - Date de réalisation <= date de fin du passage aux urgences\n",
    "\n",
    "*Le script de transformation peut être consulté dans `database_constitution/database_constitution.py`*\n",
    "\n",
    "Un token de téléchargement des données vous a normallement été mis à disposition."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "    # Commande à executer dans le terminal\n",
    "    pip install -r requirements.txt\n",
    "    python download_data.py [TOKEN]\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## II.2 Transformation des données au format tabulaire"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Les données sont extraites depuis la base de données SQLITE de la façon suivante :\n",
    "  - Récupération et aggrégation des informations suivantes pour chaque consultation aux urgence identifié par un identifiant unique *stay_id* :\n",
    "    - Date de passage *intime*\n",
    "    - Genre *gender*\n",
    "    - Age *age*\n",
    "    - Température à l'accueil **temperature**\n",
    "    - Fréquence Cardiaque à l'accueil **heartrate**\n",
    "    - Fréquence respiratoire à l'accueil **resprate**\n",
    "    - Saturation en Oxygène à l'accueil **o2sat**\n",
    "    - Pression artérielle Systolique à l'accueil (**sbp**) et Diastolique (**dbp**)\n",
    "    - Cotation de douleur à l'accueil **pain**\n",
    "    - Motif de consultation à l'accueil **chiefcomplaint**\n",
    "    - Consultation dans les 7 derniers jours **last_7** ou 30 derniers jours **last_30**\n",
    "    - Antécédents connus au moment de la consultation selon la Classification Internationale des Maladies (CIM) : CIM-9 **icd9** ou CIM10 **icd10**\n",
    "    - Traitements habituels du patient lors de sa consultation, Generic Sequence Number (GSN) (**gsn**)\n",
    "  - Récupération des examens prescrits pour chaque consultation aux urgences :\n",
    "    - Les examens ont été regroupés par paquet correspondant aux techniques de laboratoire et aux organes / aspects fonctionnels explorés sur base de connaissance métier.\n",
    "    - Il s'agit pour chaque paquet d'examen d'une variables binaire indiquant si l'examen a été prescrit au moins une fois durant le passage aux urgences\n",
    "    - La prescription est identifié par la présence d'un résultat d'examen dans la table de résultats d'examens biologiques **labevents**\n",
    "    - Les différentes modalités d'examens sont :\n",
    "      - Cardiaque (**Cardiaque**)\n",
    "      - Coagulation (**Coagulation**)\n",
    "      - Gazométrie (**Gazometrie**)\n",
    "      - Glycemie Sanguine (**Glycemie_Sanguine**)\n",
    "      - Hépato-biliaire (**Hepato-Biliaire**)\n",
    "      - Ionogramme Complet (**IonoC**)\n",
    "      - Lipase (**Lipase**)\n",
    "      - Numération de Formule Sanguine (**NFS**)\n",
    "      - Phospho-Calcique (**Phospho-Calcique**)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 160,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bop_scripts import preprocessing\n",
    "\n",
    "lab_dictionnary = pd.read_csv(\"./config/lab_items.csv\").set_index(\"item_id\")[\"3\"].to_dict()\n",
    "get_drugs, get_diseases = True, True\n",
    "\n",
    "X = preprocessing.generate_features_dataset(\n",
    "    database=\"./data/mimic-iv.sqlite\",\n",
    "    get_drugs=get_drugs,\n",
    "    get_diseases=get_diseases\n",
    ")\n",
    "\n",
    "y = preprocessing.generate_labels_dataset(\n",
    "    database=\"./data/mimic-iv.sqlite\",\n",
    "    lab_dictionnary=lab_dictionnary,\n",
    ")\n",
    "\n",
    "# Par conception, last_7 et last_30 doivent valoir 0 lorsque manquant\n",
    "X[\"last_7\"] = X[\"last_7\"].fillna(0)\n",
    "X[\"last_30\"] = X[\"last_30\"].fillna(0)\n",
    "\n",
    "assert((X[\"stay_id\"] != y[\"stay_id\"]).sum() == 0) # Sanity check"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 161,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Train - test split\n",
    "# Nous gardons 10 000 lignes pour l'évaluation\n",
    "\n",
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "X_train, X_test, y_train, y_test = train_test_split(\n",
    "    X, y, test_size=10000, random_state=42\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# III. Exploration et visualisation les données"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 162,
   "metadata": {},
   "outputs": [],
   "source": [
    "import seaborn as sns\n",
    "from matplotlib import pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Avant d'explorer en détail les données, nous procédons à une identification et un nettoyage des données abérrantes.\n",
    "Ce nettoyage est effectué à partir de la documentation de MIMIC, de la visualisation des données et de connaissances métier."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## III.1. Identification et suppression des outliers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 163,
   "metadata": {},
   "outputs": [],
   "source": [
    "import importlib\n",
    "from bop_scripts import visualisation\n",
    "importlib.reload(visualisation)\n",
    "\n",
    "from bop_scripts.visualisation import plot_all_scatter, plot_missing_outcome, plot_missing_bar, plot_correlation, plot_labels_frequencies_and_correlation, plot_box_variable_label_distribution, plot_odd_word_wc\n",
    "from bop_scripts.preprocessing import remove_outliers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 164,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 77168 characters]",
      "text/plain": [
       "<Figure size 1440x720 with 8 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "variables = [\"temperature\", \"heartrate\", \"resprate\", \"o2sat\", \"sbp\", \"dbp\", \"pain\"]\n",
    "plot_all_scatter(X_train, variables, ncols=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "De facon évidente, des **outliers** sont présents dans le dataset. \n",
    "\n",
    "Une temperature au dela de 150°F, un rythme cardiaque au dela de 400 bpm, une saturation en oxygène au dela de 100%, ou une douleur coté au-dessus de 10 sur une echelle de 0 à 10, correspondent à des données abberantes. \n",
    "\n",
    "A l'aide de la visualisation des données, de la documentation de MIMIC, et de connaissances métier, nous definissons des intervalles pour ces variables et supprimons les outliers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 165,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>n</th>\n",
       "      <th>total</th>\n",
       "      <th>pourcentage</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>temperature</th>\n",
       "      <td>515</td>\n",
       "      <td>414671</td>\n",
       "      <td>0.12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>heartrate</th>\n",
       "      <td>30</td>\n",
       "      <td>421179</td>\n",
       "      <td>0.01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>resprate</th>\n",
       "      <td>78</td>\n",
       "      <td>417837</td>\n",
       "      <td>0.02</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>o2sat</th>\n",
       "      <td>137</td>\n",
       "      <td>417552</td>\n",
       "      <td>0.03</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>sbp</th>\n",
       "      <td>269</td>\n",
       "      <td>419888</td>\n",
       "      <td>0.06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>dbp</th>\n",
       "      <td>626</td>\n",
       "      <td>419060</td>\n",
       "      <td>0.15</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>pain</th>\n",
       "      <td>11614</td>\n",
       "      <td>409525</td>\n",
       "      <td>2.84</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                 n   total  pourcentage\n",
       "temperature    515  414671         0.12\n",
       "heartrate       30  421179         0.01\n",
       "resprate        78  417837         0.02\n",
       "o2sat          137  417552         0.03\n",
       "sbp            269  419888         0.06\n",
       "dbp            626  419060         0.15\n",
       "pain         11614  409525         2.84"
      ]
     },
     "execution_count": 165,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "variables_ranges = {\n",
    "    \"temperature\":[60,130],\n",
    "    \"heartrate\":[20, 300],\n",
    "    \"resprate\":[5, 50],\n",
    "    \"o2sat\":[20, 100],\n",
    "    \"sbp\":[40, 250],\n",
    "    \"dbp\":[20, 200],\n",
    "    \"pain\":[0,10]\n",
    "}\n",
    "\n",
    "X_train_clean, outliers = remove_outliers(X_train, variables_ranges)\n",
    "outliers.round(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 166,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 85192 characters]",
      "text/plain": [
       "<Figure size 1440x720 with 8 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_all_scatter(X_train_clean, variables, ncols=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La **distribution des variables après suppression des outliers.**\n",
    "\n",
    "On observe une **distribution normale** des variables comme la fréquence cardiaque, la pression arterielle ou la température"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## III.2. Analyse des valeurs manquantes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 186,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 110888 characters]",
      "text/plain": [
       "<Figure size 1440x720 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "categorical_features = ['gender', \"last_7\", \"last_30\"]\n",
    "continuous_features = ['age', 'temperature', 'heartrate', 'resprate', 'o2sat', 'sbp', 'dbp', 'pain']\n",
    "features = categorical_features+continuous_features\n",
    "labels = y_train.columns.values[1:].tolist()\n",
    "\n",
    "plot_missing_outcome(X_train_clean, y_train, features, labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nous observons que le taux de prises de sang prescrites augmente avec le nombre de valeurs manquantes.\n",
    "En effet, plus le nombre de features est manquant, plus les patients ont eu une prise de sang.\n",
    "La variable *donnée manquante* n'est donc pas indépendante de la target variable à prédire. \n",
    "\n",
    "Nous avons observé, en regardant de plus près les motifs de consultation des patients avec beaucoup de données manquantes, qu'il s'agissait en réalité, des **patients les plus graves**.   \n",
    "Il s'agissait typiquement de traumatismes sévères, d'urgences neuro-chirurgicales, d'arrêts cardiaques, ou d'états de choc, ayant conduits les patients **directement en service d'accueil des urgences vitales (le déchocage), sans passer par le triage et l'infirmier d'accueil.**. Cela peut se faire quand le camion du SAMU transfert directement ces patients en salle de déchocage. La prise en charge (et donc la mesure de leurs constantes vitales) a donc été réalisé directement en shuntant le parcours classique, compte tenu de la gravité de leur état médical.  \n",
    "Il pouvait aussi s'agir de patients moins graves mais particulièrement **agités**, ou dont l'état rend la prise en charge à l'IAO complexe et nécéssite donc directement l'examen par un médecin, ou l'administration d'un traitement initial (sédation par exemple).\n",
    "\n",
    "**Au total,**\n",
    "\n",
    "- **le nombre de features manquants est directement associé à la variable d'intêret (target)**\n",
    "\n",
    "- **le nombre de features manquants est un surrogate de l'état et de la gravité des patients.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 184,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 18772 characters]",
      "text/plain": [
       "<Figure size 1080x720 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_missing_bar(X, features)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Le pourcentage de données manquantes concernant les features ne dépasse pas 5% pour chaque variable** (à l'exception de la variable \"pain\" qui atteint 7 %). "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# III.3. Visualisation des corrélations"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 15172 characters]",
      "text/plain": [
       "<Figure size 720x432 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "features_for_corr = ['temperature', 'heartrate','resprate','o2sat', 'sbp','dbp']\n",
    "plot_correlation(X_train_clean, features_for_corr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On observe **quelques corrélations caractéristiques** et attendues entre certaines variables:\n",
    "- Entre la pression arterielle systolique et diastolique\n",
    "- Entre la température et le rythme cardiaque (une fièvre engendre physiologiquement une tachycardie)\n",
    "- Entre le rythme cardiaque et le rythme respiratoire (un état de choc, un exercice physique ou une attaque de panique peuvent accélerer le rythme cardiaque et le rythme respiratoire de facon conjointe)\n",
    "\n",
    "Cependant, on note **de manière générale une corrélation plutôt faible dans la globalité des variables prédictives entre elles.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# III. 4. Analyse du texte"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 689068 characters]",
      "text/plain": [
       "<Figure size 1440x720 with 20 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_odd_word_wc(X, y, \"chiefcomplaint\", labels, min_occurrence=3, ncols=5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ici nous représentons les **motifs de consultations** les plus associé à la prescription où non d'un type d'examen biologique. Cette mesure de force d'associé est effectué par le calcul d'un rapport de côte. Les termes présentant ayant un rapport de côte le plus élevé sont affichés dans chaque groupe.\n",
    "\n",
    "Ainsi on observe la capacité éventuelle de la variable \"motif de consultation\" à discriminer les patients ayant recu une prise de sang et son type.\n",
    "\n",
    "Par exemple, on observe que les motifs de consultations prédominants chez les patients ayant bénéficié d'un bilan hépatique sont la présence d'ascite, d'un ictère (jaunisse), d'une pancréatite, d'une colique hépatique, d'une cholecystite, de vomissements. Ces motifs ne sont pas présents de facon prédominante chez les patients n'ayant pas recu de bilan sanguin."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# III. 5. Exploration des labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 56876 characters]",
      "text/plain": [
       "<Figure size 2160x720 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "labels = y_train.columns.values[1:].tolist()\n",
    "plot_labels_frequencies_and_correlation(y, labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Concernant la **fréquence de réalisation de chaque examen biologique.**, environ 50% patients ont bénéficié d'au moins un des examens parmi NFS, ionogramme sanguin, gaz du sang tandis que les autres examens biologiques étaient réalisés chez à peu près 20%.\n",
    "\n",
    "On observe une **corrélation importante entre les 3 variables (labels)** les plus fréquentes, traduisant un co-occurence de leur réalisation aux urgences, à savoir NFS, ionogramme sanguin et gaz du sang. Il existe également une **corrélation importante entre ces 3 variables et le reste des examens biologiques.**  \n",
    "\n",
    "Autrement dit, quand une prise de sang est réalisée, dans la grande majorité des cas, celle-ci comprend en général **au moins une NFS, un ionogramme et un gaz du sang** (ces 3 examens se comportent presque comme un cluster) **plus ou moins** d'autres modalités d'examens biologiques."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# III. 6. Association entre les features et labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 156616 characters]",
      "text/plain": [
       "<Figure size 1440x1152 with 32 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "features = [\"age\", \"temperature\", \"sbp\", \"dbp\", \"heartrate\", \"resprate\", \"o2sat\", \"pain\"]\n",
    "labels = [\"NFS\", \"IonoC\", \"Cardiaque\", \"Hepato-Biliaire\"]\n",
    "plot_box_variable_label_distribution(X_train_clean, y_train, features, labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pour 4 labels (NFS, ionogramme, biomarqueurs cardiaques et bilan hépatique), nous visualisons les **valeurs médianes des différents features selon que l'examen biologique ait été réalisé ou non.**\n",
    "\n",
    "On observe de facon générale, un âge, une température, et un rythme cardiaque plus élevés et une saturation en oxygène plus basse chez les patients avec bilan sanguin, en comparaison au patients non prélevés. \n",
    "\n",
    "On observe de facon générale **un faible pouvoir discriminant** de ces critères pris isolément pour distinguer les patients ayant bénéficié d'une prise de sang des autres."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# IV. Sélection des variables d'interêts"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 605,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bop_scripts.models import generate_model, get_features_selection\n",
    "from bop_scripts.visualisation import vizualize_features_selection\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "_, X_train_clean_subset, _, y_train_subset = train_test_split(\n",
    "    X_train_clean, y_train, test_size=500, random_state=42"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 606,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 80392 characters]",
      "text/plain": [
       "<Figure size 1080x864 with 18 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "qualitatives_variables = [\"gender\", \"last_7\", \"last_30\"]\n",
    "quantitatives_variables = ['age', 'temperature', 'heartrate', 'resprate', 'o2sat', 'sbp', 'dbp', 'pain']\n",
    "text_variables = [\"chiefcomplaint\"]\n",
    "\n",
    "scores = get_features_selection(X_train_clean_subset, y_train_subset.iloc[:,1:], \n",
    "                                LogisticRegression(class_weight=\"balanced\", C=1, solver=\"liblinear\", max_iter=50),\n",
    "                                qualitatives_variables, quantitatives_variables, text_variables[0], min_features=8)\n",
    "vizualize_features_selection(scores, \"roc_auc\", n_score_max=5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Afin d'évaluer les combinaisons idéales de variables, nous avons entrainé et mesuré les performances de l'ensemble des modèles contenant entre 7 et 11 variables pour l'ensemble des labels.\n",
    "Les performances ont été arrondis à la deuxième décimale.  \n",
    "Lorsque deux modèles présentaient les mêmes performances, le modèle contenant le moins de variables était retenu.\n",
    "\n",
    "L'enjeu est d'évaluer :\n",
    "- Si des modèles plus petits performent aussi bien que de grand modèles\n",
    "- Si certaines variables n'apportaient aucun gain de performance de manière systématique\n",
    "\n",
    "Le texte a été traité à l'aide d'un **CountVectorizer** et l'ensemble des modèles ont étés entrainés à l'aide d'une régression logistique. L'algorithme d'optimisation utilisé a été **liblinear** qui convergeait plus rapidement dans le cadre de notre problème où un conditionnement par normalisation des variables a été effectué."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "On observe une certaine hétérogénéité des variables conduisant à l'obtention d'un meilleur modèle selon le label à prédire.  \n",
    "\n",
    "**Aucune variable ne s'est montrée systématiquement inutile**. \n",
    "\n",
    "A l'opposé, on identifie un fort poids des variables suivantes au sein des meilleurs modèles:\n",
    "- **Age**\n",
    "- Avoir consulté dans les 7 ou 30 derniers jours (**last_7** ou **last_30**) \n",
    "- Motif de consultation (**chiefcomplaint**) \n",
    "\n",
    "Chose notable, certains modèles semblent bénéficier de l'association de **last_7** et de **last_30**.  \n",
    "\n",
    "Il faut toutefois noter que les modèles proposés présentent de **faibles variations**, ces dernières pouvant être lié à des **fluctuactions d'échantillonage lors de la cross-validation**."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# V. Définition et entrainement d'une solution d'apprentissage statistique"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A partir des explorations précédents, nous proposons d'inclure l'ensemble des variables dans le modèle final.  \n",
    "Nous entrainerons **un modèle par label à prédire** plutôt qu'un modèle multi-label.\n",
    "\n",
    "**Nous inclurons l'ensemble des variables explorées**, c'est à dire :\n",
    "- genre\n",
    "- last_7\n",
    "- last_30\n",
    "- age\n",
    "- temperature\n",
    "- heartrate\n",
    "- resprate\n",
    "- o2sat\n",
    "- sbp\n",
    "- dbp\n",
    "- pain\n",
    "- chiefcomplaint\n",
    "\n",
    "Ce choix est motivé de la façon suivante :\n",
    "- Notre exploration des variables d'intérêt ne rend pas compte de potentielles relation complexes entre les features.\n",
    "- Aucunes des variables analysées n'ont montrées l'absence total d'intérêt au sein des différents modèles.\n",
    "- Il existe un rationel métier / physiologique en faveur de l'intérêt de ces variables."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Nous nous proposons d'explorer deux modèles :\n",
    "- Une classification à l'aide d'une **régression logistique**, entrainé à l'aide d'un algorithme stochastique (SAG, SAGA) afin d'éviter d'effectuer le calcul de gradient sur l'ensemble du jeu de données (contenant plus de 500 000 éléments)\n",
    "- Une classification à l'aide d'un réseau de neurones : **Multi Layer Percreptron (MLP)**. Le réseau sera entrainé sur un maximum de 50 epochs, nous procéderons à un arrêt précoce de l'entrainement par cross-validation du F1-score sur un jeu de validation indépendant.\n",
    "\n",
    "La validation est effectué sur un jeu de données de validation de 10 000 éléments.\n",
    "Nous avons considéré qu'il n'était pas nécessaire de procéder à une validation par cross-validation répété, dans la mesure où nous avons observés une forte reproductibilité de nos résultats durant nos différents entrainements et surtout du fait de la grande taille des échantillons d'entrainement (plus de 500 000 éléments) et de validation (10 000)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 148,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bop_scripts.models import generate_model, fit_all_classifiers\n",
    "from bop_scripts.visualisation import display_model_performances\n",
    "\n",
    "qualitatives_variables = [\"gender\", \"last_7\", \"last_30\"]\n",
    "quantitatives_variables = ['age', 'temperature', 'heartrate', 'resprate', 'o2sat', 'sbp', 'dbp', 'pain']\n",
    "text_variables = [\"chiefcomplaint\"]\n",
    "labels = y_train.columns[1:]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## V. 1. Régression logistique"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 137,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "\n",
    "def lr_classifier_fn ():\n",
    "    lr_classifier = generate_model(\n",
    "        LogisticRegression(class_weight=\"balanced\", solver=\"saga\"),\n",
    "        qualitatives_variables,\n",
    "        quantitatives_variables,\n",
    "        text_variables[0],\n",
    "        remove_outliers=True,\n",
    "        outliers_variables_ranges=variables_ranges,\n",
    "        CountVectorizer_kwargs={\"ngram_range\":(1,1), \"max_features\":600}\n",
    "    )\n",
    "\n",
    "    return lr_classifier\n",
    "\n",
    "lr_classifiers = fit_all_classifiers(\n",
    "    lr_classifier_fn,\n",
    "    X_train,\n",
    "    y_train.iloc[:,1:],\n",
    "    hide_warnings=True\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 149,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 349008 characters]",
      "text/plain": [
       "<Figure size 2160x2520 with 29 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "display_model_performances(lr_classifiers, X_test, y_test[labels], threshold=0.5, algorithm_name=\"régression logistique\", ncols=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## V. 2. Réseau de neurone (MLP)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {},
   "outputs": [],
   "source": [
    "from bop_scripts.nn_models import torchMLPClassifier_sklearn, torchMLP\n",
    "import torch\n",
    "\n",
    "device = \"cuda:0\" if torch.cuda.is_available() else \"cpu\"\n",
    "def torch_classifier_fn ():\n",
    "\n",
    "    torch_classifier = torchMLPClassifier_sklearn(\n",
    "        torchMLP,\n",
    "        early_stop_validations_size=10000,\n",
    "        early_stop=True,\n",
    "        early_stop_metric=\"f1\",\n",
    "        early_stop_tol=1,\n",
    "        n_epochs=50,\n",
    "        device_train= device,\n",
    "        device_predict=\"cpu\",\n",
    "        class_weight=\"balanced\",\n",
    "        learning_rate=1e-4,\n",
    "        verbose=False\n",
    "    )\n",
    "\n",
    "    torch_sklearn_classifier = generate_model(\n",
    "            torch_classifier,\n",
    "            qualitatives_variables,\n",
    "            quantitatives_variables,\n",
    "            text_variables[0],\n",
    "            remove_outliers=True,\n",
    "            outliers_variables_ranges=variables_ranges,\n",
    "            CountVectorizer_kwargs={\"ngram_range\":(1,1), \"max_features\":600}\n",
    "    )\n",
    "\n",
    "    return torch_sklearn_classifier\n",
    "\n",
    "torch_sklearn_classifiers = fit_all_classifiers(\n",
    "    torch_classifier_fn,\n",
    "    X_train,\n",
    "    y_train.iloc[:,1:],\n",
    "    verbose=False\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 150,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 344256 characters]",
      "text/plain": [
       "<Figure size 2160x2520 with 29 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "display_model_performances(torch_sklearn_classifiers, X_test, y_test.iloc[:,1:], threshold=0.5, algorithm_name=\"MLP\", ncols=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Nous observons des performances légèrement meilleures avec un modèle base sur des réseau de neurones en comparaison à une régression logistique**. Ces différences restent tout de même assez modestes.  \n",
    "Pour des raisons de concision et de lisibilité du rapport, nous avons pas fait état de l'ensemble de nos expérimentations, nous avons toutefois essayés plusieurs architectures de réseaux de neurones, des modifications d'optimiseur, des modifications des paramètres d'apprentissage et avons conservé les modèles les plus performants.  \n",
    "\n",
    "Concernant les pistes d'amélioration, il semble nécessaire d'ajouter de nouvelles features afin d'obtenir des meilleurs performances. Ainsi, nous pourrions par exemple exploiter :\n",
    "- Les informations textuelles de manière plus fines, par exemple à l'aide d'embeddings\n",
    "- Exploiter les **antécédents connus**\n",
    "- Exploiter les **traitements en cours**\n",
    "\n",
    "A ce titre, nous avons effectués plusieurs expérimentations qui ne nous ont toutefois pas permis d'améliorer le modèle :\n",
    "- Utilisation d'embeddings de type Fastext où embedding contextuel à l'aide des modèle BERT-base ou BioBert\n",
    "- Représentation des antécédents sous forme d'embedding à l'aide du modèle d'embedding des codes de classification internationale des maladies (ICD-9 / ICD-10) issus du projet *icd-codex* : https://github.com/icd-codex/icd-codex\n",
    "- Représentation des traitements en cours par leurs appartenance à une des grande classes selon la classification ATC (anatomique, thérapeutique et chimique)\n",
    "- Conceptions d'embeddings d'ordonnance crée par l'entrainement d'un réseau de neurone à identifier la co-prescription de pairs de molécules, stratégie voulue comme analogue aux méthodes *CBOW* et *skip-gram*\n",
    "\n",
    "Bien que l'ensemble de ces méthodes ne nous aient pas données de résultats satisfaisant, nous considérons que chacune demanderait un temps d'exploration plus approfondie avant d'en conclure en leurs inefficacité.\n",
    "\n",
    "Nous attirons l'attention du lecteur sur quelques points nécessaire à l'interprétation des performances :\n",
    "- La non prédiction d'un examen à prescrire (**Faux Négatif**) engendre essentiellement un coût d'opportunité, correspondant au temps qui aurait été gagné si l'examen aurait été correctement prédit. **Ce Faux Négatif n'a pas d'impact sur le fonctionnement habituel du service. Cela revient à \"faire comme d'habitutde\".**\n",
    "- La prédiction à tord d'un examen à prescrire (**Faux Positif**) engendre de nombreux coûts :\n",
    "  - Coût relatif à la gêne occasionné au patient par la réalisation de l'acte de prélèvement (geste invasif)\n",
    "  - Une potentielle prolongation inutile de la durée du passage dans le service\n",
    "  - Une augmentation de la charge de travail du personnel soignant ayant potentiellement pour conséquence un ralentissement des autres prises en charge\n",
    "  - Coût financier\n",
    "\n",
    "Ainsi, nous attendons que notre algorithme une diminution de taux de faux positifs, c'est à dire une maximisation de la précision. En statistique bio-médicale cette métrique se nomme la **Valeur Prédictive Positive (VPP)** dont le seuil d'acceptabilité resterait à définir."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notre modèle présente des performances très limité dans la prédiction de la prescription d'examen **Phospho-calcique**, **Lipase**, **Hepato-Biliaire** et **Glycémie Sanguine**. La forme des courbes ROC de ces derniers laisse entrevoir une difficulté à trouver un compromis entre précision et recall. Nous pensons que cela s'expliquer par deux facteurs :\n",
    "- La fréquence de réalisation de ces examens est plus faible que celle des autres examens (autours de 20%), constituant partiellement un problème d'entrainement sur échantillons déséquilibré. Il pourrait à ce titre être intéressant d'explorer une approche autours de la gestion de jeux de données déséquilibré (ré-équilibrage par suppression d'examples négatifs, augmentation de dataset par génération de données synthétiques (par exemple à l'aide de l'outils SMOTE))\n",
    "- Les données actuelles n'encodent pas assez d'information pour discriminer un patient ayant où n'ayant pas besoin d'un de ces types d'examens.\n",
    "\n",
    "Concernant la marqueur **Cardiaque** et la **coagulation** nous identifions de relatives bonnes performances qui restent à notre avis malgré tout en deça de performances acceptables pour une utilisation pratique de l'outils. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Enfin, pour la **NFS**, le **Ionogramme complet** et la **Gazométrie**, qui sont les examens les plus couramment réalisés, nous disposons de performances correctes avec **la possibilité de maximiser la précision en sacrifiant du recall par ajustement du seuil de décision de la positivité de la prédiction.**\n",
    " \n",
    "C'est ce que nous envisageons enfin ci-dessous"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "display_model_performances(torch_sklearn_classifiers, X_test, y_test.iloc[:,1:], threshold=0.5, algorithm_name=\"MLP\", ncols=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 158,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 130104 characters]",
      "text/plain": [
       "<Figure size 2160x1008 with 11 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "exams = [\"NFS\", \"IonoC\", \"Gazometrie\"]\n",
    "exams_classifiers = dict([(x,y) for x, y in torch_sklearn_classifiers.items() if x in exams])\n",
    "display_model_performances(exams_classifiers, X_test, y_test[exams], threshold=0.7, algorithm_name=\"MLP\", ncols=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Nous obtenons ainsi des précisions (métrique d'intêret comme expliqué plus haut) et des AUC dépassants 80% avec une minimisation des faux positifs, lesquels représentent moins de 5% du test set.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Quelques remarques finales avant de conclure: \n",
    "\n",
    "A noter que le temps de réalisation d'un examen se décompose de la façon suivante :\n",
    "- Temps technique de prélèvement\n",
    "- Temps d'acheminement de l'examen au laboratoire\n",
    "- Temps de traitement de la demande au laboratoire\n",
    "- Temps de mesure au sein de l'automate\n",
    "\n",
    "Ainsi, le temps de mesure au sein de l'automate ne correspond qu'à une petite partie du temps nécessaire à la réalisation d'un examen.  \n",
    "Il est donc possible, lorsque l'échantillon sanguin est compatible, de faire réaliser **à posteriori** (en appelant le laboratoire par example qui se charge de processer à nouveau le même tube de sang déja acheminé) un où des examens complémentaires sur ce même prélèvement.  \n",
    "**Ainsi, pour certains examens, la seule prédiction d'une modalité est suffisante pour maintenir la pertinence du système,** c'est notamment le cas pour : **IonoC**, **Cardiaque**, **Lipase**, **Hépato-biliaire** et **Phospho-calcique**, lesquels sont des examens pratiqués dans le même laboratoire de **biochimie**. \n",
    "\n",
    "Ce n'est toutefois pas le cas pour la **coagulation** (réalisé au laboratoire d'hémostase). \n",
    "\n",
    "Enfin l'examen glycémie sanguine peut quand à lui être substitué par des mesures capillaires se faisant extrêmement rapidement.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**En conclusion :**\n",
    "\n",
    "- **Nous avons developpé un outil de prediction, basé sur un réseau de neurone, permettant, à partir de données simples, obtenues dans les premières minutes d'une consultation aux urgences, de prédire correctement la nécéssité de réaliser une NFS, un ionogramme complet et une gazométrie.**\n",
    "\n",
    "- **Nous reconnaissons qu'une amélioration des performances prédictive est possible (en étudiant les performances de modèles intégrants les antécédents et traitements en cours des patients) et serait attendu en vue d'obtenir un système optimal avant d'envisager un déploiement.**"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "28b293e0c0671e44c7281dde6399c7c7419d3faca031d22494da8635907ada72"
  },
  "kernelspec": {
   "display_name": "Python 3.9.7 ('base')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.9"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
