{"id":247,"date":"2014-12-15T17:48:42","date_gmt":"2014-12-15T16:48:42","guid":{"rendered":"http:\/\/perso.ens-lyon.fr\/lise.vaudor\/?p=247"},"modified":"2019-08-16T15:37:20","modified_gmt":"2019-08-16T13:37:20","slug":"classification-par-arbres-decisionnels","status":"publish","type":"post","link":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/classification-par-arbres-decisionnels\/","title":{"rendered":"Classification par arbres d\u00e9cisionnels"},"content":{"rendered":"<p><img decoding=\"async\" src=\"..\/..\/lise.vaudor\/Rfigures\/Arbres_decisionnels\/Lise_Vaudor_headband.png\" alt=\"plot of chunk\nLise_Vaudor_headband\" \/><\/p>\n<h2>Qu&rsquo;est-ce que c&rsquo;est?<\/h2>\n<p>Les arbres d\u00e9cisionnels font partie des m\u00e9thodes d&rsquo;<strong>apprentissage supervis\u00e9<\/strong>, et font \u00e0 ce titre partie de la bo\u00eete \u00e0 outils du parfait petit dataminer. Ils visent \u00e0 <strong>pr\u00e9dire les valeurs<\/strong> prises par une variable en fonction d&rsquo;un jeu de variables d&rsquo;entr\u00e9e (qu&rsquo;on appellera ici les descripteurs). Cette pr\u00e9diction se fait \u00e0 travers la construction d&rsquo;un <strong>arbre<\/strong> dont chaque <strong>noeud<\/strong> correspond \u00e0 une <strong>d\u00e9cision<\/strong> quant \u00e0 la valeur de la variable \u00e0 pr\u00e9dire. Cette d\u00e9cision est prise <strong>en fonction de la valeur d&rsquo;un des descripteurs<\/strong>.<\/p>\n<p>La variable \u00e0 pr\u00e9dire et les descripteurs, peuvent \u00eatre quantitatifs ou cat\u00e9goriels.<\/p>\n<h2>Exemple:<\/h2>\n<p>Consid\u00e9rons l&rsquo;exemple suivant (purement fictif):<\/p>\n<p>On imagine que le propri\u00e9taire d&rsquo;un magasin de v\u00eatements a not\u00e9 tous les articles disponibles selon leur prix, leur qualit\u00e9 (note de 0 \u00e0 100), leur branchitude (note de 0 \u00e0 100) et leur flashitude (note de 0 \u00e0 100). Il note si ces articles ont \u00e9t\u00e9 achet\u00e9s par des clients au cours de la semaine pass\u00e9e.<\/p>\n<p><img decoding=\"async\" src=\"..\/..\/lise.vaudor\/Rfigures\/Arbres_decisionnels\/decision_tree.png\" alt=\"plot of chunk\ndecision_tree\" \/><\/p>\n<p>L&rsquo;arbre de classification ci-dessus s&rsquo;interpr\u00e8te de la mani\u00e8re suivante.<\/p>\n<p>Si la valeur de branchitude d&rsquo;un article est sup\u00e9rieure \u00e0 85, alors les clients l&rsquo;ach\u00e8tent (11 achats contre 1 non-achat).<\/p>\n<p>Si la branchitude d&rsquo;un article est inf\u00e9rieure \u00e0 85 mais sa flashitude est sup\u00e9rieure \u00e0 65, alors les clients l&rsquo;ach\u00e8tent (7 achats contre un non-achat).<\/p>\n<p>Si la branchitude d&rsquo;un article est inf\u00e9rieure \u00e0 85, et sa flashitude inf\u00e9rieure \u00e0 17.5, alors les clients ne l&rsquo;ach\u00e8tent pas (13 non-achats contre 3 achats). Si la branchitude est inf\u00e9rieure \u00e0 65, la flashitude entre 17.5 et 65, mais la qualit\u00e9 est bonne (sup\u00e9rieure \u00e0 75), alors les clients l&rsquo;ach\u00e8tent tout de m\u00eame (8 achats contre 4 non-achats). Si au contraire la qualit\u00e9 de l&rsquo;article est m\u00e9diocre (inf\u00e9rieure \u00e0 75), alors les clients ne l&rsquo;ach\u00e8tent pas (21 non achats contre 9 achats).<\/p>\n<p>(En r\u00e9sum\u00e9, si j&rsquo;\u00e9tais le g\u00e9rant de ce magasin, pour maximiser mes ventes, j&rsquo;essaierais de proposer des articles branch\u00e9s et flashy, et pr\u00e9f\u00e9rentiellement de bonne qualit\u00e9, sans trop me soucier du prix auquel je les affiche&#8230;)<\/p>\n<h2>Construction d&rsquo;un arbre de d\u00e9cision<\/h2>\n<p>Nous allons voir maintenant comment construire cet arbre. Le jeu de donn\u00e9es \u00e9voqu\u00e9 ci-dessus se trouve <a href=\"..\/..\/lise.vaudor\/Rdata\/Arbres_decisionnels\/magasin.csv\">ici<\/a>.<\/p>\n<p>Pour calculer l&rsquo;arbre de d\u00e9cision, nous allons utiliser le package <code>rpart<\/code>.<\/p>\n<pre><code>magasin=read.table(paste(dat.path,\"magasin.csv\",sep=\"\"),\n                   sep=\";\", header=T, dec=\",\")\nattach(magasin)\ndt=rpart(Achat~Prix+Flashitude+Branchitude+Qualite, data=magasin)\n<\/code><\/pre>\n<p>Le graphique ci-dessus est g\u00e9n\u00e9r\u00e9 \u00e0 travers les commandes suivantes:<\/p>\n<pre><code>plot(dt)\ntext(dt, use.n=T)\n<\/code><\/pre>\n<p>Examinons l&rsquo;objet renvoy\u00e9 par la fonction <code>rpart<\/code>.<\/p>\n<pre><code>print(dt)\n\n## n= 78 \n## \n## node), split, n, loss, yval, (yprob)\n##       * denotes terminal node\n## \n##  1) root 78 38 non (0.51282 0.48718)  \n##    2) Branchitude&lt; 85 66 27 non (0.59091 0.40909)  \n##      4) Flashitude&lt; 65 58 20 non (0.65517 0.34483)  \n##        8) Flashitude&lt; 17.5 16  3 non (0.81250 0.18750) *\n##        9) Flashitude&gt;=17.5 42 17 non (0.59524 0.40476)  \n##         18) Qualite&lt; 75 30  9 non (0.70000 0.30000) *\n##         19) Qualite&gt;=75 12  4 oui (0.33333 0.66667) *\n##      5) Flashitude&gt;=65 8  1 oui (0.12500 0.87500) *\n##    3) Branchitude&gt;=85 12  1 oui (0.08333 0.91667) *\n<\/code><\/pre>\n<p>Voici comment lire cette sortie :<\/p>\n<ul>\n<li>A la racine de l&rsquo;arbre (<strong>branche 1<\/strong>) il y a <strong>78<\/strong> individus, dont seulement <strong>38 \u00ab\u00a0oui\u00a0\u00bb<\/strong>. C&rsquo;est donc le <strong>\u00ab\u00a0non\u00a0\u00bb<\/strong> qui l&#8217;emporte (\u00e0 <strong>51&#46;3%<\/strong>).<\/li>\n<li>L&rsquo;arbre pr\u00e9sente un noeud qui se divise en deux branches (les branches 2 et 3). La <strong>branche 2<\/strong> correspond aux individus tels que <strong>Branchitude &lt; 85<\/strong>. Il y a <strong>66<\/strong> individus dans cette branche, dont seulement <strong>27 \u00ab\u00a0oui\u00a0\u00bb<\/strong>. C&rsquo;est donc le <strong>\u00ab\u00a0non\u00a0\u00bb<\/strong> qui l&#8217;emporte (\u00e0 <strong>59%<\/strong>). La <strong>branche 3<\/strong> correspond au reste des individus (tels que <strong>Branchitude \u2004\u2265\u2004 85<\/strong>). Il y a <strong>12<\/strong> individus dans cette branche, dont <strong>1 seul \u00ab\u00a0non\u00a0\u00bb<\/strong>. C&rsquo;est donc le <strong>oui<\/strong> qui l&#8217;emporte (\u00e0 <strong>91&#46;6%<\/strong>).<\/li>\n<li>La <strong>branche 2<\/strong> pr\u00e9sente \u00e0 son tour un noeud, qui se divise en deux branches (les branches 4 et 5). La <strong>branche 4<\/strong> correspond aux individus tels que <strong>Flashitude &lt; 65<\/strong>. Il y a <strong>58<\/strong> individus dans cette branche dont seulement <strong>20 \u00ab\u00a0oui\u00a0\u00bb<\/strong>. C&rsquo;est donc le <strong>\u00ab\u00a0non\u00a0\u00bb<\/strong> qui l&#8217;emporte (\u00e0 <strong>65%<\/strong>). La <strong>branche 5<\/strong> correspond au reste des individus (tels que <strong>Flashitude \u2004\u2265\u2004 65<\/strong>). Il y a <strong>65<\/strong> individus dans cette branche dont seulement <strong>8 \u00ab\u00a0non\u00a0\u00bb<\/strong>. C&rsquo;est donc le <strong>\u00ab\u00a0oui\u00a0\u00bb<\/strong> qui l&#8217;emporte (\u00e0 <strong>87&#46;5%<\/strong>).<\/li>\n<li>etc.<\/li>\n<\/ul>\n<h2>Comment \u00e7a marche?<\/h2>\n<p>Dans cette partie je vais expliquer comment sont \u00e9tablis les crit\u00e8res de d\u00e9cision abord\u00e9s ci-dessus. L&rsquo;arbre de d\u00e9cision est cr\u00e9\u00e9 de sorte que chaque noeud divise un ensemble d&rsquo;individus en <strong>deux sous-ensembles (correspondant aux 2 branches) les plus homog\u00e8nes possibles<\/strong> en terme de variable \u00e0 pr\u00e9dire.<\/p>\n<p>Pour calculer l&rsquo;h\u00e9t\u00e9rog\u00e9n\u00e9it\u00e9 d&rsquo;un ensemble d&rsquo;individus, on a recours \u00e0 une mesure appel\u00e9e <strong>impuret\u00e9<\/strong>.<\/p>\n<h1>Calcul de l&rsquo;impuret\u00e9<\/h1>\n<p>Pour quantifier l&rsquo;<strong>impuret\u00e9 d&rsquo;un \u00e9chantillon<\/strong> (i.e. son h\u00e9t\u00e9rog\u00e9n\u00e9it\u00e9 en termes de classes), on utilise une fonction, dite <strong>index de Gini<\/strong>.<\/p>\n<p>(NB: tous les codes dans cette sous-partie ne sont pas \u00e0 reproduire pour construire un arbre d\u00e9cisionnel, ils servent simplement \u00e0 illustrer la mani\u00e8re dont l&rsquo;arbre se construit, \u00e9tape par \u00e9tape!)<\/p>\n<p>L&rsquo;index de Gini s&rsquo;applique \u00e0 une probabilit\u00e9 (par exemple probabilit\u00e9 d&rsquo;une classe <em>i<\/em>, <em>p<\/em><sub><em>i<\/em><\/sub>):<\/p>\n<pre><code>    $$ Gini(p_i)=p_i(1-p_i) $$\n<\/code><\/pre>\n<p>Plus la probabilit\u00e9 d&rsquo;une classe <em>i<\/em> est proche de 0.5, (i.e. plus l&rsquo;\u00e9chantillon semble h\u00e9t\u00e9rog\u00e8ne pour la classe <em>i<\/em>), et plus l&rsquo;index de Gini est \u00e9lev\u00e9.<\/p>\n<p>Pour calculer l&rsquo;impuret\u00e9 d&rsquo;un \u00e9chantillon, on somme les indices de Gini pour l&rsquo;ensemble des classes.<\/p>\n<pre><code>calcul_impurete=function(x){\n  probas=table(x)\/length(x)\n  impurete=sum(probas*(1-probas))\n  return(impurete)\n}\n\nprobas=table(Achat)\/length(Achat)\nimpurete=calcul_impurete(Achat)\n<\/code><\/pre>\n<p>Consid\u00e9rons l&rsquo;ensemble des donn\u00e9es. On a 51.2821% de classe \u00ab\u00a0non\u00a0\u00bb et 48.7179% de classe \u00ab\u00a0oui\u00a0\u00bb. Cela correspond \u00e0 une impuret\u00e9 de 0.4997.<\/p>\n<h1>Calcul de la r\u00e9duction d&rsquo;impuret\u00e9<\/h1>\n<p>Chacun des noeuds de l&rsquo;arbre est construit de mani\u00e8re \u00e0 repr\u00e9senter la <strong>plus grande r\u00e9duction d&rsquo;impuret\u00e9 possible<\/strong>. C&rsquo;est-\u00e0-dire que l&rsquo;on cherche la <strong>variable<\/strong> et le <strong>seuil<\/strong> qui vont maximiser la diff\u00e9rence entre l&rsquo;impuret\u00e9 de la branche-parent (A) et l&rsquo;impuret\u00e9 des branches-enfants (\u00e0 gauche -L- et \u00e0 droite -R-):<\/p>\n<pre><code>    $$ \n    \\Delta I=pr(A)I(A)-pr(A_L)I(A_L)-pr(A_R)I(A_R)\n    $$\n<\/code><\/pre>\n<p>o\u00f9 <em>pr(A)<\/em> correspond \u00e0 la probabilit\u00e9 de la branche <em>A<\/em>.<\/p>\n<p>Consid\u00e9rons ainsi le premier noeud de l&rsquo;arbre ci-dessus.<\/p>\n<p>Nous avons vu que l&rsquo;impuret\u00e9 pour la branche principale de l&rsquo;arbre \u00e9tait:<\/p>\n<pre><code>prA=1\nIA=calcul_impurete(Achat)\nprint(IA)\n\n## [1] 0.4997\n<\/code><\/pre>\n<p>Consid\u00e9rons le descripteur (\u00ab\u00a0Branchitude\u00a0\u00bb) et le seuil (85) indiqu\u00e9s par l&rsquo;arbre de d\u00e9cision calcul\u00e9 par la fonction <code>rpart<\/code>:<\/p>\n<pre><code>n=length(Achat)\nindL=which(Branchitude&lt;85)\nindR=which(Branchitude&gt;=85)\nprL=length(indL)\/n\nprR=length(indR)\/n\nIL=calcul_impurete(Achat[indL])\nIR=calcul_impurete(Achat[indR])\n\nperte_impurete=prA*IA-prL*IL-prR*IR\nprint(perte_impurete)\n\n## [1] 0.06708\n<\/code><\/pre>\n<p>Cette valeur de perte d&rsquo;impuret\u00e9 est la <strong>valeur maximale<\/strong> que l&rsquo;on puisse obtenir pour le premier noeud, parmi tous les descripteurs et tous les seuils possibles.<\/p>\n<p>Pour vous en convaincre, vous pouvez tester quelques autres possibilit\u00e9s (nous n&rsquo;allons pas toutes les tester ici&#8230;)<\/p>\n<p>Consid\u00e9rons par exemple ce qu&rsquo;on obtiendrait avec une autre valeur de seuil (65 au lieu de 85):<\/p>\n<pre><code>prA=1\nindL=which(Branchitude&lt;65)\nindR=which(Branchitude&gt;=65)\n\nprL=length(indL)\/n\nprR=length(indR)\/n\nIL=calcul_impurete(Achat[indL])\nIR=calcul_impurete(Achat[indR])\n\nperte_impurete=prA*IA-prL*IL-prR*IR\nprint(perte_impurete)\n\n## [1] 0.0158\n<\/code><\/pre>\n<p>ou encore, consid\u00e9rons un autre descripteur, par exemple, la \u00ab\u00a0Flashitude\u00a0\u00bb:<\/p>\n<pre><code>prA=1\nindL=which(Flashitude&lt;65)\nindR=which(Flashitude&gt;=65)\n\nn=length(Achat)\nprL=length(indL)\/n\nprR=length(indR)\/n\nIA=calcul_impurete(Achat)\nIL=calcul_impurete(Achat[indL])\nIR=calcul_impurete(Achat[indR])\n\nperte_impurete=prA*IA-prL*IL-prR*IR\nprint(perte_impurete)\n\n## [1] 0.0501\n<\/code><\/pre>\n<p>Dans ces deux cas, la perte d&rsquo;impuret\u00e9 est effectivement moindre que celle correspondant \u00e0 la sortie du mod\u00e8le (ouf!).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Qu&rsquo;est-ce que c&rsquo;est? Les arbres d\u00e9cisionnels font partie des m\u00e9thodes d&rsquo;apprentissage supervis\u00e9, et font \u00e0 ce titre partie de la bo\u00eete \u00e0 outils du parfait petit dataminer. Ils visent \u00e0 pr\u00e9dire les valeurs prises par une variable en fonction d&rsquo;un jeu de variables d&rsquo;entr\u00e9e (qu&rsquo;on appellera ici les descripteurs). Cette pr\u00e9diction se fait \u00e0 travers la construction d&rsquo;un arbre dont chaque noeud correspond \u00e0 une d\u00e9cision quant \u00e0 la valeur.. <a href=\"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/classification-par-arbres-decisionnels\/\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-247","post","type-post","status-publish","format-standard","hentry","category-tous-les-posts"],"_links":{"self":[{"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/posts\/247","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/comments?post=247"}],"version-history":[{"count":26,"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/posts\/247\/revisions"}],"predecessor-version":[{"id":1093,"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/posts\/247\/revisions\/1093"}],"wp:attachment":[{"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/media?parent=247"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/categories?post=247"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/perso.ens-lyon.fr\/lise.vaudor\/wp-json\/wp\/v2\/tags?post=247"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}