以下为《决策树模型-ID3决策树》的无排版文字预览,完整格式请下载
下载前请仔细阅读文字预览以及下方图片预览。图片预览是什么样的,下载的文档就是什么样的。
决策树模型-ID3决策树
模型算法思想:
决策树(decision tree)是一个树结构(可以是二叉树或非二叉树)
其每个非叶节点表示一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的输出,而每个叶节点存放一个类别。
总结来说决策树模型的核心由下面几部分组成:
结点和有向边
结点有内部结点和叶结点两种类型
内部结点表示一个特征,叶结点表示一类
决策树代表实例属性值约束的合取析取式。从树根到树叶的每一条路径对应一组属性测试的合取,树本身对应这些合取的析取。
模型算法应用
评价项目风险
预测可行性
所选择模型的基本原理(模型及推导)
决策树算法构造决策树来发现数据中蕴涵的分类规则.如何构造精度高、规模小的决策树是决策树算法的核心内容。决策树构造可以分两步进行。第一步,决策树的生成:由训练样本集生成决策树的过程。一般情况下,训练样本数据集是根据实际需要有历史的、有一定综合程度的,用于数据分析处理的数据集。第二步,决策树的剪枝:决策树的剪枝是对上一阶段生成的决策树进行检验、校正和修下的过程,主要是用新的样本数据集(称为测试数据集)中的数据校验决策树生成过程中产生的初步规则,将那些影响预衡准确性的分枝剪除。决策树是附加概率结果的一个树状的决策图,是直观的运用统计概率分析的图法。机器学习中决策树是一个预测模型,它表示对象属性和对象值之间的一种映射,树中的每一个节点表示对象属性的判断条件,其分支表示符合节点条件的对象。树的叶子节点表示对象所属的预测结果。
信息增益
信息熵表示的是不确定度。均匀分布时,不确定度最大,此时熵就最大。当选择某个特征对数据集进行分类时,分类后的数据集信息熵会比分类前的小,其差值表示为信息增益。信息增益可以衡量某个特征对分类结果的影响大小。
假设在样本数据集 D 中,混有 c 种类别的数据。构建决策树时,根据给定的样本数据集选择某个特征值作为树的节点。在数据集中,可以计算出该数据中的信息熵:
/
其中 D 表示训练数据集,c 表示数据类别数,Pi 表示类别 i 样本数量占所有样本的比例。
对应数据集 D,选择特征 A 作为决策树判断节点时,在特征 A 作用后的信息熵的为 Info(D),计算如下:
/
其中 k 表示样本 D 被分为 k 个部分。
信息增益表示数据集 D 在特征 A 的作用后,其信息熵减少的值。公式如下:
/
对于决策树节点最合适的特征选择,就是 Gain(A) 值最大的特征。
所选算法的实现流程
导入所需要的包
计算信息熵
创建数据集
选择最优属性
统计出现最多的类标签
创建决策树
获取决策树叶子结点的数目
获取决策树的层数
绘制结点
绘制边的属性
绘制决策树
代码实现
# -*- coding: UTF-8 -*-
from matplotlib.font_manager import FontProperties
import matplotlib.pyplot as plt
from math import log
import operator
#计算信息熵
def calcShannonEnt(dataSet):
numEntires = len(dataSet) #返回数据集的行数
labelCounts = {} #保存每个标签(Label)出现次数的字典
for featVec in dataSet: #对每组特征向量进行统计
currentLabel = featVec[-1] #提取标签(Label)信息
if currentLabel not in labelCounts.keys(): #如果标签(Label)没有放入统计次数的字典,添加进去
labelCounts[currentLabel] = 0
labelCounts[currentLabel] += 1 #Label计数
shannonEnt = 0.0 #经验熵(香农熵)
for key in labelCounts: #计算香农熵
prob = float(labelCounts[key]) / numEntires #选择该标签(Label)的概率
shannonEnt -= prob * log(prob, 2) #利用公式计算
return shannonEnt #返回经验熵(香农熵)
#创建数据集
def createDataSet():
dataSet = [[0, 0, 0, 0, 0, 0, 'yes'], # 数据集
[1, 0, 1, 0, 0, 0, 'yes'],
[1, 0, 0, 0, 0, 0, 'yes'],
[0, 0, 1, 0, 0, 0, 'yes'],
[2, 0, 0, 0, 0, 0, 'yes'],
[0, 1, 0, 0, 1, 1, 'yes'],
[1, 1, 0, 1, 1, 1, 'yes'],
[1, 1, 0, 0, 1, 0, 'yes'],
[1, 1, 1, 1, 1, 0, 'no'],
[0, 2, 2, 0, 2, 1, 'no'],
[2, 2, 2, 2, 2, 0, 'no'],
[2, 0, 0, 2, 2, 1, 'no'],
[0, 1, 0, 1, 0, 0, 'no'],
[2, 1, 1, 1, 0, 0, 'no'],
[1, 1, 0, 0, 1, 1, 'no'],
[2, 0, 0, 2, 2, 0, 'no'],
[0, 0, 1, 1, 1, 0, 'no']]
labels = ['色泽', '根蒂', '敲声', '纹理', '脐部', '触感', '好瓜'] #特征标签
return dataSet, labels #返回数据集和分类属性
#划分子数据集(按照给定特征划分数据集)
def splitDataSet(dataSet, axis, value):
retDataSet = [] #创建返回的数据集列表
for featVec in dataSet: #遍历数据集
if featVec[axis] == value:
reducedFeatVec = featVec[:axis] #去掉axis特征
reducedFeatVec.extend(featVec[axis+1:]) #将符合条件的添加到返回的数据集
retDataSet.append(reducedFeatVec)
return retDataSet #返回划分后的数据集
#选择最优属性
def chooseBestFeatureToSplit(dataSet):
numFeatures = len(dataSet[0]) - 1 #特征数量
baseEntropy = calcShannonEnt(dataSet) #计算数据集的香农熵
bestInfoGain = 0.0 #信息增益
bestFeature = -1 #最优特征的索引值
for i in range(numFeatures): #遍历所有特征
#获取dataSet的第i个所有特征
featList = [example[i] for example in dataSet]
uniqueVals = set(featList) #创建set集合{},元素不可重复
newEntropy = 0.0 #经验条件熵
for value in uniqueVals: #计算信息增益
subDataSet = splitDataSet(dataSet, i, value) #subDataSet划分后的子集
prob = len(subDataSet) / float(len(dataSet)) #计算子集的概率
newEntropy += prob * calcShannonEnt(subDataSet) #根据公式计算经验条件熵
infoGain = baseEntropy - newEntropy #信息增益
# print("第%d个特征的增益为%.3f" % (i, infoGain)) #打印每个特征的信息增益
if (infoGain > bestInfoGain): #计算信息增益
bestInfoGain = infoGain #更新信息增益,找到最大的信息增益
bestFeature = i #记录信息增益最大的特征的索引值
return bestFeature #返回信息增益最大的特征的索引值
#统计classList中出现此处最多的元素(类标签)
def majorityCnt(classList):
classCount = {}
for vote in classList: #统计classList中每个元素出现的次数
if vote not in classCount.keys():classCount[vote] = 0
classCount[vote] += 1
sortedClassCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse = True) #根据字典的值降序排序
return sortedClassCount[0][0] #返回classList中出现次数最多的元素
#创建决策树
def createTree(dataSet, labels, featLabels):
classList = [example[-1] for example in dataSet] #取分类标签(是否放贷:yes or no)
if classList.count(classList[0]) == len(classList): #如果类别完全相同则停止继续划分
return classList[0]
if len(dataSet[0]) == 1: #遍历完所有特征时返回出现次数最多的类标签
return majorityCnt(classList)
bestFeat = chooseBestFeatureToSplit(dataSet) #选择最优特征
bestFeatLabel = labels[bestFeat] #最优特征的标签
featLabels.append(bestFeatLabel)
myTree = {bestFeatLabel:{}} #根据最优特征的标签生成树
del (labels[bestFeat]) #删除已经使用特征标签
featValues = [example[bestFeat] for example in dataSet] #得到训练集中所有最优特征的属性值
uniqueVals = set(featValues) #去掉重复的属性值
for value in uniqueVals: #遍历特征,创建决策树。
subLabels = labels[:]
myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLabels, featLabels)
return myTree
#获取决策树叶子结点的数目
def getNumLeafs(myTree):
numLeafs = 0 #初始化叶子
firstStr = next(iter(myTree)) #python3中myTree.keys()返回的是dict_keys,不在是list,所以不能使用myTree.keys()[0]的方法获取结点属性,可以使用list(myTree.keys())[0]
secondDict = myTree[firstStr] #获取下一组字典
for key in secondDict.keys():
if type(secondDict[key]).__name__=='dict': #测试该结点是否为字典,如果不是字典,代表此结点为叶子结点
numLeafs += getNumLeafs(secondDict[key])
else: numLeafs +=1
return numLeafs
#获取决策树的层数
def getTreeDepth(myTree):
maxDepth = 0 #初始化决策树深度
firstStr = next(iter(myTree)) 内容过长,仅展示头部和尾部部分文字预览,全文请查看图片预览。
# [0, 2, 2, 0, 2, 1],
# [2, 0, 0, 0, 0, 0],
# [0, 1, 0, 0, 1, 1],
# [1, 1, 0, 1, 1, 1]]
# for i in range(0, len(testVec)):
# label = classify(myTree, featLabels, testVec[i])
# if label == 'yes':
# print("好瓜")
# if label == 'no':
# print("坏瓜")
实验结果
实验总结
本次试验选择决策树模型-ID3决策树来对西瓜数据集进行建模训练,选择了西瓜数据集的前六列属性(色泽,根蒂,敲声,纹理,脐部,触感)来作文特征,判定数据集中的结果为好瓜还是坏瓜。更好的了解了决策树算法的核心思想以及决策树中个内容含义,熟悉了判定构建决策树的过程。
[文章尾部最后500字内容到此结束,中间部分内容请查看底下的图片预览]请点击下方选择您需要的文档下载。
以上为《决策树模型-ID3决策树》的无排版文字预览,完整格式请下载
下载前请仔细阅读上面文字预览以及下方图片预览。图片预览是什么样的,下载的文档就是什么样的。