python实现ID3决策树算法


Posted in Python onAugust 29, 2018

ID3决策树是以信息增益作为决策标准的一种贪心决策树算法

# -*- coding: utf-8 -*-


from numpy import *
import math
import copy
import cPickle as pickle


class ID3DTree(object):
  def __init__(self): # 构造方法
    self.tree = {} # 生成树
    self.dataSet = [] # 数据集
    self.labels = [] # 标签集


  # 数据导入函数
  def loadDataSet(self, path, labels):
    recordList = []
    fp = open(path, "rb") # 读取文件内容
    content = fp.read()
    fp.close()
    rowList = content.splitlines() # 按行转换为一维表
    recordList = [row.split("\t") for row in rowList if row.strip()] # strip()函数删除空格、Tab等
    self.dataSet = recordList
    self.labels = labels


  # 执行决策树函数
  def train(self):
    labels = copy.deepcopy(self.labels)
    self.tree = self.buildTree(self.dataSet, labels)


  # 构件决策树:穿件决策树主程序
  def buildTree(self, dataSet, lables):
    cateList = [data[-1] for data in dataSet] # 抽取源数据集中的决策标签列
    # 程序终止条件1:如果classList只有一种决策标签,停止划分,返回这个决策标签
    if cateList.count(cateList[0]) == len(cateList):
      return cateList[0]
    # 程序终止条件2:如果数据集的第一个决策标签只有一个,返回这个标签
    if len(dataSet[0]) == 1:
      return self.maxCate(cateList)
    # 核心部分
    bestFeat = self.getBestFeat(dataSet) # 返回数据集的最优特征轴
    bestFeatLabel = lables[bestFeat]
    tree = {bestFeatLabel: {}}
    del (lables[bestFeat])
    # 抽取最优特征轴的列向量
    uniqueVals = set([data[bestFeat] for data in dataSet]) # 去重
    for value in uniqueVals: # 决策树递归生长
      subLables = lables[:] # 将删除后的特征类别集建立子类别集
      # 按最优特征列和值分隔数据集
      splitDataset = self.splitDataSet(dataSet, bestFeat, value)
      subTree = self.buildTree(splitDataset, subLables) # 构建子树
      tree[bestFeatLabel][value] = subTree
    return tree


  # 计算出现次数最多的类别标签
  def maxCate(self, cateList):
    items = dict([(cateList.count(i), i) for i in cateList])
    return items[max(items.keys())]


  # 计算最优特征
  def getBestFeat(self, dataSet):
    # 计算特征向量维,其中最后一列用于类别标签
    numFeatures = len(dataSet[0]) - 1 # 特征向量维数=行向量维数-1
    baseEntropy = self.computeEntropy(dataSet) # 基础熵
    bestInfoGain = 0.0 # 初始化最优的信息增益
    bestFeature = -1 # 初始化最优的特征轴
    # 外循环:遍历数据集各列,计算最优特征轴
    # i为数据集列索引:取值范围0~(numFeatures-1)
    for i in xrange(numFeatures):
      uniqueVals = set([data[i] for data in dataSet]) # 去重
      newEntropy = 0.0
      for value in uniqueVals:
        subDataSet = self.splitDataSet(dataSet, i, value)
        prob = len(subDataSet) / float(len(dataSet))
        newEntropy += prob * self.computeEntropy(subDataSet)
      infoGain = baseEntropy - newEntropy
      if (infoGain > bestInfoGain): # 信息增益大于0
        bestInfoGain = infoGain # 用当前信息增益值替代之前的最优增益值
        bestFeature = i # 重置最优特征为当前列
    return bestFeature



  # 计算信息熵
  # @staticmethod
  def computeEntropy(self, dataSet):
    dataLen = float(len(dataSet))
    cateList = [data[-1] for data in dataSet] # 从数据集中得到类别标签
    # 得到类别为key、 出现次数value的字典
    items = dict([(i, cateList.count(i)) for i in cateList])
    infoEntropy = 0.0
    for key in items: # 香农熵: = -p*log2(p) --infoEntropy = -prob * log(prob, 2)
      prob = float(items[key]) / dataLen
      infoEntropy -= prob * math.log(prob, 2)
    return infoEntropy


  # 划分数据集: 分割数据集; 删除特征轴所在的数据列,返回剩余的数据集
  # dataSet : 数据集; axis: 特征轴; value: 特征轴的取值
  def splitDataSet(self, dataSet, axis, value):
    rtnList = []
    for featVec in dataSet:
      if featVec[axis] == value:
        rFeatVec = featVec[:axis] # list操作:提取0~(axis-1)的元素
        rFeatVec.extend(featVec[axis + 1:])
        rtnList.append(rFeatVec)
    return rtnList
  # 存取树到文件
  def storetree(self, inputTree, filename):
    fw = open(filename,'w')
    pickle.dump(inputTree, fw)
    fw.close()

  # 从文件抓取树
  def grabTree(self, filename):
    fr = open(filename)
    return pickle.load(fr)

