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 Django使用forms来实现评论功能
Aug 17 Python
Python中selenium实现文件上传所有方法整理总结
Apr 01 Python
Python+Pandas 获取数据库并加入DataFrame的实例
Jul 25 Python
Python字符串逆序的实现方法【一题多解】
Feb 18 Python
Python转换时间的图文方法
Jul 01 Python
python3 mmh3安装及使用方法
Oct 09 Python
TENSORFLOW变量作用域(VARIABLE SCOPE)
Jan 10 Python
基于Pycharm加载多个项目过程图解
Jan 19 Python
tensorflow 环境变量设置方式
Feb 06 Python
Matplotlib使用Cursor实现UI定位的示例代码
Mar 12 Python
Python2手动安装更新pip过程实例解析
Jul 16 Python
python中用ctypes模拟点击的实例讲解
Nov 26 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 checkdate、getdate等日期时间函数操作详解
2010/03/11 PHP
PHP句法规则详解 入门学习
2011/11/09 PHP
基于php在各种web服务器的运行模式详解
2013/06/03 PHP
PHP中使用file_get_contents post数据代码例子
2015/02/13 PHP
详解PHP的Yii框架中自带的前端资源包的使用
2016/03/31 PHP
弹出广告特效(一个IP只弹出一次)的代码
2007/07/27 Javascript
javascript中"/"运算符常见错误
2010/10/13 Javascript
jquery ajax对特殊字符进行转义防止js注入使用示例
2013/11/21 Javascript
对Jquery中的ajax再封装,简化操作示例
2014/02/12 Javascript
JavaScript组件焦点与页内锚点间传值的方法
2015/02/02 Javascript
jQuery标签编辑插件Tagit使用指南
2015/04/21 Javascript
一个用jquery写的判断div滚动条到底部的方法【推荐】
2016/04/29 Javascript
js阻止默认浏览器行为与冒泡行为的实现代码
2016/05/15 Javascript
js 连续赋值的简单实现
2016/06/13 Javascript
JS获取url参数、主域名的方法实例分析
2016/08/03 Javascript
微信小程序 wx:key详细介绍
2016/10/28 Javascript
用js将long型数据转换成date型或datetime型的实例
2017/07/03 Javascript
Vue-Router基础学习笔记(小结)
2018/10/15 Javascript
使用Jenkins部署React项目的方法步骤
2019/03/11 Javascript
手把手教你使用TypeScript开发Node.js应用
2019/05/06 Javascript
使用Python编写爬虫的基本模块及框架使用指南
2016/01/20 Python
Python面向对象编程基础解析(一)
2017/10/26 Python
Python使用pyautocad+openpyxl处理cad文件示例
2019/07/11 Python
用python画一只可爱的皮卡丘实例
2019/11/21 Python
tensorflow 环境变量设置方式
2020/02/06 Python
python实现logistic分类算法代码
2020/02/28 Python
Python网络爬虫四大选择器用法原理总结
2020/06/01 Python
Python猫眼电影最近上映的电影票房信息
2020/09/18 Python
strstr()的简单实现
2013/09/26 面试题
递归计算如下递归函数的值(斐波拉契)
2012/02/04 面试题
自荐信如何制作?
2014/02/21 职场文书
优秀毕业生自荐信
2014/06/10 职场文书
酒店端午节活动方案
2014/08/26 职场文书
纪念一二九运动演讲稿
2014/09/16 职场文书
JS代码编译器Monaco使用方法
2021/06/11 Javascript
PyCharm 配置SSH和SFTP连接远程服务器
2022/05/11 Python