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读取mp3中ID3信息的方法
Mar 05 Python
详解在Python程序中解析并修改XML内容的方法
Nov 16 Python
Python中实现switch功能实例解析
Jan 11 Python
Python实现的爬虫刷回复功能示例
Jun 07 Python
完美解决安装完tensorflow后pip无法使用的问题
Jun 11 Python
python向字符串中添加元素的实例方法
Jun 28 Python
pybind11在Windows下的使用教程
Jul 04 Python
运用PyTorch动手搭建一个共享单车预测器
Aug 06 Python
解决Pytorch 训练与测试时爆显存(out of memory)的问题
Aug 20 Python
在python中利用try..except来代替if..else的用法
Dec 19 Python
python3中的logging记录日志实现过程及封装成类的操作
May 12 Python
如何利用Python 进行边缘检测
Oct 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
sqlyog 中文乱码问题的设置方法
2008/10/19 PHP
慎用preg_replace危险的/e修饰符(一句话后门常用)
2013/06/19 PHP
解析php获取字符串的编码格式的方法(函数)
2013/06/21 PHP
php制作中间带自己定义图片二维码的方法
2014/01/27 PHP
Yii2搭建后台并实现rbac权限控制完整实例教程
2016/04/28 PHP
php函数mkdir实现递归创建层级目录
2016/10/27 PHP
MSN消息提示类
2006/09/05 Javascript
prototype Element学习笔记(Element篇三)
2008/10/26 Javascript
validator验证控件使用代码
2010/11/23 Javascript
JavaScript 高级篇之函数 (四)
2012/04/07 Javascript
自定义右键属性覆盖浏览器默认右键行为实现代码
2013/02/02 Javascript
Checbox的操作含已选、未选及判断代码
2013/11/07 Javascript
Chrome下ifame父窗口调用子窗口的问题示例探讨
2014/03/17 Javascript
JavaScript中实现继承的三种方式和实例
2015/01/29 Javascript
Javascript实现颜色rgb与16进制转换的方法
2015/04/18 Javascript
JavaScript使用FileSystemObject对象写入文本文件内容的方法
2015/08/05 Javascript
浅谈Javascript中Object与Function对象
2015/09/26 Javascript
延时加载JavaScript代码提高速度
2015/12/27 Javascript
举例讲解jQuery中可见性过滤选择器的使用
2016/04/18 Javascript
jQuery EasyUI之验证框validatebox实例详解
2017/04/10 jQuery
使用原生js封装的ajax实例(兼容jsonp)
2017/10/12 Javascript
使用webpack将ES6转化ES5的实现方法
2019/10/13 Javascript
Python微信企业号开发之回调模式接收微信端客户端发送消息及被动返回消息示例
2017/08/21 Python
Python爬虫框架Scrapy基本用法入门教程
2018/07/26 Python
Python装饰器简单用法实例小结
2018/12/03 Python
Python3中函数参数传递方式实例详解
2019/05/05 Python
使用Python爬虫库BeautifulSoup遍历文档树并对标签进行操作详解
2020/01/25 Python
python filecmp.dircmp实现递归比对两个目录的方法
2020/05/22 Python
python 日志模块logging的使用场景及示例
2021/01/04 Python
HTML5中Canvas与SVG的画图原理比较
2013/01/16 HTML / CSS
德国著名廉价网上药店:Shop-Apotheke
2017/07/23 全球购物
LN-CC日本:高端男装和女装的奢侈时尚目的地
2019/09/01 全球购物
RealTek面试题
2016/06/28 面试题
四风对照检查剖析材料
2014/10/07 职场文书
贷款承诺书
2015/01/20 职场文书
vue报错function () { [native code] },无法出现我们想要的内容 Unknown custom element
2022/04/11 Vue.js