PC & Mobile

Arbre de décision: Classifier from Scratch: classer le niveau de connaissances de l’élève

Arbre de décision: Classifier from Scratch: classer le niveau de connaissances de l’élève


2.1 Préparation des données

Nous allons utiliser pandas pour le traitement et le nettoyage des données.

Dictionnaire de données
importation pandas comme pddf = pd.read_csv ('data.csv')
df.head ()

D'abord nous importons data.csv fichier puis en le traitant comme un cadre de données de pandas et en jetant un coup d’œil sur les données.

Aperçu des données

Comme nous pouvons le voir, nos données ont 6 colonnes. Nous avons 5 caractéristiques et 1 étiquette. Comme ces données sont déjà nettoyées, il n’est pas nécessaire de les nettoyer et querelles. Cependant, lorsque vous travaillez avec d'autres jeux de données du monde réel, il est important de vérifier les valeurs nulles et les valeurs aberrantes dans le jeu de données et de concevoir les meilleures fonctionnalités.

2.2 Train d'essai divisé

train = df.values[-:20]
test = df.values[-20:]

Ici, nous séparons ou donnons des données en train et testons où les 20 dernières données de notre ensemble de données sont des données de test et les données restantes sont des données de train.

2.3 Écrire notre propre modèle d'apprentissage machine

Il est maintenant temps d’écrire notre classificateur d’arbres de décision.

Mais avant de plonger dans le code, il y a peu de choses à apprendre:

  1. Pour construire l’arbre, nous utilisons un algorithme d’apprentissage Arbre de décision appelé CHARIOT. Il existe d'autres algorithmes d'apprentissage tels que: ID3, C4.5, C5.0 etc. Vous pouvez en apprendre plus sur eux à partir d'ici.
  2. CHARIOT est synonyme d'arbres de classification et de régression. CHARIOT les usages Gini impureté comme métrique pour quantifier à quel point une question permet de démélanger les données ou dans un simple mot, CARD utilise Gini comme fonction de coût pour évaluer les erreurs.
  3. Sous le capot, tous les algorithmes d'apprentissage nous donnent une procédure pour décider quelle question poser et à quel moment.
  4. Vérifier dans quelle mesure la question nous a aidés à démêler les données que nous utilisons Gain d'information. Cela nous aide à réduire l'incertitude et nous l'utilisons pour sélectionner la meilleure question à poser. Etant donné cette question, nous construisons de manière récursive un nœud d'arbre. Nous continuons ensuite à diviser le noeud jusqu'à ce qu'il n'y ait plus de question à poser et nous désignons ce dernier noeud comme une feuille.

2.3.1 Ecriture des fonctions d'assistance

Pour implémenter Decision Tree Classifier, nous devons savoir quelle question poser et à quel moment. Permet d'écrire un code pour cela:

classe CreateQuestion:        def __init __ (auto, colonne, valeur):
self.column = colonne
self.value = valeur
def chèque (auto, données):
val = data[self.column]
return val> = self.value
def __repr __ (auto):

return "Est-ce que% s% s% s?" % (
auto.colonne[-1], "> =", str (self.value))

Ci-dessus, nous avons écrit un CreateQuestion classe qui prend 2 entrées: numéro de colonne et valeur comme une variable d'instance. Il a vérifier méthode qui est utilisée pour comparer la valeur de la fonctionnalité. __repr__ est juste une fonction magique de python pour aider à afficher la question.

Permet de le voir en action:

q = CreateQuestion(0, 0.08)
Créer une question

permet maintenant de vérifier si notre vérifier la méthode fonctionne bien ou pas:

données = train[0]
q.check (données)
Méthode de test de vérification
Méthode de vérification croisée

comme nous pouvons le voir, nous avons une valeur False. Puisque notre valeur 0ᵗʰ en train est 0.0, ce qui n’est pas plus grand ni égal à 0,08, notre méthode fonctionne bien.

Il est maintenant temps de créer une fonction de partition qui nous aide à partitionner nos données en deux sous-ensembles: le premier ensemble contient toutes les données qui sont vraies et le second contient les valeurs fausses.

