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中的复制操作及copy模块中的浅拷贝与深拷贝方法
Jul 02 Python
Centos 升级到python3后pip 无法使用的解决方法
Jun 12 Python
Python代码块批量添加Tab缩进的方法
Jun 25 Python
python学习之hook钩子的原理和使用
Oct 25 Python
python队列原理及实现方法示例
Nov 27 Python
基于Python和PyYAML读取yaml配置文件数据
Jan 13 Python
TensorFlow2.1.0安装过程中setuptools、wrapt等相关错误指南
Apr 08 Python
aws 通过boto3 python脚本打pach的实现方法
May 10 Python
Python grequests模块使用场景及代码实例
Aug 10 Python
Expected conditions模块使用方法汇总代码解析
Aug 13 Python
python+openCV对视频进行截取的实现
Nov 27 Python
matplotlib相关系统目录获取方式小结
Feb 03 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面向对象的使用教程 简单数据库连接
2006/11/25 PHP
rephactor 优秀的PHP的重构工具
2011/06/09 PHP
PHP的变量类型和作用域详解
2014/03/12 PHP
php实现的漂亮分页方法
2014/04/17 PHP
PHP Warning: Module 'modulename' already loaded in问题解决办法
2015/03/16 PHP
php和editplus正则表达式去除空白行
2015/04/17 PHP
PHP匿名函数和use子句用法实例
2016/03/16 PHP
thinkphp5 URL和路由的功能详解与实例
2017/12/26 PHP
php实现微信企业付款到个人零钱功能
2018/10/09 PHP
Laravel框架实现多数据库连接操作详解
2019/07/12 PHP
仅IE9/10同时支持script元素的onload和onreadystatechange事件分析
2011/04/27 Javascript
js如何实现设计模式中的模板方法
2013/07/23 Javascript
javascript实现十六进制颜色值(HEX)和RGB格式相互转换
2014/06/20 Javascript
IE中getElementsByName()对有些元素无效的解决方案
2014/09/28 Javascript
JavaScript中常见的字符串操作函数及用法汇总
2015/05/04 Javascript
JavaScript截取、切割字符串的技巧
2016/01/07 Javascript
非常酷炫的Bootstrap图片轮播动画
2016/05/27 Javascript
Ajax基础知识详解
2017/02/17 Javascript
自定义vue全局组件use使用、vuex的使用详解
2017/06/14 Javascript
webpack搭建vue 项目的步骤
2017/12/27 Javascript
nodejs中各种加密算法的实现详解
2019/07/11 NodeJs
Vue退出登录时清空缓存的实现
2019/11/12 Javascript
js生成1到100的随机数最简单的实现方法
2020/02/07 Javascript
js实现整体缩放页面适配移动端
2020/03/31 Javascript
在vue-cli创建的项目中使用sass操作
2020/08/10 Javascript
python下如何让web元素的生成更简单的分析
2008/07/17 Python
Python随机生成带特殊字符的密码
2016/03/02 Python
python 链接和操作 memcache方法
2017/03/04 Python
Python数据分析之获取双色球历史信息的方法示例
2018/02/03 Python
Python迭代器和生成器定义与用法示例
2018/02/10 Python
Python调用C++,通过Pybind11制作Python接口
2018/10/16 Python
python爬虫要用到的库总结
2020/07/28 Python
使用CSS3制作响应式导航菜单的方法
2015/07/12 HTML / CSS
菲律宾票务网站:StubHub菲律宾
2018/04/21 全球购物
领导批评与自我批评范文
2014/10/16 职场文书
监理中标通知书
2015/04/16 职场文书