决策树
决策树通常有三个步骤:特征选择、决策树生成、决策树的修建。
https://www.jianshu.com/p/25c8bbd1bfa0
特征选择
我们在选择特征时,会考虑到两种不同的指标,分别为:信息增益和信息增益比。
有关定义:
1.熵(Entropy)是表示随机变量不确定性的度量。(熵越大,随机变量的不确定性就越大。)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-armG1IGG-1583500872102)
基本思想:是随着树深度的增加,节点的熵迅速地降低。要求:熵降低的速度越快越好,这样我们构造的决策树是一颗高度最矮的决策树(分支过多容易出现过拟合的现象)。
决策树生成
1、训练阶段
从给定的训练数据集DB,构造出一颗决策树
class=DecisionTree(DB)
2、分类阶段
从根开始,按照决策树的分类属性逐层往下划分,直到叶节点,获得概念(决策、分类)结果。
y=DecisionTree(x)
例子代码:
根据天气状况决定是否出去打球
from math import log
def createDataSet():
#outlook:sunny:1,overcast:2,rainy:3
#temperature:hot:1,mild:2,cool:3
#humidity:high:1,normal:2
#windy:false:1,true:2
#play:no,yes
dataSet=[
[1,1,1,1,'no'],
[1,1,1,2,'no'],
[2,1,1,1,'yes'],
[3,2,1,1,'yes'],
[3,3,2,1,'yes'],
[3,3,2,2,'no'],
[2,3,2,2,'yes'],
[1,2,1,1,'no'],
[1,3,2,1,'yes'],
[3,2,2,1,'yes'],
[1,2,2,2,'yes'],
[2,2,1,2,'yes'],
[2,1,2,1,'yes'],
[3,2,1,2,'no']
]
labels=['outlook','temperature','humidity','windy','play']
return dataSet,labels
def calcShannonEnt(dataSet):
#返回数据集行数
numEntries=len(dataSet)
#保存每个标签(label)出现次数的字典
labelCounts={}
#对每组特征向量进行统计
for featVec in dataSet:
currentLabel=featVec[-1]#提取标签信息
if currentLabel not in labelCounts.keys():#如果标签没有放入统计次数
labelCounts[currentLabel]=0
labelCounts[currentLabel]+=1#label计数
shannonEnt=0.0
#计算经验熵
for key in labelCounts:
prob=float(labelCounts[key])/numEntries #选择该标签的概率
shannonEnt-=prob*log(prob,2) #利用公式计算
return shannonEnt
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
def splitDataSet(dataSet,axis,value):
retDataSet=[]
for featVec in dataSet:
if featVec[axis]==value:
reducedFeatVec=featVec[:axis]
reducedFeatVec.extend(featVec[axis+1:])
retDataSet.append(reducedFeatVec)
return retDataSet
if __name__=='__main__':
dataSet,features=createDataSet()
print(dataSet)
print(calcShannonEnt(dataSet))
print("最优索引值:"+str(chooseBestFeatureToSplit(dataSet)))
决策树的修建
ID3:信息增益
C4.5:信息增益率
CART:Gini系数
ID3 算法通过递归的方式建立决策树。
1.从根节点开始,对节点计算每个独立特征的信息增益,选择信息增益最大的特征作为节点特征。
2.对该特征施加判断条件,建立子节点。
3.针对子节点再此使用信息增益进行判断,直到所有特征的信息增益很小或者没有特征时结束,这样就逐步建立一颗完整的决策树。
通过优化损失函数来去掉不必要的一些分类特征,降低模型的整体复杂度。修剪的方式,就是从树的叶节点出发,向上回缩,逐步判断。如果去掉某一特征后,整棵决策树所对应的损失函数更小,那就将该特征及带有的分支剪掉。
剪枝策略分为两种:
预剪枝:在构建决策树的过程时,提前停止
后剪枝:决策树构建好后,然后才开始裁剪
作者:没才艺的华哥
链接:https://www.jianshu.com/p/25c8bbd1bfa0
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。