python编写分类决策树的代码


Posted in Python onDecember 21, 2017

决策树通常在机器学习中用于分类。

优点:计算复杂度不高,输出结果易于理解,对中间值缺失不敏感,可以处理不相关特征数据。
缺点:可能会产生过度匹配问题。
适用数据类型:数值型和标称型。

1.信息增益

划分数据集的目的是:将无序的数据变得更加有序。组织杂乱无章数据的一种方法就是使用信息论度量信息。通常采用信息增益,信息增益是指数据划分前后信息熵的减少值。信息越无序信息熵越大,获得信息增益最高的特征就是最好的选择。
熵定义为信息的期望,符号xi的信息定义为:

python编写分类决策树的代码

其中p(xi)为该分类的概率。
熵,即信息的期望值为:

python编写分类决策树的代码

计算信息熵的代码如下:

def calcShannonEnt(dataSet):
  numEntries = len(dataSet)
  labelCounts = {}
  for featVec in dataSet:
    currentLabel = featVec[-1]
    if currentLabel not in labelCounts:
      labelCounts[currentLabel] = 0
    labelCounts[currentLabel] += 1
  shannonEnt = 0
  for key in labelCounts:
    shannonEnt = shannonEnt - (labelCounts[key]/numEntries)*math.log2(labelCounts[key]/numEntries)
  return shannonEnt

可以根据信息熵,按照获取最大信息增益的方法划分数据集。

2.划分数据集

划分数据集就是将所有符合要求的元素抽出来。

def splitDataSet(dataSet,axis,value):
  retDataset = []
  for featVec in dataSet:
    if featVec[axis] == value:
      newVec = featVec[:axis]
      newVec.extend(featVec[axis+1:])
      retDataset.append(newVec)
  return retDataset

3.选择最好的数据集划分方式

信息增益是熵的减少或者是信息无序度的减少。

def chooseBestFeatureToSplit(dataSet):
  numFeatures = len(dataSet[0]) - 1
  bestInfoGain = 0
  bestFeature = -1
  baseEntropy = calcShannonEnt(dataSet)
  for i in range(numFeatures):
    allValue = [example[i] for example in dataSet]#列表推倒,创建新的列表
    allValue = set(allValue)#最快得到列表中唯一元素值的方法
    newEntropy = 0
    for value in allValue:
      splitset = splitDataSet(dataSet,i,value)
      newEntropy = newEntropy + len(splitset)/len(dataSet)*calcShannonEnt(splitset)
    infoGain = baseEntropy - newEntropy
    if infoGain > bestInfoGain:
      bestInfoGain = infoGain
      bestFeature = i
  return bestFeature

4.递归创建决策树

结束条件为:程序遍历完所有划分数据集的属性,或每个分支下的所有实例都具有相同的分类。
当数据集已经处理了所有属性,但是类标签还不唯一时,采用多数表决的方式决定叶子节点的类型。

def majorityCnt(classList):
 classCount = {}
 for value in classList:
  if value not in classCount: classCount[value] = 0
  classCount[value] += 1
 classCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
 return classCount[0][0]

生成决策树:

def createTree(dataSet,labels):
 classList = [example[-1] for example in dataSet]
 labelsCopy = labels[:]
 if classList.count(classList[0]) == len(classList):
  return classList[0]
 if len(dataSet[0]) == 1:
  return majorityCnt(classList)
 bestFeature = chooseBestFeatureToSplit(dataSet)
 bestLabel = labelsCopy[bestFeature]
 myTree = {bestLabel:{}}
 featureValues = [example[bestFeature] for example in dataSet]
 featureValues = set(featureValues)
 del(labelsCopy[bestFeature])
 for value in featureValues:
  subLabels = labelsCopy[:]
  myTree[bestLabel][value] = createTree(splitDataSet(dataSet,bestFeature,value),subLabels)
 return myTree

5.测试算法——使用决策树分类

同样采用递归的方式得到分类结果。

