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

Implémentation de l'arbre de décision en Python

L'exemple de cet article partage le code Python pour la mise en œuvre de l'arbre de décision, pour votre référence, le contenu est le suivant

Avantages et inconvénients de l'algorithme :

Avantage : le degré de complexité de calcul n'est pas élevé, les résultats sont faciles à comprendre, insensible aux valeurs manquantes intermédiaires, peut traiter des données de caractéristiques non pertinentes

Inconvénient : peut entraîner des problèmes de surajustement

Type de données applicables : numériques et nominaux

Idée de l'algorithme :

1.Idée globale de construction d'un arbre de décision :

En termes simples, un arbre de décision ressemble à un if-La structure de l'else est la même, et son résultat est un arbre qui peut être généré en commençant par la racine et en continuant à faire des choix jusqu'aux feuilles, mais ici l'if-else ne peut pas être ce que nous pensons de configurer, ce que nous devons faire est de fournir une méthode permettant à l'ordinateur de obtenir l'arbre de décision dont nous avons besoin. Le point central de cette méthode réside dans la manière dont on choisit les caractéristiques utiles et comment on les sélectionne dans le meilleur ordre, de la racine aux feuilles. Une fois cela fait, nous pouvons également construire récursivement un arbre de décision

2.Gain d'information

Le principe le plus important du segmentage des données est de rendre les données désordonnées plus ordonnées. Comme cela implique également la question de l'ordre et de l'ind秩序, il est naturel de penser à l'entropie d'information. Ici, nous calculons également l'entropie d'information (une autre méthode est l'impureté de Gini). L'équation est la suivante :

Les exigences que les données doivent remplir :

1 Les données doivent être des listes composées d'éléments de liste, et tous les éléments des colonnes doivent avoir la même longueur de données
2 La dernière colonne des données ou l'élément final de chaque instance doit être le label de catégorie de l'instance actuelle

Fonction :

calcShannonEnt(dataSet)

Calculer l'entropie de Shannon du jeu de données, en deux étapes: la première étape est de calculer la fréquence, et la deuxième étape est de calculer l'entropie de Shannon selon l'équation

splitDataSet(dataSet, aixs, value)

Segmenter le jeu de données, regrouper tous les valeurs qui satisfont X[aixs] == value, et retourner un ensemble segmenté (sans inclure l'attribut aixs utilisé pour le segment, car il n'est pas nécessaire)

chooseBestFeature(dataSet)

Choisir les meilleures propriétés pour le segment, la pensée est très simple: diviser chaque propriété, voir laquelle est la meilleure. Ici, un ensemble est utilisé pour sélectionner les éléments uniques de la liste, ce qui est une méthode très rapide

majorityCnt(classList)

因为我们递归构建决策树是根据属性的消耗进行计算的,所以可能会存在最后属性用完了,但是分类还是没有算完,这时候就会采用多数表决的方式计算节点分类

createTree(dataSet, labels)

基于递归构建决策树。这里的label更多是对于分类特征的名字,为了更好看和后面的理解。

#coding=utf-8
import operator
from math import log
import time
def createDataSet():
  dataSet=[[1,1,'yes'],
      [1,1,'yes'],
      [1,0,'no'],
      [0,1,'no'],
      [0,1,'no']]
  labels = ['no surfaceing','flippers']
  return dataSet, labels
#计算香农熵
def calcShannonEnt(dataSet):
  numEntries = len(dataSet)
  labelCounts = {}
  for feaVec in dataSet:
    currentLabel = feaVec[-1]
    if currentLabel not in labelCounts:
      labelCounts[currentLabel] = 0
    labelCounts[currentLabel] += 1
  shannonEnt = 0.0
  for key in labelCounts:
    prob = float(labelCounts[key])/numEntries
    shannonEnt -= * log(prob, 2)
  return shannonEnt
def splitDataSet(dataSet, axis, value):
  retDataSet = []
  for featVec in dataSet:
    if featVec[axis] == value:
      reducedFeatVec = featVec[:axis]
      reducedFeatVec.extend(featVec[axis+1:])
      retDataSet.append(reducedFeatVec)
  retourne retDataSet
def chooseBestFeatureToSplit(dataSet):
  numFeatures = len(dataSet[0]) - 1#因为数据集的最后一项是标签
  baseEntropy = calcShannonEnt(dataSet)
  bestInfoGain = 0.0
  bestFeature = -1
  pour chaque i in range(numFeatures):
    featList = [example[i] pour chaque example in dataSet]
    uniqueVals = set(featList)
    newEntropy = 0.0
    for value in uniqueVals:
      subDataSet = splitDataSet(dataSet, i, value)
      prob = len(subDataSet) / float(len(dataSet))
      newEntropy += * calcShannonEnt(subDataSet)
    infoGain = baseEntropy -newEntropy
    si infoGain > bestInfoGain:
      bestInfoGain = infoGain
      bestFeature = i
  retourne bestFeature
#因为我们递归构建决策树是根据属性的消耗进行计算的,所以可能会存在最后属性用完了,但是分类
#还是没有算完,这时候就会采用多数表决的方式计算节点分类
def majorityCnt(classList):
  classCount = {}
  pour chaque vote in classList:
    si vote not in classCount.keys():
      classCount[vote] = 0
    classCount[vote] += 1
  retourne max(classCount)     
def createTree(dataSet, labels):
  classList = [example[-1] pour chaque example in dataSet
  si classList.count(classList[0]) ==len(classList):#类别相同则停止划分
    retourne classList[0]
  si len(dataSet[0]) == 1:#Toutes les caractéristiques ont été utilisées
    return majorityCnt(classList)
  bestFeat = chooseBestFeatureToSplit(dataSet)
  bestFeatLabel = labels[bestFeat]
  myTree = {bestFeatLabel:{}}
  del(labels[bestFeat])
  featValues = [example[bestFeat] for example in dataSet]
  uniqueVals = set(featValues)
  for value in uniqueVals:
    subLabels = labels[:]#Pour ne pas changer le contenu de la liste originale, une copie a été faite
    myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet," ",subLabels)) 
                    (bestFeat, value),subLabels)
  return myTree
def main():
  data,label = createDataSet()
  t1 = time.clock()
  myTree = createTree(data,label)
  t2 = time.clock()
  print myTree
  print 'execute for ',t2-t1
if __name__=='__main__':
  main()

Voici la fin de l'article, j'espère que cela peut aider à votre apprentissage, et j'espère que vous soutenerez également le tutoriel criant.

Déclaration : Le contenu de cet article est partagé sur Internet, propriété de l'auteur original, le contenu est partagé par les utilisateurs d'Internet, ce site Web ne possède pas de propriété, n'a pas été traité par l'éditeur humain et n'assume aucune responsabilité juridique. Si vous trouvez du contenu susceptible de violer les droits d'auteur, veuillez envoyer un e-mail à : notice#w pour signaler, et fournir des preuves pertinentes.3Déclaration : Le contenu de cet article est tiré du réseau, propriété de l'auteur original, le contenu est contribué et téléchargé par les utilisateurs d'Internet, ce site Web ne possède pas de propriété, n'a pas été traité par l'éditeur humain et n'assume aucune responsabilité juridique. Si vous trouvez du contenu susceptible de violer les droits d'auteur, veuillez envoyer un e-mail à : notice#w pour signaler, et fournir des preuves pertinentes. Une fois confirmé, ce site supprimera immédiatement le contenu suspect de violation de droits d'auteur.

Vous pourriez aussi aimer