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一行输出不显示的问题
Dec 03 Python
python3使用flask编写注册post接口的方法
Dec 28 Python
Python实现的对本地host127.0.0.1主机进行扫描端口功能示例
Feb 15 Python
详解python读取image
Apr 03 Python
详解Python中的正斜杠与反斜杠
Aug 09 Python
详解Python3 pandas.merge用法
Sep 05 Python
Django项目基础配置和基本使用过程解析
Nov 25 Python
pytorch 实现cross entropy损失函数计算方式
Jan 02 Python
通过实例解析python描述符原理作用
Jan 22 Python
Window系统下Python如何安装OpenCV库
Mar 05 Python
解决Jupyter notebook中.py与.ipynb文件的import问题
Apr 21 Python
Python 文本滚动播放器的实现代码
Apr 25 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
PHPExcel读取Excel文件的实现代码
2011/12/06 PHP
php微信开发之自定义菜单完整流程
2016/10/08 PHP
详解EventDispatcher事件分发组件
2016/12/25 PHP
Laravel5.7框架安装与使用学习笔记图文详解
2019/04/02 PHP
用javascript实现无刷新更新数据的详细步骤 asp
2006/12/26 Javascript
javascript面向对象之Javascript 继承
2010/05/04 Javascript
jquery 注意事项与常用语法小结
2010/06/07 Javascript
Iframe自适应高度绝对好使的代码 兼容IE,遨游,火狐
2011/01/27 Javascript
一个级联菜单代码学习及removeClass与addClass的应用
2013/01/24 Javascript
jquery统计用户选中的复选框的个数
2014/06/06 Javascript
JS实现超过长度限制后自动跳转下一款文本框的方法
2015/02/23 Javascript
jquery模拟进度条实现方法
2015/08/03 Javascript
Nodejs Express4.x开发框架随手笔记
2015/11/23 NodeJs
jquery获取img的src值的简单实例
2016/05/17 Javascript
jQuery+ajax+asp.net获取Json值的方法
2016/06/08 Javascript
使用Angular.js开发的注意事项
2016/10/19 Javascript
jsTree使用记录实例
2016/12/01 Javascript
JavaScript使用ZeroClipboard操作剪切板
2017/05/10 Javascript
BootStrap模态框和select2合用时input无法获取焦点的解决方法
2017/09/01 Javascript
js中this对象用法分析
2018/01/05 Javascript
JS实现商品橱窗特效
2020/01/09 Javascript
vue开发简单上传图片功能
2020/06/30 Javascript
[13:16]INFAMOUS vs VGJ T BO3
2018/06/07 DOTA
[54:57]DOTA2-DPC中国联赛定级赛 Aster vs DLG BO3第二场 1月8日
2021/03/11 DOTA
Python3实现从文件中读取指定行的方法
2015/05/22 Python
python中函数默认值使用注意点详解
2016/06/01 Python
pycharm中成功运行图片的配置教程
2018/10/28 Python
python调用opencv实现猫脸检测功能
2019/01/15 Python
详解用python实现基本的学生管理系统(文件存储版)(python3)
2019/04/25 Python
浅谈Tensorflow 动态双向RNN的输出问题
2020/01/20 Python
python3.9.1环境安装的方法(图文)
2021/02/02 Python
应届生会计求职信
2013/11/11 职场文书
商场拾金不昧表扬信
2014/01/13 职场文书
教师群众路线教育实践活动学习笔记
2014/11/05 职场文书
实践论读书笔记
2015/06/29 职场文书
远程教育培训心得体会
2016/01/09 职场文书