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

Code für die Implementierung eines Klassifikationsdecision trees in Python schreiben

Decision Trees werden in der Regel in der maschinellen Lernung zur Klassifizierung verwendet.

Vorteile: Die Komplexität der Berechnung ist nicht hoch, die Ergebnisse sind leicht verständlich, sie sind nicht empfindlich gegenüber fehlenden Zwischenwerten und können irrelevante Merkmalsdaten verarbeiten.
Nachteile: Es kann zu einem Übermaß an Übereinstimmungen kommen.
Anwendbare Datentypen: numerische und nominalen Typen.

1.信息增益

划分数据集的目的是:将无序的数据变得更加有序。组织杂乱无章数据的一种方法就是使用信息论度量信息。通常采用信息增益,信息增益是指数据划分前后信息熵的减少值。信息越无序信息熵越大,获得信息增益最高的特征就是最好的选择。
熵定义为信息的期望,符号xi的信息定义为:

其中p(xi)为该分类的概率。
熵,即信息的期望值为:

计算信息熵的代码如下:

def calcShannonEnt(dataSet):
  numEntries = len(dataSet)
  labelCounts = {}
  für featVec in dataSet:
    currentLabel = featVec[-1]
    if currentLabel not in labelCounts:
      labelCounts[currentLabel] = 0
    labelCounts[currentLabel] += 1
  shannonEnt = 0
  for key in labelCounts:
    shannonEnt = shannonEnt - (labelCounts[key]/Anzahl der Einträge)*math.log}2(labelCounts[key]/Anzahl der Einträge)
  return shannonEnt

可以根据信息熵,按照获取最大信息增益的方法划分数据集。

2.划分数据集

划分数据集就是将所有符合要求的元素抽出来。

def splitDataSet(dataSet, axis, value):
  retDataset = []
  für featVec in dataSet:
    Wenn featVec[axis] == value:
      newVec = featVec[:axis]
      newVec.extend(featVec[axis+1:])
      retDataset.append(newVec)
  return retDataset

3.选择最好的数据集划分方式

信息增益是熵的减少或者是信息无序度的减少。

def chooseBestFeatureToSplit(dataSet):
  numFeatures = Länge von dataSet[0] - 1
  bestInfoGain = 0
  bestFeature = -1
  baseEntropy = calcShannonEnt(dataSet)
  für i in range(numFeatures):
    allValue = [example[i] for example in dataSet]#列表推倒,创建新的列表
    allValue = set(allValue)#最快得到列表中唯一元素值的方法
    newEntropy = 0
    für value in allValue:
      splitset = splitDataSet(dataSet, i, value)
      newEntropy = newEntropy + Länge von splitset/Länge von dataSet*calcShannonEnt(splitset)
    infoGain = baseEntropy - newEntropy
    Wenn infoGain > bestInfoGain:
      bestInfoGain = infoGain
      bestFeature = i
  return bestFeature

4.递归创建决策树

结束条件为:程序遍历完所有划分数据集的属性,或每个分支下的所有实例都具有相同的分类。
当数据集已经处理了所有属性,但是类标签还不唯一时,采用多数表决的方式决定叶子节点的类型。

