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实现多线程下载文件的代码实例
Jun 01 Python
使用python编写android截屏脚本双击运行即可
Jul 21 Python
[原创]使用豆瓣提供的国内pypi源
Jul 02 Python
django初始化数据库的实例
May 27 Python
python实现图片彩色转化为素描
Jan 15 Python
详解python做UI界面的方法
Feb 27 Python
基于python进行抽样分布描述及实践详解
Sep 02 Python
tensorflow 实现从checkpoint中获取graph信息
Feb 10 Python
使用python执行shell脚本 并动态传参 及subprocess的使用详解
Mar 06 Python
python matplotlib:plt.scatter() 大小和颜色参数详解
Apr 14 Python
Python参数传递对象的引用原理解析
May 22 Python
Pycharm常用快捷键总结及配置方法
Nov 14 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时间戳使用实例代码
2008/06/07 PHP
php中inlcude()性能对比详解
2012/09/16 PHP
php的$_FILES的临时储存文件与回收机制实测过程
2013/07/12 PHP
php把大写命名转换成下划线分割命名
2015/04/27 PHP
PHP+AjaxForm异步带进度条上传文件实例代码
2017/08/14 PHP
浅谈Javascript嵌套函数及闭包
2010/11/09 Javascript
浅析JavaScript中的类型和对象
2013/11/29 Javascript
JavaScript中的索引数组、关联数组和静态数组、动态数组讲解
2014/11/08 Javascript
jQuery实现长按按钮触发事件的方法
2015/02/02 Javascript
javascript实现根据3原色制作颜色选择器的方法
2015/07/17 Javascript
JavaScript常用函数工具集:lao-utils
2016/03/01 Javascript
JS实现动画兼容性的transition和transform实例分析
2016/12/13 Javascript
理解javascript中的闭包
2017/01/11 Javascript
jQuery制作图片旋转效果
2017/02/02 Javascript
JavaScript函数中的this四种绑定形式
2017/08/15 Javascript
javaScript canvas实现(画笔大小 颜色 橡皮的实例)
2017/11/28 Javascript
Vue实现动态添加或者删除对象和对象数组的操作方法
2018/09/21 Javascript
说说如何利用 Node.js 代理解决跨域问题
2019/04/22 Javascript
JS document对象简单用法完整示例
2020/01/14 Javascript
Django objects的查询结果转化为json的三种方式的方法
2018/11/07 Python
Python 3 实现定义跨模块的全局变量和使用教程
2019/07/07 Python
python flask搭建web应用教程
2019/11/19 Python
Python 寻找局部最高点的实现
2019/12/05 Python
numpy ndarray 取出满足特定条件的某些行实例
2019/12/05 Python
简单了解python字符串前面加r,u的含义
2019/12/26 Python
python实现opencv+scoket网络实时图传
2020/03/20 Python
HTML5 Canvas 破碎重组的视频特效的示例代码
2019/09/24 HTML / CSS
LACOSTE波兰官网:Polo衫、服装和鞋类
2020/09/29 全球购物
大学生实习介绍信
2015/05/05 职场文书
二审答辩状格式
2015/05/22 职场文书
实施意见格式范本
2015/06/05 职场文书
婚礼领导致辞大全
2015/07/28 职场文书
大学班干部竞选稿
2015/11/20 职场文书
预备党员入党思想汇报(范文)
2019/08/14 职场文书
在Spring-Boot中如何使用@Value注解注入集合类
2021/08/02 Java/Android
Win11如何默认打开软件界面最大化?Win11默认打开软件界面最大化的方法
2022/07/15 数码科技