Dans ce nouveau TP sur les arbres de décision, on voit comment traiter les attributs nominaux.
À l'issue de ce TP, vous m'envoyez par email un compte-rendu (format odt ou pdf) indiquant la réponse aux questions qui sont posées. Vous m'envoyez également un fichier python réalisant toutes les manipulations de ce TP. Appelez-le tp8.votre-nom.py. Je dois pouvoir exécuter ce fichier en tapant python3 tp8.votre-nom.py et reproduire vos résultats. Cette exécution ne doit pas provoquer d'erreur de python. Remarque : un notebook ne convient pas.
Les attributs nominaux sont faciles à traiter pour induire un arbre de décision mais malheureusement, scikit_learn ne sait pas le faire. Il faut utiliser des moyens détournés pour arriver à les prendre en compte, quoique de manière pas très satisfaisante. Comme c'est l'outil que l'on utilise, on va quand même voir comment faire avec cet outil. Mais je ne peux que vous encouragez à ne pas utiliser cette approche et à vous tourner vers un logiciel sérieux : R (ou encore c4.5). Malheureusement, nous n'avons pas le temps d'apprendre à utiliser R dans les quelques heures que dure ce module.
Nous allons illustrer le principe sur un jeu de données contenant des attributs nominaux et des attributs quantitatifs. Ce jeu de données est disponible à cette url https://philippe-preux.codeberg.page/ensg/miashs/datasets/enoughTip.csv. Je suppose par la suite que vous avez chargé ce jeu de données dans un objet dénommé tips.
Aux États-Unis (et dans d'autres pays), à moins d'être un goujat ou d'avoir été particulièrement mal traité par le serveur, on donne systématiquement un pourboire au restaurant et dans les bars. En effet, le service n'est pas inclus dans la note. En principe, ce pourboire s'élève à au moins 15% de la note.
Chaque ligne de ce jeu de données contient des informations concernant une tablée dans un restaurant :
TOTBILL : le montant de la note,TIP : le montant du pourboire laissé par le client,SEX : le genre du client ayant payé la note,SMOKER : est-il fumeur ou pas ?DAY : le jour,TIME : déjeuner ou dîner ?SIZE : taille de la tablée,enough : est-ce que le pourboire est ≥ 15% ?
Les attributs TOTBILL, TIP et SIZE sont numériques. Les autres attributs sont nominaux. On veut prédire l'attribut enough.
Considérons l'attribut DAY qui vaut sun, sat, fri, ou thurs. Pour pouvoir construire un arbre de décision avec scikit_learn, nous devons le transformer en un attribut numérique. La méthode que l'on va utiliser doit fonctionner quel que soit le nombre de valeurs que peut prendre l'attribut (l'arité de l'attribut). Cet attribut prenant 4 valeurs différentes, il va être transformé en 4 attributs valant 0 ou 1 : chacun de ces 4 attributs correspond donc à l'une des 4 valeurs possibles de l'attribut et 1 seul de ces 4 nouveaux attributs numériques vaudra 1.
Cela pourrait constituer un petit exercice de programmation, mais pandas dispose d'une fonction qui effectue cette transformation pour nous. Faites : pd.get_dummies(tips.DAY).head(). Cela affiche :
fri sat sun thurs 0 0 0 1 0 1 0 0 1 0 2 0 0 1 0 3 0 0 1 0 4 0 0 1 0
>>> tips.loc[:,"DAY"].head() 0 sun 1 sun 2 sun 3 sun 4 sun Name: DAY, dtype: object
pandas composé de 4 colonnes, une colonne par valeur possible.
>>> tips.loc[:,"DAY"].tail() 239 sat 240 sat 241 sat 242 sat 243 thurs Name: DAY, dtype: object
>>> pd.get_dummies(tips.DAY).tail()
fri sat sun thurs
239 0 1 0 0
240 0 1 0 0
241 0 1 0 0
242 0 1 0 0
243 0 0 0 1
Maintenant que l'on sait transformer un attribut en un ensemble d'attributs numériques, il suffit d'ajouter ces 4 attributs au data frame et de retirer l'attribut nominal d'origine. Pour ajouter les colonnes, on utilise la méthode join() de pandas. Pour retirer une colonne, on utilise la méthode drop () de pandas. Cela s'utilise de la manière suivante :
>>> tips = tips.join (pd.get_dummies(tips.DAY)) tips.drop (columns = ["DAY"], inplace=True)
Remarque : visiblement, il y a un bug dans pandas. Si on a préalablement indiqué que le type de DAY est catégorique (avec tips ["DAY"] = tips ["DAY"]. astype ("category")), le join () plante, affiche une cinquantaine de lignes totalement incompréhensibles, ne me demandez pas pourquoi. Dans ce cas, il faut retirer le type catégorique de la colonne (get_dummies().
À faire : faites ce que je viens d'expliquer et traitez de la même manière les autres attributs nominaux (SEX, SMOKER, TIME).
Remarquez que vous pouvez retirer plusieurs colonnes en une seule instruction en indiquant leur nom dans le paramètre columns de la méthode drop().
Le data frame est maintenant utilisable par l'algorithme d'induction d'arbres de décision.
À faire : en suivant la méthode vue précédemment, induire un arbre de décision. Essayez de l'améliorer en modifiant les paramètres de l'arbre.