English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Apprentissage de l'algorithme de classification des arbres de décision en Python

À partir de ce chapitre, nous entrons dans l'apprentissage formel de l'algorithme.

Nous allons apprendre maintenant une classification classique et efficace : l'algorithme de classification arbre de décision.

1et l'algorithme de décision arbre

L'arbre de décision utilise une structure arborescente pour classer les attributs des échantillons, c'est l'algorithme de classification le plus intuitif, et il peut également être utilisé pour la régression. Cependant, pour certains types de classification logique spéciaux, il peut y avoir des difficultés. Par exemple, la logique XOR, l'arbre de décision n'est pas bon pour résoudre ce type de problème.
La construction de l'arbre de décision n'est pas unique, malheureusement, la construction de l'arbre de décision optimal est un problème NP. Par conséquent, la construction d'un bon arbre de décision est un point de recherche important.
J. Ross Quinlan dans1975ont introduit le concept d'entropie d'information dans la construction de l'arbre de décision, c'est-à-dire le célèbre ID3algorithme. Les C4.5, C5.0, CART, etc. sont des améliorations de cette méthode.

L'entropie est le degré de "désordre" et de "mélangisme". Il peut y avoir de la confusion au début de cette notion. Pour comprendre rapidement comment utiliser l'augmentation de l'entropie d'information pour diviser les attributs, vous pouvez consulter l'article de ce frère : Python Machine Learning Decision Tree Algorithm

Si cela ne vous est pas encore clair, regardez cet exemple ci-dessous.

Pour construire un arbre de décision automatique pour choisir de bonnes pommes, pour simplifier, je lui ai fait apprendre ce qui suit :4échantillons :
Échantillon Rouge Grand Bonne pomme 
0         1        1         1 
1         1        0         1 
2         0        1         0 
3         0 0 0 

L'échantillon contient2caractéristiques, A0 représente s'il s'agit d'une pomme rouge. A1représente s'il s'agit d'une grande pomme.

Alors, l'entropie d'information de ce échantillon avant la classification est S = -(1/2 * log(1/2) + 1/2 * log(1/2)) = 1.

L'entropie est1représente l'état le plus confus et le plus désorganisé actuel.

Dans cet exemple, seulement2caractéristiques. Alors, naturellement, il ne peut y en avoir que2arbre de décision, comme illustré ci-dessous :

Il est évident que l'arbre de décision basé sur A0 (rouge) à gauche est supérieur à celui de droite en utilisant A1Un arbre de décision basé sur la division (taille).
Bien sûr, c'est une cognition intuitive. Pour une analyse quantitative, il faut calculer l'augmentation de l'entropie d'information de chaque situation de division.
On choisit d'abord A0 pour la division, et le calcul de l'entropie des sous-nœuds est le suivant :
0,1Les nœuds feuilles ont2exemples positifs, 0 exemples négatifs. L'entropie est : e1 = -(2/2 * log(2/2) + 0/2 * log(0/2)) = 0。
2,3Les nœuds feuilles ont 0 exemples positifs,2exemples négatifs. L'entropie est : e2 = -(0/2 * log(0/2) + 2/2 * log(2/2)) = 0。

Par conséquent, on choisit l'entropie d'information de la division A0 après pour chaque noeud enfant en fonction du poids de la proportion de l'entropie de l'information : E = e1*2/4 + e2*2/4 = 0。
Choisir A0 pour la division de l'entropie d'information gagnée G(S, A0) = S - E = 1 - 0 = 1.

En réalité, les nœuds feuilles de l'arbre de décision représentent déjà des catégories identiques, donc l'entropie est certainement 0.

De même, si vous choisissez A1faire la division, les calculs d'entropie des noeuds sous-jacents de chaque sous-noeud sont les suivants :
0,2les noeuds sous-jacents ont1exemples positifs,1exemples négatifs. L'entropie est : e1 = -(1/2 * log(1/2) + 1/2 * log(1/2)) = 1.
1,3les noeuds sous-jacents ont1exemples positifs,1exemples négatifs. L'entropie est : e2 = -(1/2 * log(1/2) + 1/2 * log(1/2)) = 1.
Par conséquent, choisir A1L'entropie de l'entropie après la division est la pondération pondérée de la proportion de l'entropie de chaque noeud sous-jacent : E = e1*2/4 + e2*2/4 = 1. Cela signifie que la division ne change rien !
Choisir A1G(S, A) est l'entropie d'information gagnée par la division d'information.1)=S - E = 1 - 1 = 0.
Par conséquent, avant chaque division, nous devons simplement calculer la division qui maximise l'entropie d'information.

2、Jeu de données

