Tanagra Data Mining 5 février 2020 Page 1/24 0.22.1 #vérification de la version

Tanagra Data Mining 5 février 2020 Page 1/24 0.22.1 #vérification de la version de scikit-learn import sklearn print(sklearn. version ) 1 Introduction Implémentation des arbres de décision avec la librairie Scikit-Learn (0.22.1) sous Python. Représentation graphique de l’arbre et appréhension des variables prédictives qualitatives. Tous les ans, préalablement à chacune de mes séances sur machine avec les étudiants, je fais un travail de mise à jour des instructions et indications de résultats retranscrits dans ma fiche de TD (travaux dirigés). Il faut dire que les packages sous R et Python ne se soucient pas toujours de compatibilités descendantes ou ascendantes. Une instruction valable hier peut ne pas fonctionner aujourd’hui ou, pire, fournir un résultat différent parce que les paramètres par défaut ont été modifiés ou les algorithmes sous-jacents améliorés. La situation est moins critique lorsque des fonctionnalités additionnelles sont proposées. Encore faut-il les connaître. La veille technologique est indissociable de notre activité, et j’y passe vraiment beaucoup de temps. Concernant ma séance consacrée aux arbres de décision sous Python justement, où nous utilisons la libraire Scikit-Learn (Decision Trees), j’avais pour habitude d’annoncer à mes étudiants qu’il n’était pas possible de disposer – simplement – d’une représentation graphique de l’arbre, à l’instar de ce que nous fournirait le package ‘’rpart.plot’’ pour les arbres ‘’rpart’’ sous R par exemple. La nécessité d’installer un outil externe (voir ‘’Random Forest et Boosting avec R et Python’’, novembre 2015 ; section 4.3.3) rendait la manipulation rédhibitoire dans une séance où nous travaillons en temps (très) restreint avec des machines (très) protégées. Je me suis rendu compte récemment au détour d’une requête Google, assez heureuse je dois l’avouer, que la situation a évolué avec la version 0.21.0 de Scikit-Learn (Mai 2019). Nous allons vérifier cela dans ce tutoriel. Nous en profiterons pour étudier les manipulations à réaliser pour pouvoir appliquer les dits-arbres sur des variables prédictives (explicatives) catégorielles. L’outil ne sait pas les appréhender de manière native… pour l’instant (version 0.22.1, février 2020). 2 Construction et représentation d’un arbre avec Scikit-Learn 2.1 Vérification de la version de Scikit-Learn Nous devrions commencer toute session d’analyse avec l’identification des versions des packages que nous utilisons. Concernant ‘’scikit-learn’’, nous travaillons avec… (699, 10) #modifier le working directory import os os.chdir("... votre dossier de travail ...") #importer les données – utilisation de la librairie pandas import pandas df = pandas.read_excel("breast.xlsx",sheet_name = 0) #dimension du data frame print(df.shape) s variables frame.DataFrame'> RangeIndex: 699 entries, 0 to 698 Data columns (total 10 columns): nt Dtype dtypes: int64(9), object(1) 2.2 Importation et expertise des données Nous traitons un exemple très simple dans un premier temps. Nous utilisons la base ultra-connue ‘’Breast Cancer Wisconsin’’. Nous cherchons à expliquer la variable ‘’classe’’ décrivant la nature maligne (malignant) ou non (begnin) de cellules à partir de leurs caractéristiques (clump, ucellsize, …, mitoses ; 9 variables numériques). Nous disposons de 699 observations et 10 variables. Voici les premières lignes de notre dataset. #affichage des premières lignes print(df.head()) clump ucellsize ucellshape ... normnucl mitoses classe 0 4 2 2 ... 1 1 begnin 1 1 1 1 ... 1 1 begnin 2 2 1 1 ... 1 1 begnin 3 10 6 6 ... 7 1 malignant 4 4 1 1 ... 1 1 begnin Nous affichons les informations sur le type des variables. 0 clump 699 non-null int64 1 ucellsize 699 non-null int64 2 ucellshape 699 non-null int64 3 mgadhesion 699 non-null int64 4 sepics 699 non-null int64 5 bnuclei 699 non-null int64 6 bchromatin 699 non-null int64 7 normnucl 699 non-null int64 8 mitoses 699 non-null int64 9 classe 699 non-null object La variable cible ‘’classe’’ est la seule non-numérique, le type ‘’object’’ lui est associé. Name: classe, dtype: int64 458 241 begnin malignant #vérifier la distribution absolue des classes print(df.classe.value_counts()) Name: classe, dtype: float64 0.655222 0.344778 begnin malignant #la distribution relative print(df.classe.value_counts(normalize=True)) Ensemble d’apprentissage Construction de la fonction f(.) à partir des données d’apprentissage Y = f(X1,X2,…) +  Application du modèle (prédiction) sur l’ensemble de test Ensemble de données (dataset) (Y ,Y ) ˆ Ensemble de test Y : valeurs observées Y^ : valeurs prédites par f(.) Mesures de performances par confrontation entre Y et Y^ : matrice de confusion + Nous affichons la fréquence absolue des classes… … puis relative. Ces informations sont importantes lorsque nous aurons à inspecter les résultats. 2.3 Partition en échantillons d’apprentissage et de test Nous cherchons à appliquer le schéma type de l’analyse prédictive : scinder les données en échantillons d’apprentissage et de test, développer le modèle (estimer ses paramètres) sur le premier, en évaluer les performances sur le second à travers la confrontation des classes observées et prédites. Figure 1 - Schéma type de travail en analyse prédictive Nous souhaitons réserver 399 observations pour l’apprentissage et 300 pour le test, avec un échantillonnage stratifié (stratify) c.-à-d. respectant les proportions des classes dans les deux sous-ensembles. Nous fixons (random_state = 1) pour que l’expérimentation soit reproductible. #subdiviser les données en échantillons d'apprentissage et de test #vérification des dimensions print(dfTrain.shape) #(399, 10) print(dfTest.shape) #(300, 10) #instanciation de l'arbre from sklearn.tree import DecisionTreeClassifier arbreFirst = DecisionTreeClassifier(min_samples_split=30,min_samples_leaf=10) Name: classe, dtype: float64 0.654135 0.345865 begnin malignant #vérification des distributions en apprentissage print(dfTrain.classe.value_counts(normalize=True)) Name: classe, dtype: float64 0.656667 0.343333 begnin malignant #vérification des distributions en test print(dfTest.classe.value_counts(normalize=True)) DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini', max_depth=None, max_features=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_ #const arbreF from sklearn.model_selection import train_test_split dfTrain, dfTest = train_test_split(df,test_size=300,random_state=1,stratify=df.classe) Nous vérifions les dimensions des données. Nous affichons les distributions relatives des classes en apprentissage… … et en test. Les proportions sont respectées. 2.4 Instanciation et modélisation Nous instancions un arbre de décision ‘’DecisionTreeClassifier’’ de la librairie Sckit-Learn (https://scikit-learn.org/stable/modules/tree.html ; ‘’Classification’’) avec deux paramètres : un sommet n’est pas segmenté s’il est composé de moins de 30 individus (min_samples_split = 30) ; une segmentation est validée si et seulement si les feuilles générées comportent tous au moins 10 observations (min_samples_leaf = 10). Nous lançons le processus de modélisation sur les données d’apprentissage en spécifiant la matrice (X) des variables prédictives, et le vecteur (y) de la variable cible. #affichage graphique de l'arbre - depuis sklearn 0.21 #https://scikit-learn.org/stable/modules/generated/sklearn.tree.plot_tree.html#sklearn.tree.plot_tree from sklearn.tree import plot_tree plot_tree(arbreFirst,feature_names = list(df.columns[:-1]),filled=True) [Text(182.61818181818182, 195.696, 'ucellsize <= 3.5\ngini = 0.452\nsamples = 399\nvalue = [261, 138]'), Text(121.74545454545455, 152.208, 'bnuclei <= 6.0\ngini = 0.136\nsamples = 273\nvalue = [253, 20]'), Text(91.30909090909091, 108.72, 'ucellshape <= 3.5\ngini = 0.045\nsamples = 259\nvalue = [253, 6]'), Text(60.872727272727275, 65.232, 'bnuclei <= 3.5\ngini = 0.008\nsamples = 247\nvalue = [246, 1]'), Text(30.436363636363637, 21.744, 'gini = 0.0\nsamples = 232\nvalue = [232, 0]'), Text(91.30909090909091, 21.744, 'gini = 0.124\nsamples = 15\nvalue = [14, 1]'), Text(121.74545454545455, 65.232, 'gini = 0.486\nsamples = 12\nvalue = [7, 5]'), Text(152.1818181818182, 108.72, 'gini = 0.0\nsamples = 14\nvalue = [0, 14]'), Text(243.4909090909091, 152.208, 'ucellsize <= 4.5\ngini = 0.119\nsamples = 126\nvalue = [8, 118]'), Text(213.05454545454546, 108.72, 'gini = 0.393\nsamples = 26\nvalue = [7, 19]'), Text(273.92727272727274, 108.72, 'mgadhesion <= 2.5\ngini = 0.02\nsamples = 100\nvalue = [1, 99]'), Text(243.4909090909091, 65.232, 'gini = 0.117\nsamples = 16\nvalue = [1, 15]'), Text(304.3636363636364, 65.232, 'gini = 0.0\nsamples = 84\nvalue = [0, 84]')] La console affiche l’ensemble des paramètres utilisés lors de la modélisation. 2.5 Affichage graphique de l’arbre L’affichage de l’arbre était un des obstacles de l’utilisation de cet outil. Auparavant, il fallait générer un fichier au format particulier (.dot), que l’on faisait interpréter par un outil externe à installer au préalable. Ce n’était pas vraiment ‘’user friendly’’. Aujourd’hui, depuis la version 0.21 de Scikit-Learn, nous disposons d’une fonction dédiée à la génération de la représentation graphique directement dans la console. Voyons ce qu’il en est. La fonction prend en paramètre l’arbre généré par l’apprentissage, la liste des noms des variables prédictives (feature_names), les sommets peuvent être coloriés selon la classe majoritaire (filled = True). L’outil affiche la description textuelle de l’arbre. Puis sous sa forme graphique. #affichage plus grand pour une meilleure lisibilité import matplotlib.pyplot as plt plt.figure(figsize=(10,10)) plot_tree(arbreFirst,feature_names = list(df.columns[:-1]),filled=True) plt.show() Si elle n’est pas très lisible, nous pouvons en moduler la taille. Racine de l’arbre 1 Yes No c.-à-d. ucellsize ≤ 3.5 c.-à-d. ucellsize > 3.5 2 3 5 6 7 4 9 10 11 8 12 7 feuilles donc 7 règles, mais certaines pourront être simplifiées 13 Figure 2 - Premier arbre de décision sur les données "breast" Que lisons-nous ?  L’arbre est composé de 7 feuilles (sommets n°12, 13, 9, 5, 6, 10, 11). Il produit donc 7 règles prédictives matérialisées par les chemins partant de la racine aux feuilles.  Nous observons l’effectif de l’échantillon d’apprentissage sur la racine de l’arbre (nRacine = n = samples = 399) avec 261 ‘’begnin’’ et 138 ‘’malignant’’ (dans l’ordre alphabétique).  Les sommets sont teintés (c’est le rôle de l’option filled = True) selon la classe majoritaire qu’ils portent, avec plus ou moins d’intensité selon la concentration des effectifs. Ici, visiblement, le bleu est dévolu à ‘’malignant’’, l’orange à ‘’begnin’’.  La concentration des classes est calculée à l’aide de l’indice de Gini (on parle aussi de mesure d’impureté [de l’anglais ‘’impurity’’] ou de mesure de diversité). Pour la racine (sommet n°1), nous avons (K = 2, nombre de modalités uploads/Litterature/ fr-tanagra-scikit-learn-decision-tree-2.pdf

  • 26
  • 0
  • 0
Afficher les détails des licences
Licence et utilisation
Gratuit pour un usage personnel Attribution requise
Partager