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

Код классификационного决策 дерева на python

Деревья решений обычно используются в машинном обучении для классификации.

Преимущества: низкая сложность вычислений, легко понимаемые результаты, нечувствительность к отсутствию промежуточных значений, может обрабатывать данные с несовместимыми признаками.
Недостатки: может возникнуть проблема чрезмерного соответствия.
Применяется к типам данных: числовым и категориальным.

1. Информация о增益е

Цель разделения данных заключается в том, чтобы сделать неупорядоченные данные более упорядоченными. Одним из методов организации хаотических данных является использование мер информации из теории информации. Как правило, используется информация о增益е, которая представляет собой уменьшение энтропии данных до и после их разделения. Информация с большей хаотичностью имеет большую энтропию, а наибольший增益 информации является лучшим выбором.
熵定义为信息的期望,符号xi的信息定义为:

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

计算信息熵的代码如下:

def calcShannonEnt(dataSet):
  numEntries = len(dataSet)
  labelCounts = {}
  для featVec в 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]/numEntries)*math.log2(labelCounts[key]/numEntries)
  возврат shannonEnt

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

2.划分数据集

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

def splitDataSet(dataSet,axis,value):
  retDataset = []
  для featVec в dataSet:
    если featVec[axis] == value:
      newVec = featVec[:axis]
      newVec.extend(featVec[axis+1:])
      retDataset.append(newVec)
  возврат retDataset

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

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

def chooseBestFeatureToSplit(dataSet):
  numFeatures = длина dataSet[0] - 1
  bestInfoGain = 0
  bestFeature = -1
  baseEntropy = calcShannonEnt(dataSet)
  для i в range(numFeatures):
    allValue = [example[i] for example in dataSet]#列表推倒,创建新的列表
    allValue = set(allValue)#最快得到列表中唯一元素值的方法
    newEntropy = 0
    для value в allValue:
      splitset = splitDataSet(dataSet,i,value)
      newEntropy = newEntropy + длина splitset / длина dataSet * calcShannonEnt(splitset)
    infoGain = baseEntropy - newEntropy
    если infoGain > bestInfoGain:
      bestInfoGain = infoGain
      bestFeature = i
  возврат bestFeature

4.递归创建决策树

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

def majorityCnt(classList):
 classCount = {}
 для value в classList:
  если value не в classCount: classCount[value] = 0
  classCount[value] += 1
 classCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
 возврат classCount[0][0] 

生成决策树:

def createTree(dataSet,labels):
 classList = [example[-1] для example в dataSet]
 labelsCopy = labels[:]
 если classList.count(classList[0]) равна len(classList):
  возврат classList[0]
 если длина 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 = {}
 для featVec в 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]/numEntries)*math.log2(labelCounts[key]/numEntries)
 возврат shannonEnt
def splitDataSet(dataSet,axis,value):
 retDataset = []
 для featVec в dataSet:
  если featVec[axis] == value:
   newVec = featVec[:axis]
   newVec.extend(featVec[axis+1:])
   retDataset.append(newVec)
 возврат retDataset
def chooseBestFeatureToSplit(dataSet):
 numFeatures = длина dataSet[0] - 1
 bestInfoGain = 0
 bestFeature = -1
 baseEntropy = calcShannonEnt(dataSet)
 для i в range(numFeatures):
  allValue = [example[i] for example in dataSet]
  allValue = set(allValue)
  newEntropy = 0
  для value в allValue:
   splitset = splitDataSet(dataSet,i,value)
   newEntropy = newEntropy + длина splitset / длина dataSet * calcShannonEnt(splitset)
  infoGain = baseEntropy - newEntropy
  если infoGain > bestInfoGain:
   bestInfoGain = infoGain
   bestFeature = i
 возврат bestFeature
def majorityCnt(classList):
 classCount = {}
 для value в classList:
  если value не в classCount: classCount[value] = 0
  classCount[value] += 1
 classCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
 возврат classCount[0][0]   
def createTree(dataSet,labels):
 classList = [example[-1] для example в dataSet]
 labelsCopy = labels[:]
 если classList.count(classList[0]) равна len(classList):
  возврат classList[0]
 если длина 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. Программные хитрости

Разница между extend и append

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

extend([]), добавляет каждый элемент списка в новый список
append() добавляет содержимое скобок в качестве нового элемента в новый список

Списковый спред

Создание нового списка

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

Изъятие уникальных элементов из списка

allValue = set(allValue)

Сортировка списка/тuples, функция sorted()

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

Копирование списка

labelsCopy = labels[:]

Загрузка кода и данных:Дерево решений

Вот весь контент статьи, мы надеемся, что он поможет вам в изучении, и我们也 надеемся на вашу поддержку и поддержку учебника Yanyao.

Заявление: контент этой статьи был взят из Интернета, авторские права принадлежат их владельцам, контент был предоставлен пользователями Интернета, сайт не обладает правами собственности, не был отредактирован вручную, и не несет ответственности за соответствующие юридические последствия. Если вы обнаружите спорный материал, пожалуйста, отправьте письмо по адресу: notice#oldtoolbag.com (при отправке письма замените # на @) для жалоб,并提供相关证据. При подтверждении факта, сайт немедленно удалит спорный материал.

Вам может понравиться