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中最常用的操作列表的几种方法归纳
Apr 24 Python
python图像处理之反色实现方法
May 30 Python
在Mac OS系统上安装Python的Pillow库的教程
Nov 20 Python
web.py 十分钟创建简易博客实现代码
Apr 22 Python
python+pygame简单画板实现代码实例
Dec 13 Python
使用python 爬虫抓站的一些技巧总结
Jan 10 Python
Python多线程中阻塞(join)与锁(Lock)使用误区解析
Apr 27 Python
pycharm 取消默认的右击运行unittest的方法
Nov 29 Python
一个可以套路别人的python小程序实例代码
Apr 09 Python
python迭代器常见用法实例分析
Nov 22 Python
Python代码覆盖率统计工具coverage.py用法详解
Nov 25 Python
实例讲解Python中sys.argv[]的用法
Jun 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中使用DOM类读取XML文件的实现代码
2011/12/14 PHP
浅析关于PHP位运算的简单权限设计
2013/06/30 PHP
php中的常用魔术方法总结
2013/08/02 PHP
Yii 使用intervention/image拓展实现图像处理功能
2019/06/22 PHP
Yii 框架控制器创建使用及控制器响应操作示例
2019/10/14 PHP
showModelessDialog()使用详解
2006/09/21 Javascript
javascript之更有效率的字符串替换
2008/08/02 Javascript
理解Javascript_03_javascript全局观
2010/10/11 Javascript
自用js开发框架小成 学习js的朋友可以看看
2010/11/16 Javascript
关于URL中的特殊符号使用介绍
2011/11/03 Javascript
jQuery .tmpl() 用法示例介绍
2014/08/21 Javascript
详解JS中Array对象扩展与String对象扩展
2016/01/07 Javascript
javascript中select下拉框的用法总结
2016/01/07 Javascript
JavaScript数据推送Comet技术详解
2016/04/07 Javascript
Node.js环境下JavaScript实现单链表与双链表结构
2016/06/12 Javascript
NodeJS与HTML5相结合实现拖拽多个文件上传到服务器的实现方法
2016/07/26 NodeJs
通过BootStrap实现轮播图的实际应用
2016/09/26 Javascript
JSP防止网页刷新重复提交数据的几种方法
2016/11/19 Javascript
node学习笔记之读写文件与开启第一个web服务器操作示例
2019/05/29 Javascript
Vuex 模块化使用详解
2019/07/31 Javascript
JS实现点星星消除小游戏
2020/03/24 Javascript
[44:40]KG vs LGD 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
Python实现自动添加脚本头信息的示例代码
2016/09/02 Python
python中的计时器timeit的使用方法
2017/10/20 Python
朗仕(Lab series)英国官网:雅诗兰黛集团男士专属护肤品牌
2017/11/28 全球购物
4s店机修工岗位职责
2013/12/20 职场文书
中专生职业生涯规划书范文
2014/01/10 职场文书
民警群众路线教育实践活动对照检查材料
2014/10/04 职场文书
离婚协议书标准格式
2014/10/04 职场文书
工伤死亡理赔协议书
2014/10/20 职场文书
2014年团委工作总结
2014/11/13 职场文书
2014年工程工作总结
2014/11/25 职场文书
计划生育汇报材料
2014/12/26 职场文书
公司更名通知函
2015/04/24 职场文书
班主任工作总结范文
2015/08/13 职场文书
MySQL索引失效场景及解决方案
2022/07/23 MySQL