def classify(inputTree,featLabels,testVec):
 currentFeat = list(inputTree.keys())[0]
 secondTree = inputTree[currentFeat]
 try:
  featureIndex = featLabels.index(currentFeat)
 except ValueError as err:
  print('yes')
 try:
  for value in secondTree.keys():
   if value == testVec[featureIndex]:
    if type(secondTree[value]).__name__ == 'dict':
     classLabel = classify(secondTree[value],featLabels,testVec)
    else:
     classLabel = secondTree[value]
  return classLabel
 except AttributeError:
  print(secondTree)

6.完整代码如下

import numpy as np
import math
import operator
def createDataSet():
 dataSet = [[1,1,'yes'],
    [1,1,'yes'],
    [1,0,'no'],
    [0,1,'no'],
    [0,1,'no'],]
 label = ['no surfacing','flippers']
 return dataSet,label

def calcShannonEnt(dataSet):
 numEntries = len(dataSet)
 labelCounts = {}
 for featVec in dataSet:
  currentLabel = featVec[-1]
  if currentLabel not in labelCounts:
   labelCounts[currentLabel] = 0
  labelCounts[currentLabel] += 1
 shannonEnt = 0
 for key in labelCounts:
  shannonEnt = shannonEnt - (labelCounts[key]/numEntries)*math.log2(labelCounts[key]/numEntries)
 return shannonEnt


def splitDataSet(dataSet,axis,value):
 retDataset = []
 for featVec in dataSet:
  if featVec[axis] == value:
   newVec = featVec[:axis]
   newVec.extend(featVec[axis+1:])
   retDataset.append(newVec)
 return retDataset

def chooseBestFeatureToSplit(dataSet):
 numFeatures = len(dataSet[0]) - 1
 bestInfoGain = 0
 bestFeature = -1
 baseEntropy = calcShannonEnt(dataSet)
 for i in range(numFeatures):
  allValue = [example[i] for example in dataSet]
  allValue = set(allValue)
  newEntropy = 0
  for value in allValue:
   splitset = splitDataSet(dataSet,i,value)
   newEntropy = newEntropy + len(splitset)/len(dataSet)*calcShannonEnt(splitset)
  infoGain = baseEntropy - newEntropy
  if infoGain > bestInfoGain:
   bestInfoGain = infoGain
   bestFeature = i
 return bestFeature

def majorityCnt(classList):
 classCount = {}
 for value in classList:
  if value not in classCount: classCount[value] = 0
  classCount[value] += 1
 classCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
 return classCount[0][0]   

def createTree(dataSet,labels):
 classList = [example[-1] for example in dataSet]
 labelsCopy = labels[:]
 if classList.count(classList[0]) == len(classList):
  return classList[0]
 if len(dataSet[0]) == 1:
  return majorityCnt(classList)
 bestFeature = chooseBestFeatureToSplit(dataSet)
 bestLabel = labelsCopy[bestFeature]
 myTree = {bestLabel:{}}
 featureValues = [example[bestFeature] for example in dataSet]
 featureValues = set(featureValues)
 del(labelsCopy[bestFeature])
 for value in featureValues:
  subLabels = labelsCopy[:]
  myTree[bestLabel][value] = createTree(splitDataSet(dataSet,bestFeature,value),subLabels)
 return myTree


def classify(inputTree,featLabels,testVec):
 currentFeat = list(inputTree.keys())[0]
 secondTree = inputTree[currentFeat]
 try:
  featureIndex = featLabels.index(currentFeat)
 except ValueError as err:
  print('yes')
 try:
  for value in secondTree.keys():
   if value == testVec[featureIndex]:
    if type(secondTree[value]).__name__ == 'dict':
     classLabel = classify(secondTree[value],featLabels,testVec)
    else:
     classLabel = secondTree[value]
  return classLabel
 except AttributeError:
  print(secondTree)

if __name__ == "__main__":
 dataset,label = createDataSet()
 myTree = createTree(dataset,label)
 a = [1,1]
 print(classify(myTree,label,a))

7.编程技巧

extend与append的区别

newVec.extend(featVec[axis+1:])
 retDataset.append(newVec)

extend([]),是将列表中的每个元素依次加入新列表中
append()是将括号中的内容当做一项加入到新列表中

列表推到

创建新列表的方式

allValue = [example[i] for example in dataSet]

提取列表中唯一的元素

allValue = set(allValue)

