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 07 Python
PyCharm 常用快捷键和设置方法
Dec 20 Python
python修改list中所有元素类型的三种方法
Apr 09 Python
关于python之字典的嵌套,递归调用方法
Jan 21 Python
python实现抽奖小程序
Apr 15 Python
python的mysql数据库建立表与插入数据操作示例
Sep 30 Python
pycharm通过ssh连接远程服务器教程
Feb 12 Python
python获取依赖包和安装依赖包教程
Feb 13 Python
Python 实现将numpy中的nan和inf,nan替换成对应的均值
Jun 08 Python
Python实现Keras搭建神经网络训练分类模型教程
Jun 12 Python
python time()的实例用法
Nov 03 Python
python爬虫中的url下载器用法详解
Nov 30 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
Yii2中hasOne、hasMany及多对多关联查询的用法详解
2017/02/15 PHP
基于jQuery试卷自动排版系统
2010/07/18 Javascript
javascript实现跳转菜单的具体方法
2013/07/05 Javascript
js的延迟执行问题分析
2014/06/23 Javascript
最棒的Angular2表格控件
2016/08/10 Javascript
Vue2组件tree实现无限级树形菜单
2017/03/29 Javascript
jQuery进阶实践之利用最优雅的方式如何写ajax请求
2017/12/20 jQuery
解决iview打包时UglifyJs报错的问题
2018/03/07 Javascript
vue2.0 实现富文本编辑器功能
2019/05/26 Javascript
JS实现利用闭包判断Dom元素和滚动条的方向示例
2019/08/26 Javascript
继承行为在 ES5 与 ES6 中的区别详解
2019/12/24 Javascript
跟老齐学Python之一个免费的实验室
2014/09/14 Python
python目录与文件名操作例子
2016/08/28 Python
Python实现将一个大文件按段落分隔为多个小文件的简单操作方法
2017/04/17 Python
python监控linux内存并写入mongodb(推荐)
2017/09/11 Python
pandas apply 函数 实现多进程的示例讲解
2018/04/20 Python
利用Django模版生成树状结构实例代码
2019/05/19 Python
Python中IP地址处理IPy模块的方法
2019/08/16 Python
python使用paramiko实现ssh的功能详解
2020/03/06 Python
python 如何使用find和find_all爬虫、找文本的实现
2020/10/16 Python
高清屏中使用Canvas绘图出现模糊的问题及解决方法
2019/06/03 HTML / CSS
阿根廷网上配眼镜:SmartBuyGlasses阿根廷
2016/08/19 全球购物
Ray-Ban雷朋西班牙官网:全球领先的太阳眼镜品牌
2018/11/28 全球购物
Notino芬兰:购买香水和化妆品
2019/04/15 全球购物
奥地利购买珠宝和手表网站:ELLA JUWELEN
2019/09/03 全球购物
软件测试英文面试题
2012/10/14 面试题
正隆泰信息技术有限公司上机题
2012/06/14 面试题
校友会欢迎辞
2014/01/13 职场文书
酒店经理职责
2014/01/30 职场文书
心得体会的写法
2014/09/05 职场文书
运动会广播稿100字
2014/09/14 职场文书
社会体育专业大学生职业生涯规划书
2014/09/17 职场文书
中学教师教学工作总结
2015/08/13 职场文书
《你在为谁工作》心得体会(共8篇)
2016/01/20 职场文书
八年级作文之友情
2019/11/25 职场文书
js中Map和Set的用法及区别实例详解
2022/02/15 Javascript