TensorFlow une librairie de Deep Learning Python

    [Tutoriel] Deep Learning avec TensorFlow dans R

    Le Deep Learning est un type d’apprentissage automatique basé sur l’apprentissage de la structure et la représentation des données ainsi que l’apprentissage des fonctionnalités (Feature learning) plutôt que des taches isolées. Le Feature learning peut être supervisé, non supervise ou semi supervisé.

    Les applications du Deep Learning regroupe la reconnaissance faciale, la vision par ordinateur, le NLP (natural language processing) et la reconnaissance des images. Ces applications et pleins d’autres sont possibles grâce aux architectures du Deep Learning comprenant les réseaux de neurones profonds (Deep Neural Networks) entre autre.

    Le but de ce tutoriel est de vous expliquer : Comment implémenter un réseau de neurones profonds avec TensorFlow dans R.

    Qu’est ce que TensorFlow ?

    TensorFlow est une librairie open source d’apprentissage automatique développée par Google. Cette librairie permet, entre autre, de faire des calculs numériques complexes pour construire des modèles de Deep Learning.

    Sa conception réfléchie et sa facilité d’utilisation, l’ont rendu populaire auprès des Data Scientists.

    Installation de TensorFlow et préparation des données 

    Installation et préparation des données TensorFlow sur R

    Installation et préparation des données

     Avant d’utiliser TensorFlow dans R, on doit télécharger et installer la librairie. Pour ce faire, on va directement la télécharger depuis Github.

    devtools::install_github("rstudio/tfestimators")
    library(tfestimators)

    Bien que nous ayons installé la librarie, on n’a pas réellement le code compilé de TensorFlow. Pour l’avoir, il faut utiliser la commande suivant :

    install_tensorflow()

    Données pour le tutoriel

    Durant ce tutoriel, nous allons utilisé un data set tiré du livre Data Science for Fundraising. 

    On commence par charger le data set dans notre environnement en utilisant les librairies readr et dplyr :

    library(readr)
    library(dplyr)
     
    donor_data <- read_csv("https://www.dropbox.com/s/ntd5tbhr7fxmrr4/DonorSampleDataCleaned.csv?raw=1")

    Regardons maintenant à quoi ressemble ces données :

    glimpse(donor_data)
     
    #> Observations: 34,508
    #> Variables: 23
    #> $ ID                  <int> 1, 2, 3, 4, 5, 6,...
    #> $ ZIPCODE             <chr> "23187", "77643",...
    #> $ AGE                 <int> NA, 33, NA, 31, 6...
    #> $ MARITAL_STATUS      <chr> "Married", NA, "M...
    #> $ GENDER              <chr> "Female", "Female...
    #> $ MEMBERSHIP_IND      <chr> "N", "N", "N", "N...
    #> $ ALUMNUS_IND         <chr> "N", "Y", "N", "Y...
    #> $ PARENT_IND          <chr> "N", "N", "N", "N...
    #> $ HAS_INVOLVEMENT_IND <chr> "N", "Y", "N", "Y...
    #> $ WEALTH_RATING       <chr> NA, NA, NA, NA, N...
    #> $ DEGREE_LEVEL        <chr> NA, "UB", NA, NA,...
    #> $ PREF_ADDRESS_TYPE   <chr> "HOME", NA, "HOME...
    #> $ EMAIL_PRESENT_IND   <chr> "N", "Y", "N", "Y...
    #> $ CON_YEARS           <int> 1, 0, 1, 0, 0, 0,...
    #> $ PrevFYGiving        <chr> "$0", "$0", "$0",...
    #> $ PrevFY1Giving       <chr> "$0", "$0", "$0",...
    #> $ PrevFY2Giving       <chr> "$0", "$0", "$0",...
    #> $ PrevFY3Giving       <chr> "$0", "$0", "$0",...
    #> $ PrevFY4Giving       <chr> "$0", "$0", "$0",...
    #> $ CurrFYGiving        <chr> "$0", "$0", "$200...
    #> $ TotalGiving         <dbl> 10, 2100, 200, 0,...
    #> $ DONOR_IND           <chr> "Y", "Y", "Y", "N...
    #> $ BIRTH_DATE          <date> NA, 1984-06-16, ...

    TensorFlow ne gère pas les valeurs manquantes, c’est la raison pour laquelle on va remplacer ces valeurs dans cet ordre :

    • Factors par Modes
    • Numeriques par medianes.

    Pour faire cela, on va utiliser le code suivant :

    # function copied from
    # https://stackoverflow.com/a/8189441/934898
    my_mode <- function(x) {
        ux <- unique(x)
        ux[which.max(tabulate(match(x, ux)))]
    }
     
    donor_data <- donor_data %>% 
      mutate_if(is.numeric, 
                .funs = funs(
                  ifelse(is.na(.), 
                         median(., na.rm = TRUE),
                         .))) %>%
      mutate_if(is.character, 
                .funs = funs(
                  ifelse(is.na(.), 
                         my_mode(.),
                         .)))

    Maintenant, on va convertir les variables de type caractères en Factor :

    predictor_cols <- c("MARITAL_STATUS", "GENDER", 
                        "ALUMNUS_IND", "PARENT_IND", 
                        "WEALTH_RATING", "PREF_ADDRESS_TYPE")
     
    # Convert feature to factor
    donor_data <- mutate_at(donor_data, 
                            .vars = predictor_cols, 
                            .funs = as.factor)

     Maintenant, nous allons indiquer à TensorFlow les types de colonnes. Pour les colonnes de Factor, on doit lui specifier les valeurs contenues dans ces colonnes en utilisant la fonction column_categorical_with_vocabulary_list. Deuxiement, on va convertir chacune des valeurs de facteur d’une colonne en sa propre colonne avec 0 et 1 – ce processus est appelé codage à chaud en utilisant la fonction column_indicator. Par exemple, pour la colonne GENDER, nous avons que deux valeurs possibles: Homme et Femme. Un processus d’encodage à chaud crée deux colonnes: une pour les hommes et l’autre pour les femmes. Chacune de ces colonnes contiendra 0 ou 1 en fonction de la valeur de données contenue dans la colonne GENDER.

    feature_cols <- feature_columns(
      column_indicator(
        column_categorical_with_vocabulary_list(
          "MARITAL_STATUS", 
          vocabulary_list = unique(donor_data$MARITAL_STATUS))), 
        column_indicator(
          column_categorical_with_vocabulary_list(
            "GENDER", 
            vocabulary_list = unique(donor_data$GENDER))), 
        column_indicator(
          column_categorical_with_vocabulary_list(
            "ALUMNUS_IND", 
            vocabulary_list = unique(donor_data$ALUMNUS_IND))), 
        column_indicator(
          column_categorical_with_vocabulary_list(
            "PARENT_IND", 
            vocabulary_list = unique(donor_data$PARENT_IND))), 
        column_indicator(
          column_categorical_with_vocabulary_list(
            "WEALTH_RATING", 
            vocabulary_list = unique(donor_data$WEALTH_RATING))), 
        column_indicator(
          column_categorical_with_vocabulary_list(
            "PREF_ADDRESS_TYPE", 
            vocabulary_list = unique(donor_data$PREF_ADDRESS_TYPE))), 
        column_numeric("AGE"))

    Maintenant, nous allons créer un data set d’apprentissage et un autre de test.

    row_indices <- sample(1:nrow(donor_data), 
                          size = 0.8 * nrow(donor_data))
    donor_data_train <- donor_data[row_indices, ]
    donor_data_test <- donor_data[-row_indices, ]

    TensorFlow nécessite ensuite la création d’une fonction d’entrée avec la liste des variables d’entrée et de sortie. Nous allons prédire la probabilité du don d’une personne.

    donor_pred_fn <- function(data) {
        input_fn(data, 
                 features = c("AGE", "MARITAL_STATUS", 
                              "GENDER", "ALUMNUS_IND", 
                              "PARENT_IND", "WEALTH_RATING", 
                              "PREF_ADDRESS_TYPE"), 
                 response = "DONOR_IND")
    }

    Construction d’un Classificateur Deep Learning

    Construction du modele en utilisant tensorflow

    Construction

    Maintenant, on va utiliser le data set d’apprentissage et la fonction d’entrée pour construire notre modèle de classification. 

    On va créer trois couches cachées avec respectivement 80, 40 et 30 nœuds.

    classifier <- dnn_classifier(
      feature_columns = feature_cols, 
      hidden_units = c(80, 40, 30), 
      n_classes = 2, 
      label_vocabulary = c("N", "Y"))

    On construit le modele en utilisant la fonction d’apprentissage :

    train(classifier, 
          input_fn = donor_pred_fn(donor_data_train))

    On predit les valeurs en utilisant le model et le data set de test et le data set complet :

    predictions_test <- predict(
      classifier, 
      input_fn = donor_pred_fn(donor_data_test))
    predictions_all <- predict(
      classifier, 
      input_fn = donor_pred_fn(donor_data))

    De même, nous évaluerons le modèle à la fois pour les données de test et pour l’ensemble de données complet. Vous pouvez voir l’évaluation sur les données de test dans la table @ref (onglet: evaltftest) et pour le jeu complet de données dans la table @ref (onglet: evaltfall).

    evaluation_test <- evaluate(
      classifier, 
      input_fn = donor_pred_fn(donor_data_test))
    evaluation_all <- evaluate(
      classifier, 
      input_fn = donor_pred_fn(donor_data))

     

    >