概述
决策树
决策树是什么?决策树(decision tree)是一种基本的分类与回归方法。举个通俗易懂的例子,如下图所示的流程图就是一个决策树,长方形代表判断模块(decision block),椭圆形成代表终止模块(terminating block),表示已经得出结论,可以终止运行。从判断模块引出的左右箭头称作为分支(branch),它可以达到另一个判断模块或者终止模块。我们还可以这样理解,分类决策树模型是一种描述对实例进行分类的树形结构。决策树由结点(node)和有向边(directed edge)组成。结点有两种类型:内部结点(internal node)和叶结点(leaf node)。内部结点表示一个特征或属性,叶结点表示一个类。
计算经验熵的代码
在编写代码之前,先对数据集进行属性标注:
- 年龄:0代表青年,1代表中年,2代表老年;
- 有工作:0代表否,1代表是;
- 有自己的房子:0代表否,1代表是;
- 信贷情况:0代表一般,1代表好,2代表非常好;
- 类别(是否给贷款):no代表否,yes代表是。
from math import log
"""
函数说明:创建测试数据集
Parameters:
无
Returns:
dataSet - 数据集
labels - 分类属性
"""
def createDataSet():
dataSet = [[0, 0, 0, 0, 'no'], #数据集
[0, 0, 0, 1, 'no'],
[0, 1, 0, 1, 'yes'],
[0, 1, 1, 0, 'yes'],
[0, 0, 0, 0, 'no'],
[1, 0, 0, 0, 'no'],
[1, 0, 0, 1, 'no'],
[1, 1, 1, 1, 'yes'],
[1, 0, 1, 2, 'yes'],
[1, 0, 1, 2, 'yes'],
[2, 0, 1, 2, 'yes'],
[2, 0, 1, 1, 'yes'],
[2, 1, 0, 1, 'yes'],
[2, 1, 0, 2, 'yes'],
[2, 0, 0, 0, 'no']]
labels = ['年龄','有工作','有自己的房子','信贷情况']
#分类属性
return dataSet, labels
#返回数据集和分类属性
"""
函数说明:计算给定数据集的经验熵(香农熵)
Parameters:
dataSet - 数据集
Returns:
shannonEnt - 经验熵(香农熵)
"""
def calcShannonEnt(dataSet):
#返回数据集的行数
numEntires = len(dataSet)
#保存每个标签(Label)出现次数的字典
labelCounts = {}
#对每组特征向量进行统计
for featVec in dataSet:
#提取标签(Label)信息
currentLabel = featVec[-1]
#如果标签(Label)没有放入统计次数的字典,添加进去
if currentLabel not in labelCounts.keys():
labelCounts[currentLabel] = 0
#Label计数
labelCounts[currentLabel] += 1
#经验熵(香农熵)
shannonEnt = 0.0
#计算香农熵
for key in labelCounts:
#选择该标签(Label)的概率
prob = float(labelCounts[key]) / numEntires
#利用公式计算
shannonEnt -= prob * log(prob, 2)
#返回经验熵(香农熵)
return shannonEnt
if __name__ == '__main__':
dataSet, features = createDataSet()
print(dataSet)
print(calcShannonEnt(dataSet))
运行结果:
[[0, 0, 0, 0, 'no'], [0, 0, 0, 1, 'no'], [0, 1, 0, 1, 'yes'], [0, 1, 1, 0, 'yes'], [0, 0, 0, 0, 'no'], [1, 0, 0, 0, 'no'], [1, 0, 0, 1, 'no'], [1, 1, 1, 1, 'yes'], [1, 0, 1, 2, 'yes'], [1, 0, 1, 2, 'yes'], [2, 0, 1, 2, 'yes'], [2, 0, 1, 1, 'yes'], [2, 1, 0, 1, 'yes'], [2, 1, 0, 2, 'yes'], [2, 0, 0, 0, 'no']]
0.9709505944546686
计算信息增益的代码
from math import log
"""
函数说明:计算给定数据集的经验熵(香农熵)
Parameters:
dataSet - 数据集
Returns:
shannonEnt - 经验熵(香农熵)
"""
def calcShannonEnt(dataSet):
#返回数据集的行数
numEntires = len(dataSet)
#保存每个标签(Label)出现次数的字典
labelCounts = {}
#对每组特征向量进行统计
for featVec in dataSet:
#提取标签(Label)信息
currentLabel = featVec[-1]
#如果标签(Label)没有放入统计次数的字典,添加进去
if currentLabel not in labelCounts.keys():
labelCounts[currentLabel] = 0
#Label计数
labelCounts[currentLabel] += 1
#经验熵(香农熵)
shannonEnt = 0.0
#计算香农熵
for key in labelCounts:
#选择该标签(Label)的概率
prob = float(labelCounts[key]) / numEntires
#利用公式计算
shannonEnt -= prob * log(prob, 2)
#返回经验熵(香农熵)
return shannonEnt
"""
函数说明:创建测试数据集
Parameters:
无
Returns:
dataSet - 数据集
labels - 分类属性
"""
def createDataSet():
#数据集
dataSet = [[0, 0, 0, 0, 'no'],
[0, 0, 0, 1, 'no'],
[0, 1, 0, 1, 'yes'],
[0, 1, 1, 0, 'yes'],
[0, 0, 0, 0, 'no'],
[1, 0, 0, 0, 'no'],
[1, 0, 0, 1, 'no'],
[1, 1, 1, 1, 'yes'],
[1, 0, 1, 2, 'yes'],
[1, 0, 1, 2, 'yes'],
[2, 0, 1, 2, 'yes'],
[2, 0, 1, 1, 'yes'],
[2, 1, 0, 1, 'yes'],
[2, 1, 0, 2, 'yes'],
[2, 0, 0, 0, 'no']]
#分类属性
labels = ['年龄', '有工作', '有自己的房子', '信贷情况']
#返回数据集和分类属性
return dataSet, labels
"""
函数说明:按照给定特征划分数据集
Parameters:
dataSet - 待划分的数据集
axis - 划分数据集的特征
value - 需要返回的特征的值
Returns:
无
"""
def splitDataSet(dataSet, axis, value):
#创建返回的数据集列表
retDataSet = []
#遍历数据集
for featVec in dataSet:
if featVec[axis] == value:
#去掉axis特征
reducedFeatVec = featVec[:axis]
#将符合条件的添加到返回的数据集
reducedFeatVec.extend(featVec[axis+1:])
retDataSet.append(reducedFeatVec)
#返回划分后的数据集
return retDataSet
"""
函数说明:选择最优特征
Parameters:
dataSet - 数据集
Returns:
bestFeature - 信息增益最大的(最优)特征的索引值
"""
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]
#创建set集合{},元素不可重复
uniqueVals = set(featList)
#经验条件熵
newEntropy = 0.0
#计算信息增益
for value in uniqueVals:
#subDataSet划分后的子集
subDataSet = splitDataSet(dataSet, i, value)
#计算子集的概率
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
if __name__ == '__main__':
dataSet, features = createDataSet()
print("最优特征索引值:" + str(chooseBestFeatureToSplit(dataSet)))
运行结果:
第0个特征的增益为0.083
第1个特征的增益为0.324
第2个特征的增益为0.420
第3个特征的增益为0.363
最优特征索引值:2
最后
以上就是如意苗条为你收集整理的机器学习实战-决策树实例的全部内容,希望文章能够帮你解决机器学习实战-决策树实例所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复