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深入学习之闭包
Aug 31 Python
Python fileinput模块使用介绍
Nov 30 Python
Python MySQLdb模块连接操作mysql数据库实例
Apr 08 Python
python django 访问静态文件出现404或500错误
Jan 20 Python
Python实现Windows和Linux之间互相传输文件(文件夹)的方法
May 08 Python
python中利用xml.dom模块解析xml的方法教程
May 24 Python
django自带的server 让外网主机访问方法
May 14 Python
python f-string式格式化听语音流程讲解
Jun 18 Python
详解PyCharm安装MicroPython插件的教程
Jun 24 Python
python内存管理机制原理详解
Aug 12 Python
在pytorch中动态调整优化器的学习率方式
Jun 24 Python
基于CentOS搭建Python Django环境过程解析
Aug 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分割合并两个字符串的函数实例
2015/06/19 PHP
分享PHP计算两个日期相差天数的代码
2015/12/23 PHP
CI配置多数据库访问的方法
2016/03/28 PHP
php检查函数必传参数是否存在的实例详解
2017/08/28 PHP
thinkphp5.1框架实现格式化mysql时间戳为日期的方式小结
2019/10/10 PHP
prototype Element学习笔记(篇一)
2008/10/26 Javascript
ajax 缓存 问题 requestheader
2010/08/01 Javascript
JavaScript词法作用域与调用对象深入理解
2012/11/29 Javascript
addEventListener 的用法示例介绍
2014/05/07 Javascript
Bootstrap select实现下拉框多选效果
2016/12/23 Javascript
vue router下的html5 history在iis服务器上的设置方法
2017/10/18 Javascript
jQuery简单实现对数组去重及排序操作实例
2017/10/31 jQuery
JS实现求5的阶乘示例
2019/01/21 Javascript
微信小程序通过一个json实现分享朋友圈图片
2019/09/03 Javascript
vue如何实现动态加载脚本
2020/02/05 Javascript
JavaScript oncopy事件用法实例解析
2020/05/13 Javascript
[01:10:03]OG vs EG 2018国际邀请赛淘汰赛BO3 第三场 8.23
2018/08/24 DOTA
SublimeText 2编译python出错的解决方法(The system cannot find the file specified)
2013/11/27 Python
python实现超简单端口转发的方法
2015/03/13 Python
使用Python的PEAK来适配协议的教程
2015/04/14 Python
python3基于OpenCV实现证件照背景替换
2018/07/18 Python
python调用百度语音识别实现大音频文件语音识别功能
2018/08/30 Python
python实现微信小程序自动回复
2018/09/10 Python
Python中base64与xml取值结合问题
2019/12/22 Python
python可视化text()函数使用详解
2020/02/11 Python
Python读取多列数据以及用matplotlib制作图表方法实例
2020/09/23 Python
OpenCV+Python3.5 简易手势识别的实现
2020/12/21 Python
使用gunicorn部署django项目的问题
2020/12/30 Python
纯CSS3实现表单验证效果(非常不错)
2017/01/18 HTML / CSS
CSS实现半透明边框与多重边框的场景分析
2019/11/13 HTML / CSS
DERMAdoctor官网:美国著名皮肤护理品牌
2019/07/06 全球购物
会计电算化应届生求职信
2013/11/03 职场文书
森林病虫害防治方案
2014/06/02 职场文书
大学生年度个人总结
2015/02/15 职场文书
酒店保洁员岗位职责
2015/02/26 职场文书
postgresql 删除重复数据案例详解
2021/08/02 PostgreSQL