Permet d'écrire un code pour cela:

def partition (lignes, qsn):

true_rows, false_rows = [], []
pour rangée dans Lignes:
si qsn.check (rangée):
true_rows.append (ligne)
autre:
false_rows.append (rangée)
revenir true_rows, false_rows

notre fonction de partition prend deux entrées: Lignes et un question puis retourne une liste de vraies lignes et fausses lignes.

Voyons cela aussi en action:

true_rows, false_rows = partition (train, CreateQuestion (0, 0.08))
Aperçu des lignes True et False

ici true_rows contient toutes les données ou égale à 0,08 et false_rows contient des données inférieures à 0,08.

Maintenant il est temps d'écrire notre Gini Impurity algorithme. Comme nous en avons discuté plus tôt, cela nous aide à quantifier le degré d’incertitude dans le noeud et Gain d'information permet de quantifier combien une question réduit cette incertitude.

Les mesures d'impuretés sont comprises entre 0 et 1, une valeur inférieure indiquant une incertitude moindre.

def gini (rangées):        count = class_count (lignes)
impureté = 1
pour étiquette dans compte:
probab_of_label = compte[label] / float (len (rangées))
impureté - = probab_of_label ** 2
revenir impureté

Dans notre gini fonction, nous venons de mettre en œuvre la formule pour Gini. Il retourne la valeur d'impureté des lignes données.

compte veriable contient le dictionnaire avec les comptes totaux de la valeur donnée dans l'ensemble de données. class_counts est une fonction d'assistance permettant de compter le nombre total de données présentes dans un jeu de données d'une certaine classe.

def class_counts (lignes):

pour rangée dans Lignes:

label = rangée[-1]
si étiquette ne pas dans compte:
compte[label] = 0
compte[label] + = 1
revenir compte

Voyons voir gini en action:

Gini en action: 1
Gini en action: 2

Comme vous pouvez le voir en image 1 il y a une certaine impureté de sorte qu'il retourne 0,5 et en image 2 il n'y a pas d'impuretés, donc il retourne 0.

Nous allons maintenant écrire du code pour calculer le gain d’information:

def info_gain (gauche, droite, précision actuelle):

p = float (len (à gauche)) / (len (à gauche) + len (à droite))
revenir current_uncertainty - p * gini (gauche)
- (1 - p) * gini (droite)

Le gain d'informations est calculé en soustrayant le nœud de départ d'incertitude avec l'impureté pondérée de deux nœuds enfants.

2.3.2 Assembler le tout

Il est maintenant temps de tout mettre en place.

def find_best_split (rows):

best_gain = 0
best_question = None
current_uncertainty = gini (lignes)
n_features = len (lignes[0]) - 1

pour col dans plage (n_features):

valeurs = set ([row[col] pour rangée dans Lignes])

pour val dans valeurs:
question = Question (col, val)
true_rows, false_rows = partition (lignes, question)

si len (true_rows) == 0 ou len (false_rows) == 0:
Continuez

gain = info_gain (true_rows, false_rows,
current_uncertainty)

si gain> best_gain:
best_gain, best_question = gain, question

revenir best_gain, best_question

Nous avons écrit un find_best_split fonction qui trouve la meilleure question comme en itérant sur toutes les caractéristiques et étiquettes, puis calcule le gain d’information.

Voyons cette fonction en action:

best_gain, best_question = find_best_split (train)
Trouver la meilleure question

Nous allons maintenant écrire notre build_tree une fonction.

def ajustement (caractéristiques, étiquettes):        données = caractéristiques + étiquettes        gain, question = find_best_split (data)

si gain == 0:
revenir Feuille (rangées)

true_rows, false_rows = partition (lignes, question)

# Construire récursivement la vraie branche.
true_branch = build_tree (true_rows)

# Construit récursivement la fausse branche.
false_branch = build_tree (false_rows)

revenir Decision_Node (question, true_branch, false_branch)

