python基于ID3思想的决策树

yipeiwu_com5年前Python基础

这是一个判断海洋生物数据是否是鱼类而构建的基于ID3思想的决策树,供大家参考,具体内容如下

# 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'],
        [0,0,'maybe']]
  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 -= prob * 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)
  return retDataSet


def chooseBestFeatureToSplit(dataSet):
  numFeatures = len(dataSet[0]) - 1 # 因为数据集的最后一项是标签
  baseEntropy = calcShannonEnt(dataSet)
  bestInfoGain = 0.0
  bestFeature = -1
  for i in range(numFeatures):
    featList = [example[i] for 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 += prob * calcShannonEnt(subDataSet)
    infoGain = baseEntropy - newEntropy
    if infoGain > bestInfoGain:
      bestInfoGain = infoGain
      bestFeature = i
  return bestFeature


# 因为我们递归构建决策树是根据属性的消耗进行计算的,所以可能会存在最后属性用完了,但是分类
# 还是没有算完,这时候就会采用多数表决的方式计算节点分类
def majorityCnt(classList):
  classCount = {}
  for vote in classList:
    if vote not in classCount.keys():
      classCount[vote] = 0
    classCount[vote] += 1
  return max(classCount)


def createTree(dataSet, labels):
  classList = [example[-1] for example in dataSet]
  if classList.count(classList[0]) == len(classList): # 类别相同则停止划分
    return classList[0]
  if len(dataSet[0]) == 1: # 所有特征已经用完
    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[:] # 为了不改变原始列表的内容复制了一下
    myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet,
                                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()

最后我们测试一下这个脚本即可,如果想把这个生成的决策树用图像画出来,也只是在需要在脚本里面定义一个plottree的函数即可。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持【听图阁-专注于Python设计】。

相关文章

python或C++读取指定文件夹下的所有图片

本文实例为大家分享了python或C++读取指定文件夹下的所有图片,供大家参考,具体内容如下 1.python读取指定文件夹下的所有图片路径和图片文件名 import cv2 fro...

Django如何自定义分页

Django如何自定义分页

本文实例为大家分享了Django自定义分页的具体代码,供大家参考,具体内容如下 稳扎稳打版 def book(request): # 从URL取参数(访问的页码) page_nu...

详细整理python 字符串(str)与列表(list)以及数组(array)之间的转换方法

前提: list以及array是python中经常会用到的数据类型,当需要对list以及array进行文件的读写操作的时候,由于write函数参数需要的是一个str,所以这时就需要对l...

Python中的id()函数指的什么

Python官方文档给出的解释是 id(object) Return the “identity” of an object. This is an integer (or long i...

Django框架封装外部函数示例

Django框架封装外部函数示例

本文实例讲述了Django框架封装外部函数。分享给大家供大家参考,具体如下: 需求:我们来模拟用户登录,验证是否输入正确的用户名和密码 1.构建登录表单 <form met...