列表/元组排序,sorted()函数

classCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)

列表的复制

labelsCopy = labels[:]

代码及数据集下载:决策树

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python Sleep休眠函数使用简单实例
Feb 02 Python
Python导入oracle数据的方法
Jul 10 Python
Python实现简单拆分PDF文件的方法
Jul 30 Python
Python实现excel转sqlite的方法
Jul 17 Python
Python利用神经网络解决非线性回归问题实例详解
Jul 19 Python
对Pytorch神经网络初始化kaiming分布详解
Aug 18 Python
python bluetooth蓝牙信息获取蓝牙设备类型的方法
Nov 29 Python
利用PyCharm操作Github(仓库新建、更新,代码回滚)
Dec 18 Python
flask利用flask-wtf验证上传的文件的方法
Jan 17 Python
Python实现对adb命令封装
Mar 06 Python
python编写softmax函数、交叉熵函数实例
Jun 11 Python
python用tkinter实现一个gui的翻译工具
Oct 26 Python
Python基于PyGraphics包实现图片截取功能的方法
Dec 21 #Python
用Python写王者荣耀刷金币脚本
Dec 21 #Python
python使用Apriori算法进行关联性解析
Dec 21 #Python
python实现kMeans算法
Dec 21 #Python
利用Tkinter(python3.6)实现一个简单计算器
Dec 21 #Python
python编写朴素贝叶斯用于文本分类
Dec 21 #Python
python并发2之使用asyncio处理并发
Dec 21 #Python
You might like
《PHP边学边教》(02.Apache+PHP环境配置――上篇)
2006/12/13 PHP
php利用header函数实现文件下载时直接提示保存
2009/11/12 PHP
第四章 php数学运算
2011/12/30 PHP
PHP延迟静态绑定示例分享
2014/06/22 PHP
深入解析PHP中SESSION反序列化机制
2017/03/01 PHP
动态改变textbox的宽高的js
2006/10/26 Javascript
js实现iframe动态调整高度的代码
2008/01/06 Javascript
Document 对象的常用方法
2009/07/31 Javascript
在Windows上安装Node.js模块的方法
2011/09/25 Javascript
jquery 获取标签名(tagName)示例代码
2013/07/11 Javascript
JavaScript之IE的fireEvent方法详细解析
2013/11/20 Javascript
jQuery中:last-child选择器用法实例
2014/12/31 Javascript
解决angular的post请求后SpringMVC后台接收不到参数值问题的方法
2015/12/10 Javascript
javascript宿主对象之window.navigator详解
2016/09/07 Javascript
JavaScript 自定义事件之我见
2017/09/25 Javascript
JS的Ajax与后端交互数据的实例
2018/08/08 Javascript
Vue CLI4 Vue.config.js标准配置(最全注释)
2020/06/05 Javascript
jQuery带控制按钮轮播图插件
2020/07/31 jQuery
JavaScript位置参数实现原理及过程解析
2020/09/14 Javascript
python 中文乱码问题深入分析
2011/03/13 Python
Python3实现爬取指定百度贴吧页面并保存页面数据生成本地文档的方法
2018/04/22 Python
python 将json数据提取转化为txt的方法
2018/10/26 Python
python numpy存取文件的方式
2020/04/01 Python
详解Django3中直接添加Websockets方式
2020/02/12 Python
jupyter lab文件导出/下载方式
2020/04/22 Python
PyQt5.6+pycharm配置以及pyinstaller生成exe(小白教程)
2020/06/02 Python
详解anaconda离线安装pytorchGPU版
2020/09/08 Python
css3实例教程 一款纯css3实现的发光屏幕旋转特效
2014/12/07 HTML / CSS
Sneaker Studio捷克:购买运动鞋
2018/07/08 全球购物
会计岗位职责模板
2014/03/12 职场文书
刊首寄语大全
2014/04/11 职场文书
干部鉴定材料
2014/05/18 职场文书
干部作风建设个人剖析材料
2014/10/11 职场文书
2014年路政工作总结
2014/12/10 职场文书
党风廉政建设调研报告
2015/01/01 职场文书
使用JS实现简易计算器
2021/06/14 Javascript