def majorityCnt(classList):
 classCount = {}
 für value in classList:
  Wenn value nicht in classCount enthalten ist: classCount[value] = 0
  classCount[value] += 1
 classCount = sorted(classCount.items(), key=operator.itemgetter(1, reverse=True)
 return classCount[0][0] 

生成决策树:

def createTree(dataSet, labels):
 classList = [example[-1z.B. für each example in dataSet]
 labelsCopy = labels[:]
 Wenn die Anzahl der classList[0] in classList mit der Länge von classList gleich ist:
  return classList[0]
 if len(dataSet[0]) == 1:
  return majorityCnt(classList)
 bestFeature = chooseBestFeatureToSplit(dataSet)
 bestLabel = labelsCopy[bestFeature]
 myTree = {bestLabel:{}}
 featureValues = [example[bestFeature] for example in dataSet]
 featureValues = set(featureValues)
 del(labelsCopy[bestFeature])
 for value in featureValues:
  subLabels = labelsCopy[:]
  myTree[bestLabel][value] = createTree(splitDataSet(dataSet, bestFeature, value), subLabels)
 return myTree

5.测试算法——使用决策树分类

同样采用递归的方式得到分类结果。

def classify(inputTree, featLabels, testVec):
 currentFeat = list(inputTree.keys())[0]
 secondTree = inputTree[currentFeat]
 try:
  featureIndex = featLabels.index(currentFeat)
 except ValueError as err:
  print('yes')
 try:
  for value in secondTree.keys():
   if value == testVec[featureIndex]:
    if type(secondTree[value]).__name__ == 'dict':
     classLabel = classify(secondTree[value], featLabels, testVec)
    else:
     classLabel = secondTree[value]
  return classLabel
 except AttributeError:
  print(secondTree)

6.完整代码如下

import numpy as np
import math
import operator
def createDataSet():
 dataSet = [[1,1,'yes'],
    [1,1,'yes'],
    [1,0,'no'],
    [0,1,'no'],
    [0,1,'no'],]
 label = ['no surfacing','flippers']
 return dataSet, label
def calcShannonEnt(dataSet):
 numEntries = len(dataSet)
 labelCounts = {}
 für featVec in dataSet:
  currentLabel = featVec[-1]
  if currentLabel not in labelCounts:
   labelCounts[currentLabel] = 0
  labelCounts[currentLabel] += 1
 shannonEnt = 0
 for key in labelCounts:
  shannonEnt = shannonEnt - (labelCounts[key]/Anzahl der Einträge)*math.log}2(labelCounts[key]/Anzahl der Einträge)
 return shannonEnt
def splitDataSet(dataSet, axis, value):
 retDataset = []
 für featVec in dataSet:
  Wenn featVec[axis] == value:
   newVec = featVec[:axis]
   newVec.extend(featVec[axis+1:])
   retDataset.append(newVec)
 return retDataset
def chooseBestFeatureToSplit(dataSet):
 numFeatures = Länge von dataSet[0] - 1
 bestInfoGain = 0
 bestFeature = -1
 baseEntropy = calcShannonEnt(dataSet)
 für i in range(numFeatures):
  allValue = [example[i] for example in dataSet]
  allValue = set(allValue)
  newEntropy = 0
  für value in allValue:
   splitset = splitDataSet(dataSet, i, value)
   newEntropy = newEntropy + Länge von splitset/Länge von dataSet*calcShannonEnt(splitset)
  infoGain = baseEntropy - newEntropy
  Wenn infoGain > bestInfoGain:
   bestInfoGain = infoGain
   bestFeature = i
 return bestFeature
def majorityCnt(classList):
 classCount = {}
 für value in classList:
  Wenn value nicht in classCount enthalten ist: classCount[value] = 0
  classCount[value] += 1
 classCount = sorted(classCount.items(), key=operator.itemgetter(1, reverse=True)
 return classCount[0][0]   
def createTree(dataSet, labels):
 classList = [example[-1z.B. für each example in dataSet]
 labelsCopy = labels[:]
 Wenn die Anzahl der classList[0] in classList mit der Länge von classList gleich ist:
  return classList[0]
 if len(dataSet[0]) == 1:
  return majorityCnt(classList)
 bestFeature = chooseBestFeatureToSplit(dataSet)
 bestLabel = labelsCopy[bestFeature]
 myTree = {bestLabel:{}}
 featureValues = [example[bestFeature] for example in dataSet]
 featureValues = set(featureValues)
 del(labelsCopy[bestFeature])
 for value in featureValues:
  subLabels = labelsCopy[:]
  myTree[bestLabel][value] = createTree(splitDataSet(dataSet, bestFeature, value), subLabels)
 return myTree
def classify(inputTree, featLabels, testVec):
 currentFeat = list(inputTree.keys())[0]
 secondTree = inputTree[currentFeat]
 try:
  featureIndex = featLabels.index(currentFeat)
 except ValueError as err:
  print('yes')
 try:
  for value in secondTree.keys():
   if value == testVec[featureIndex]:
    if type(secondTree[value]).__name__ == 'dict':
     classLabel = classify(secondTree[value], featLabels, testVec)
    else:
     classLabel = secondTree[value]
  return classLabel
 except AttributeError:
  print(secondTree)
if __name__ == "__main__":
 dataset, label = createDataSet()
 myTree = createTree(dataset, label)
 a = [1,1]
 print(classify(myTree, label, a))

7. Programmier-Tricks

Unterschied zwischen extend und append

 newVec.extend(featVec[axis+1:])
 retDataset.append(newVec)

extend([]), fügt die Elemente der Liste nacheinander zur neuen Liste hinzu
append() fügt den Inhalt in Klammern als neues Element zur neuen Liste hinzu

Listendeklaration

Erstellen eines neuen Listen-Styles

allValue = [example[i] for example in dataSet]

Extrahieren einzigartiger Elemente aus einer Liste

allValue = set(allValue)

Liste/Sortieren von Tupeln, sorted() Funktion

classCount = sorted(classCount.items(), key=operator.itemgetter(1, reverse=True)

Kopieren von Listen

labelsCopy = labels[:]

Download von Code und Datensätzen:Entscheidungsbaum

Das ist der gesamte Inhalt dieses Artikels. Wir hoffen, dass er Ihnen bei Ihrem Lernen hilft und dass Sie die Anleitungshilfe mehr unterstützen.

Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet entnommen und gehört dem Urheberrechtlichem Eigentümer. Der Inhalt wurde von Internetnutzern selbstständig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht von Hand bearbeitet. Sie übernimmt auch keine rechtlichen Verantwortlichkeiten. Wenn Sie urheberrechtlich relevante Inhalte entdecken, freuen wir uns über eine E-Mail an: notice#oldtoolbag.com (Bitte ersetzen Sie # durch @, wenn Sie eine E-Mail senden, um zu melden, und fügen Sie relevante Beweise bei. Bei nachgewiesener Täuschung wird diese Website den fraglichen urheberrechtlichen Inhalt sofort löschen.)

Möchten Sie auch mögen