Notre en forme la fonction construit essentiellement un arbre pour nous. Il commence par le nœud racine et trouve la meilleure question pour demander ce nœud en utilisant notre find_best_split une fonction. Il itère sur chaque valeur puis divise les données et le gain d’information est calculé. En cours de route, il garde la trace de la question qui produit le plus de gain.

Après cela, s'il reste une question utile à poser, le gain sera plus grand, puis 0, si bien que les rangées sont sous-groupées en branches et qu'il construit récursivement la vraie branche d'abord jusqu'à ce qu'il n'y ait plus de question à poser et que le gain soit 0.

Ce nœud devient alors un Feuille nœud.

code pour notre Feuille la classe ressemble à ceci:

classe Feuille:

def __init __ (auto, rangées):
self.predictions = class_counts (lignes)

Il est titulaire d'un dictionnaire de classe(“Haut”, “Bas”) et le nombre de fois où il apparaît dans les lignes à partir des données qui ont atteint la feuille en cours.

pour le fausse branche le même processus est également appliqué. Après cela devient un Decision_Node.

Le code de notre classe Decision_Node ressemble à ceci:

classe Decision_Node:     
def __init __ (auto, question,
true_branch, false_branch):
self.question = question
self.true_branch = true_branch
self.false_branch = false_branch

Cette classe contient uniquement la référence à la question posée et les deux nœuds enfants obtenus.

maintenant, nous revenons au nœud racine et construisons le fausse branche. Comme il n’y aura pas de question à se poser, c’est le Feuille nœud et nœud racine devient également un Decision_Node.

Voyons voir en forme fonction en action:

_tree = fit (train)

pour imprimer le _arbre nous devons écrire une fonction spéciale.

def print_tree (node, spacing = ""):

# Cas de base: nous avons atteint une feuille
si isinstance (node, Leaf):
impression (espacement + "prédire", node.predictions)
revenir

# Imprimer la question sur ce noeud
impression (spacing + str (node.question))

# Appelle cette fonction récursivement sur la vraie branche
impression (espacement + '-> vrai:')
print_tree (node.true_branch, espacement + "")

# Appelle cette fonction récursivement sur la fausse branche
impression (espacement + '-> faux:')
print_tree (node.false_branch, espacement + "")

cette print_tree La fonction nous aide à visualiser notre arbre de manière géniale.

Échantillon de notre arbre

Nous venons de terminer la construction de notre classificateur d'arbres de décision!

Pour comprendre et voir ce que nous avons construit, écrivons quelques fonctions supplémentaires:

def classer (ligne, noeud):

si isinstance (node, Leaf):
revenir node.predictions

si node.question.check (rangée):
revenir classify (row, node.true_branch)
autre:
revenir classify (row, node.false_branch)

classer fonction nous aide à vérifier la confiance en ligne donnée et un arbre.

classer (train[5], _ arbre)
Échantillon de classification

Comme vous pouvez le voir ci-dessus, notre arbre a classé la valeur donnée comme un milieu avec une confiance de 96.

def print_leaf (count):

total = sum (count.values ​​()) * 1,0
probs = {}
pour lbl dans count.keys ():
probs[lbl] = str (int (compte)[lbl] / total * 100)) + "%"
revenir probs

print_leaf la fonction nous aide à embellir notre prédiction.

Joli imprimé

2.4 Évaluation du modèle

Nous avons construit, visualisé et vu notre arbre en action avec succès.

Maintenant, effectuons une évaluation de modèle simple:

pour rangée dans testing_data:
impression ("Niveau actuel: % s. Niveau prévu: % s"%
(df['LABEL'], print_leaf (classify (row, _tree))))
Prévu sur les données de test

Comme vous pouvez le constater, notre arbre a été bien prévu sur nos données de test, qui ont été isolées des données du train.

Afficher plus

SupportIvy

SupportIvy.com : Un lieu pour partager le savoir et mieux comprendre le monde. Meilleure plate-forme de support gratuit pour vous, Documentation &Tutoriels par les experts.

Articles similaires

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Bouton retour en haut de la page
Fermer