决策树


主要记录决策树的构造,绘制决策树还未理解透彻。

构造决策树主要需要完成一下部分:

1.	计算不同分类的香农熵
2.	根据香农熵划分数据集
3.	通过递归构建出决策树

香农熵的计算

在记录香农熵之前首先要说明的定义:

l ( x i ) = − l o g 2 p ( x i ) l(x_{i}) = -log_{2}p(x_{i}) l(xi)=log2p(xi)

其中 p ( x i ) p(x_{i}) p(xi) 指的是这个时间按发生的概率。

为了计算熵,我们需要计算所有可能值包含的信息期望值,通过下面公式获得:
H = − ∑ i = 1 n p ( x i ) l o g 2 p ( x i ) H=-\sum_{i=1}^{n} p (x_{i})log_{2}p(x_{i}) H=i=1np(xi)log2p(xi)

计算香农熵的代码:

def calcShannoEnt(dataset):
    numEntries = len(dataset)
    labelCounts = {}
    for featVec in dataset:
        currentLabel = featVec[-1]
        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel] = 0
        labelCounts[currentLabel] += 1
    shannoEnt = 0.0

    # 计算香农熵
    for key in labelCounts:
        prob = float(labelCounts[key]) / numEntries
        shannoEnt -= prob*log(prob, 2)
    return shannoEnt

数据集的划分

类似于物理的熵,当其值越小时,其混乱程度越低,那么在分类上再说也就是分类越明显,因此将通过计算香农熵相对原始值减少多少来寻找数据集中最优的划分条件。

代码如下:

def chooseBestFeatureToSplit(dataset):
	
	# 由于最后一项用于记录他的label所以的特征数量要减一
    numFeature = len(dataset[0]) - 1
    
    baseEntropy = calcShannoEnt(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 * calcShannoEnt(subDataSet)
        infoGain = baseEntropy - newEntropy
        if (infoGain > bestInfoGain):
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature

其中一使用到一个将数据集提取的函数 splitDataSet() 代码如下:

def splitDataSet(dataSet, axis, value):
    retDataSet = []
    for featVec in dataSet:
    	# 如果对应特征的值与value相同那么将他提取出来
        if featVec[axis] == value:
            reducedFeatVec = featVec[:axis]
            reducedFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reducedFeatVec)
    return retDataSet

使用递归生成决策树

由于我们要使用所有的特征来分类,所以我们的基线条件应该时特征的数量为0,不过特征数量为零但是统一数据集下对于不同的对象,他们的label可能不同,这是我们取数量占比大的label作为该节点的分类。

选取多数的函数如下:

def majorityent(classlist):
    classCount = {}
    for vote in classlist:
        if vote not in classCount.keys():
            classCount[vote] = 0
        classCount[vote] += 1
    sortedClassCount = sorted(list(classCount.iteritems()), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

下面就可已使用i递归创建决策树了,

def createTree(dataSet, labels):
	# 获取分类情况
    classList = [example[-1] for example in dataSet]

	# 基线情况
    if len(classList) == classList.count(classList[0]):
        return classList[0]
    if len(dataSet[0]) == 1:
        return repeat0(classList)

	# 在当前结点下选择最好的分类特征
    bestFeat = chooseBestFeatureToSplit(dataSet)
    bestFeatLabel = labels[bestFeat]

	# 构建最优特征的树
    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)
    return myTree

对于决策树的绘制还不是很懂,再研究研究在继续~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值