Pour facilité l'explication et la compréhension, nous utilisons un jeu de données de test extrêmement simple :
1.5 50 maigre 
1.5 60 obèse 
1.6 40 maigre 
1.6 60 obèse 
1.7 60 maigre 
1.7 80 obèse 
1.8 60 maigre 
1.8 90 obèse 
1.9 70 maigre 
1.9 80 obèse 

Il y a au total10des échantillons, chaque échantillon a2des attributs, à savoir la taille et le poids, la troisième colonne est le label de catégorie, indiquant 'obèse' ou 'maigre'. Ces données sont stockées dans1.txt.

Notre tâche est de former un classificateur d'arbre de décision, qui peut classer une personne comme obèse ou maigre en fonction de la taille et du poids.
(Les données sont une déduction subjective de l'auteur, avec une certaine logique, mais ignorez son rationalité)

L'arbre de décision est très naturel pour la branche de logique binaire 'oui' ou 'non'. Mais que faire dans ce jeu de données où la taille et le poids sont des valeurs continues ?

Bien que cela soit un peu ennuyeux, ce n'est pas un problème. Il suffit de trouver les points intermédiaires qui divisent ces valeurs continues en différentes intervalles pour le transformer en un problème de logique binaire.
La tâche de l'arbre de décision de cet exemple est de trouver certains seuils critiques de la taille et du poids, de classer les échantillons en paires en fonction de la logique de plus grand ou plus petit que ces seuils, et de construire l'arbre de décision de haut en bas.

L'utilisation des bibliothèques de machine learning Python est assez simple et élégante.

3、Implémentation en Python

Implémentation en Python comme suit :

# -*- coding: utf-8 -*- 
import numpy as np 
import scipy as sp 
from sklearn import tree 
from sklearn.metrics import precision_recall_curve 
from sklearn.metrics import classification_report 
from sklearn.cross_validation import train_test_split 
''' Lecture des données ''' 
data  = [] 
labels = [] 
with open("data\\1.txt) comme ifile: 
    for line in ifile: 
      tokens = line.strip().split(' ') 
      data.append([float(tk) for tk in tokens[:-1]) 
      labels.append(tokens[-1]) 
x = np.array(data) 
labels = np.array(labels) 
y = np.zeros(labels.shape) 
''''' 标签转换为0 '''/1 ''' 
y[labels=='gras'] =1 
''''' 拆分训练数据与测试数据 ''' 
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2) 
''''' 使用信息熵作为划分标准,对决策树进行训练 ''' 
clf = tree.DecisionTreeClassifier(criterion='entropy') 
print(clf) 
clf.fit(x_train, y_train) 
''''' 把决策树结构写入文件 ''' 
with open("tree.dot", 'w') as f: 
  f = tree.export_graphviz(clf, out_file=f) 
''''' 系数反映每个特征的影响力。越大表示该特征在分类中起到的作用越大 ''' 
print(clf.feature_importances_) 
'''''测试结果的打印''' 
answer = clf.predict(x_train) 
print(x_train) 
print(answer) 
print(y_train) 
print(np.mean(answer == y_train)) 
'''''准确率与召回率''' 
precision, recall, thresholds = precision_recall_curve(y_train, clf.predict(x_train)) 
answer = clf.predict_proba(x)[:,1] 
print(classification_report(y, answer, target_names = ['maigre', 'gras'])) 

les résultats de sortie sont similaires à ceux montrés ci-dessous :
[ 0.2488562  0.7511438]
array([[  1.6,  60. ],
       [  1.7,  60. ],
       [  1.9,  80. ],
       [  1.5,  50. ],
       [  1.6,  40. ],
       [  1.7,  80. ],
       [  1.8,  90. ],
       [  1.5,  60. ])
array([ 1, 0.,  1, 0., 0.,  1,  1,  1.])
array([ 1, 0.,  1, 0., 0.,  1,  1,  1.])
1.0
             precision    recall  f1-score   support
       thin       0.83      1.00      0.91         5
        fat        1.00      0.80      0.89         5
avg / total       1.00      1.00      1.00         8
array([ 0.,  1, 0.,  1, 0.,  1, 0.,  1., 0., 0.])
array([ 0.,  1, 0.,  1, 0.,  1, 0.,  1, 0.,  1.])

Voyons, en testant les données entraînées, l'exactitude est100%. Mais en fin de compte, en testant tous les données, il会出现1échantillons de test ont été classés incorrectement.
points à noter, c'est-à-dire que l'arbre de décision de cet exemple absorbe bien les règles du jeu de données d'entraînement, mais la prédictivité est légèrement mauvaise.
Il y a3points doivent être mentionnés, ce qui sera utilisé dans l'apprentissage automatique ultérieur.

1et la séparation des données d'entraînement et des données de test.

Cela est fait pour faciliter la validation croisée. La validation croisée est faite pour tester pleinement la stabilité du classificateur.
dans le code2représente la prise de données au hasard20% des données sont utilisées comme données de test. Le reste80% sont utilisés pour entraîner l'arbre de décision.
Autrement dit10échantillons ont été pris au hasard8entraînement. Le jeu de données de cet article est petit, et l'objectif ici est de voir que, en raison de la prise de données d'entraînement aléatoire, chaque arbre de décision construit à chaque fois est différent.

2et les différents facteurs d'influence des caractéristiques.

Les différences des poids des caractéristiques des échantillons ont une grande influence sur la classification. Il est également très important de voir l'influence de chaque échantillon sur la classification après la classification.
Dans cet exemple, le poids de la taille est de 0.25, poids est de 0.75Voyons, l'importance de poids est bien supérieure à celle de la taille. Pour le jugement de la corpulence, c'est aussi très logique.

3et taux de rappel.

ce2est une des principales normes pour évaluer l'exactitude du classificateur. Par exemple, à la fin, tous10résultat de test de chaque échantillon entré dans le classificateur :
résultat de test : array([ 0.,  1, 0.,  1, 0.,  1, 0.,  1., 0., 0.])
résultat réel : array([ 0.,  1, 0.,  1, 0.,  1, 0.,  1, 0.,  1.])
taux de précision pour classer en thin est de 0.83. C'est parce que le classificateur a distingué6un thin, dont5un thin, dont5/6=0.83.
taux de rappel pour classer en thin est1.00. C'est parce que dans le jeu de données, il y avait5un thin, tandis que le classificateur les a tous classés correctement (même si un fat a été classé en thin !), taux de rappel5/5=1.
taux de précision pour classer en fat est1.00. Ne plus mentionner.
taux de rappel pour classer en fat est de 0.80. C'est parce que dans le jeu de données, il y avait5fat, tandis que le classificateur ne distinguait que4un (en divisant un fat en thin !), taux de rappel4/5=0.80。
Souvent, surtout dans les cas où la classification des données est difficile, l'exactitude et le rappel sont souvent contradictoires. Vous devrez peut-être trouver un point de balance optimal selon vos besoins.
Par exemple, dans cet exemple, votre objectif est de trouver le plus possible de véritables obèses (exactitude), ou de trouver le plus possible d'obèses (rappel).

Le code a également écrit la structure de l'arbre de décision dans tree.dot. Ouvrez ce fichier, il est facile de dessiner un arbre de décision, et vous pouvez également voir plus d'informations de classification de l'arbre de décision.
Voici le tree.dot de cet article :

digraph Tree { 
0 [label = "X[1] <= 55.0000\nentropy = 0.954434002925
samples = 8", shape="box"] ; 
1 [label = "entropy = 0.0000\nsamples = 2
value = [ 2. 0.]", shape="box"] ; 
0 -> 1 ; 
2 [label = "X[1] <= 70.0000\nentropy = 0.650022421648
samples = 6", shape="box"] ; 
0 -> 2 ; 
3 [label = "X[0] <= 1.6500\nentropy = 0.918295834054
samples = 3", shape="box"] ; 
2 -> 3 ; 
4 [label = "entropy = 0.0000\nsamples = 2
value = [ 0. 2]. "shape = "box"] ; 
3 -> 4 ; 
5 [label = "entropy = 0.0000\nsamples = 1
value = [ 1. 0.]", shape="box"] ; 
3 -> 5 ; 
6 [label = "entropy = 0.0000\nsamples = 3
value = [ 0. 3]. "shape = "box"] ; 
2 -> 6 ; 
} 

Selon cette information, l'arbre de décision devrait être de la forme suivante :

Voici la totalité du contenu de cet article, j'espère qu'il vous sera utile dans vos études, et que vous souteniez également le tutoriel Yelling.

Déclaration : le contenu de cet article est来源于网络,propre à ses auteurs respectifs, contribué et téléversé par les utilisateurs d'Internet, ce site ne détient pas de droits de propriété, n'a pas été édité par l'homme, et n'assume aucune responsabilité juridique connexe. Si vous trouvez du contenu susceptible de violer les droits d'auteur, vous êtes invité à envoyer un e-mail à : notice#oldtoolbag.com (veuillez remplacer # par @ lors de l'envoi d'un e-mail pour signaler une violation, et fournir des preuves pertinentes. Une fois vérifié, ce site supprimera immédiatement le contenu suspect de violation de droits d'auteur.)

Vous pourriez aussi aimer