参与拿奖:本文已参与「新人创作礼」活动,一起开启掘金创作之路
1.决策树的优缺点
优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据
缺点:可能会产生过度匹配问题
适用数据类型:数值型和标称型
2.决策树一般步骤
搜集数据:使用爬虫获取数据或者公开的数据
准备数据:树构造算法只适用于标称型数据,因此数值型数据必须离散化
分析数据:构造树完成之后,检查图形是否符合预期
训练算法:构造树的数据结构
测试算法:使用经验树计算错误率
使用方法:适用于任何监督学习算法,使用决策树可以更好地理解数据的内在含义
3.例子
3.1计算数据的香农熵
from math import log
# 计算一个数据集的香农熵
def calcShannonEnt(dataSet):
numEntries=len(dataSet)
labelCounts={}
# 计算各个类别数量
for featVec in dataSet:
currentLabel=featVec[-1]
if currentLabel not in labelCounts.keys():
labelCounts[currentLabel]=0
labelCounts[currentLabel]+=1
shannonEnt=0.0
for key in labelCounts:
# 每个类别出现的频率
prob=float(labelCounts[key])/numEntries
# 计算熵的公式:prob表示该类别出现比例
shannonEnt -=prob*log(prob,2)
return shannonEnt
# 测试函数
# 创建数据集
def creatDataSet():
dataSet=[[1,1,'yes'],[1,1,'yes'],[1,0,'no'],[0,1,'no'],[0,1,'no']]
labels=['no surfacing','flippers']
return dataSet,labels
# 使用reload加载模块
# reload(trees.py)
myDat,labels=creatDataSet()
print(calcShannonEnt(myDat))
myDat[0][-1]='maybe'
print(calcShannonEnt(myDat))
### 得到熵之后,可以按照获取最大信息增益的方法划分数据
### 度量集合无序程度的方法:基尼不纯度,就是从一个数据集中随机选取子项,度量其被错误分类到其他组的概率
### 分类算法:划分数据集+测量信息熵
3.2 利用熵对数据集进行划分
def chooseBestFeatureToSplit(dataSet):
# 数据带有目标值(类别)
numFeature=len(dataSet[0])-1
# 原始数据集的熵(类似于baseline)
baseEntropy=calcShannonEnt(dataSet)
bestInfoGain=0.0
bestFeature=-1
for i in range(numFeature):
featList=[example[i] for example in dataSet]
# 创建唯一的分类标签列表
uniqueVals=set(featList)
newEntropy=0.0
# 计算每种划分方式的信息熵
for value in uniqueVals:
# 遍历当前特征中的所有唯一属性值,对每个特征划分一次数据集
subDataSet=splitDataSet(dataSet,i,value)
# 计算每个新数据集的新熵值,并对所有唯一特征值得到的熵求和
prob=len(subDataSet)/float(len(dataSet))
newEntropy += prob*calcShannonEnt(subDataSet)
# 信息增益是指熵的减少,或者是数据无序度的减少
infoGain=baseEntropy-newEntropy
# 计算最好的信息增益
if (infoGain>bestInfoGain):
bestInfoGain=infoGain
bestFeature=i
# 返回用于数据最好特征划分的索引值
return bestFeature
4.小结
决策树分类器就像带有终止块的流程图,终止块表示分类结果。
数据集处理:测试数据集的熵,寻找最优方案划分数据集,直到数据集中所有数据属于同一分类。
通常采用递归方法将数据集转化为决策树。
可以通过裁剪决策树,合并相邻的无法产生大量信息增益的叶子节点,消除过度匹配问题。
5.参考资料
[1] 机器学习实战
[2] 书籍源码
[3] jupyter版本