调用代码

# -*- coding: utf-8 -*-

from numpy import *
from ID3DTree import *

dtree = ID3DTree()
# ["age", "revenue", "student", "credit"]对应年龄、收入、学生、信誉4个特征
dtree.loadDataSet("dataset.dat", ["age", "revenue", "student", "credit"])
dtree.train()

dtree.storetree(dtree.tree, "data.tree")
mytree = dtree.grabTree("data.tree")
print mytree

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现360皮肤按钮控件示例
Feb 21 Python
跟老齐学Python之大话题小函数(2)
Oct 10 Python
Python实现堆排序的方法详解
May 03 Python
python音频处理用到的操作的示例代码
Oct 27 Python
Python中循环后使用list.append()数据被覆盖问题的解决
Jul 01 Python
Python实现数据可视化看如何监控你的爬虫状态【推荐】
Aug 10 Python
解决nohup执行python程序log文件写入不及时的问题
Jan 14 Python
python文件选择对话框的操作方法
Jun 27 Python
基于python plotly交互式图表大全
Dec 07 Python
TensorFlow加载模型时出错的解决方式
Feb 06 Python
python如何爬取网页中的文字
Jul 28 Python
Python爬取网页信息的示例
Sep 24 Python
python实现C4.5决策树算法
Aug 29 #Python
python机器学习之KNN分类算法
Aug 29 #Python
深入理解python中sort()与sorted()的区别
Aug 29 #Python
Python实现拷贝/删除文件夹的方法详解
Aug 29 #Python
Python读写zip压缩文件的方法
Aug 29 #Python
使用python生成杨辉三角形的示例代码
Aug 29 #Python
Python实现查询某个目录下修改时间最新的文件示例
Aug 29 #Python
You might like
PHP中在数据库中保存Checkbox数据(2)
2006/10/09 PHP
如何做到多笔资料的同步
2006/10/09 PHP
PHP类的静态(static)方法和静态(static)变量使用介绍
2012/02/19 PHP
PHP中设置时区方法小结
2012/06/03 PHP
php中将指针移动到数据集初始位置的实现代码[mysql_data_seek]
2012/11/01 PHP
如何使用PHP对网站验证码进行破解
2015/09/17 PHP
PHP的PDO常用类库实例分析
2016/04/07 PHP
深入理解PHP类的自动载入机制
2016/09/16 PHP
PHP基于反射机制实现插件的可插拔设计详解
2016/11/10 PHP
php使用PDO事务配合表格读取大量数据插入操作实现方法
2017/02/16 PHP
Laravel5.4框架使用socialite实现github登录的方法
2019/03/20 PHP
js之WEB开发调试利器:Firebug 下载
2007/01/13 Javascript
myFocus slide3D v1.1.0 使用方法与下载
2011/01/12 Javascript
js传中文参数controller里获取参数乱码问题解决方法
2014/01/03 Javascript
javascript内置对象arguments详解
2014/03/16 Javascript
JS+CSS实现弹出全屏灰黑色透明遮罩效果的方法
2014/12/20 Javascript
Nodejs Express4.x开发框架随手笔记
2015/11/23 NodeJs
javascript事件委托的用法及其好处简析
2016/04/04 Javascript
微信小程序三级联动地址选择器的实例代码
2017/07/12 Javascript
JavaScript获取tr td 的三种方式全面总结(推荐)
2017/08/15 Javascript
ant-design-vue中tree增删改的操作方法
2020/11/03 Javascript
小程序角标的添加及绑定购物车数量进行实时更新的实现代码
2020/12/07 Javascript
Python中将字典转换为XML以及相关的命名空间解析
2015/10/15 Python
Python3实现抓取javascript动态生成的html网页功能示例
2017/08/22 Python
python实战串口助手_解决8串口多个发送的问题
2019/06/12 Python
Python将string转换到float的实例方法
2019/07/29 Python
python创建与遍历List二维列表的方法
2019/08/16 Python
用python打开摄像头并把图像传回qq邮箱(Pyinstaller打包)
2020/05/17 Python
优秀团员个人事迹材料
2014/01/29 职场文书
大学生心理活动总结
2014/07/04 职场文书
2015年五四青年节演讲稿
2015/03/18 职场文书
幽灵公主观后感
2015/06/09 职场文书
学校少先队工作总结
2015/08/12 职场文书
学习《中小学教师职业道德规范》心得体会
2016/01/18 职场文书
浅谈Python numpy创建空数组的问题
2021/05/25 Python
mysql定时自动备份数据库的方法步骤
2021/07/07 MySQL