机器学习实战——3.1 决策树的构造

内容

1. 信息增益

2. 划分数据集

2.1 按照给定特征划分数据集

2.2 选择最好的数据集划分方式

3. 递归构建决策树

3.1 多数表决的方法

3.2 创建树

1. 信息增益

数据集划分前后的信息变化称为信息增益,获取信息增益最高的特征是最佳选择。聚合信息的度量称为香农熵或简称熵。

此代码的函数公式计算给定数据集的熵:

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
        shannonent -= prob*log(prob, 2)  # 以2为底求对数
    return shannonent

我们可以利用creatdataset()函数得到简单鱼鉴定数据集:

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

查看数据集:

mydata, labels = creatdataset()
print("mydata:", mydata)
print("labels:", labels)
print("香农熵:", calcshannonent(mydata))

输出结果:

机器学习实战——3.1 决策树的构造

熵越高,则混合数据也越多,这里我们增加第三个名为maybe的分类,测试熵的变化:

mydata[0][-1] = 'maybe'
print("mydata:", mydata)
print("香农熵:", calcshannonent(mydata))

输出结果:

机器学习实战——3.1 决策树的构造

2. 划分数据集

2.1 按照给定特征划分数据集

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

查看划分结果:

mydata, labels = creatdataset()
print(mydata)
print(splitdataset(mydata, 0, 1))
print(splitdataset(mydata, 0, 0))

输出结果:

机器学习实战——3.1 决策树的构造

2.2 选择最好的数据集划分方式

接下来我们将遍历整个数据集,循环计算香农熵和splitdataset()函数,找到最好的特征划分方式。

def choosebestfeaturetosplit(dataset):
    numfeatures = len(dataset[0])-1
    bestentropy = calcshannonent(dataset)  # 计算整个数据集的原始香农熵
    bestinfogain = 0.0; bestfeature = -1
    for i in range(numfeatures):  # 遍历数据集中的所有特征
        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 = bestentropy - newentropy  # 信息增益
        if (infogain > bestinfogain) :
            bestinfogain = infogain
            bestfeature = i
    return bestfeature  # 返回最好特征划分的索引值

查看分区数据集的最佳功能:

mydata, labels = creatdataset()
print("choose best feature to split:", choosebestfeaturetosplit(mydata))

输出结果:

机器学习实战——3.1 决策树的构造

可知第0个特征是最好的用于划分数据集的特征

3. 递归构建决策树

3.1 多数表决的方法

如果数据集已经处理了所有属性,但类标签仍然不唯一,这种情况下,我们通常使用多数票来确定叶子节点的分类

import operator
def majoritycnt(classlist):
    classcount = {}
    for vote in classlist:
        if vote not in classcount.keys(): classcount[vote] = 0
        classcount[vote] += 1
    sortedclasscount = sorted(classcount.iteritems(),\
                              key = operator.itemgetter(1), reverse=True)
    return sortedclasscount[0][0]

3.2 创建树

def createtree(dataset, labels):
    classlist = [example[-1] for example in dataset]  # classlist中包含数据集的所有类标签
    if classlist.count(classlist[0]) == len(classlist):
        return classlist[0]  # 递归的第一个停止条件是所有类标签完全相同,直接返回该类标签
    if len(dataset[0]) == 1:  # 递归的第二个停止条件是使用完了所有特征,仍不能将数据集划分为仅包含唯一类别的分组
        return majoritycnt(classlist)  # 返回挑选次数最多的类别
    bestfeat = choosebestfeaturetosplit(dataset)  # 当前数据集选取的最好特征存储在变量bestfeat中
    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

查看树结构信息:

mydata, labels = creatdataset()
mytree = createtree(mydata, labels)
print("my tree:", mytree)

输出结果:

机器学习实战——3.1 决策树的构造

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2022年4月15日 上午10:53
下一篇 2022年4月15日 上午11:10

相关推荐