《机器学习实战》笔记——第三章:决策树实战

本文是《机器学习实战》第三章的读书笔记,详细介绍了决策树实战,包括计算信息熵、划分数据集、递归构建决策树、测试和存储分类器。通过实例解释了如何使用Python实现决策树算法,并讨论了信息熵、信息增益等概念。文章还提到了决策树的过拟合问题和后续优化方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 说明

该书主要以原理简介+项目实战为主,本人学习的主要目的是为了结合李航老师的《统计学习方法》以及周志华老师的西瓜书的理论进行学习,从而走上机器学习的“不归路”。因此,该笔记主要详细进行代码解析,从而透析在进行一项机器学习任务时候的思路,同时也积累自己的coding能力。
正文由如下几部分组成:
1、实例代码(详细注释)
2、知识要点(函数说明)
3、调试及结果展示

2 正文

(1)计算给定数据集的信息熵

1、给定数据集为:

def createDataSet():
    dataSet = [[1, 1, 'yes'],
               [1, 1, 'yes'],
               [1, 0, 'no'],
               [0, 1, 'no'],
               [0, 1, 'no']]
    labels = ['no surfacing','flippers']
    #change to discrete values
    return dataSet, labels

该函数将书中表3-1海洋生物数据存在了一个python列表中,方便后续的处理。
接下来我们定义一个calcShannonEnt函数来计算香农信息熵:

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)#公式计算
    return shannonEnt

2、在python命令提示符下输入下列命令:

******
PyDev console: starting.
Python 3.6.7 |Anaconda, Inc.| (default, Oct 28 2018, 19:44:12) [MSC v.1915 64 bit (AMD64)] on win32
>>>import trees
>>>myDat, labels = trees.createDataSet()
>>>myDat
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
>>>trees.calcShannonEnt(myDat)
0.9709505944546686
>>>myDat[0][-1] = 'maybe'
>>>myDat
[[1, 1, 'maybe'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
>>>trees.calcShannonEnt(myDat)
1.3709505944546687

我们可以看到,在数据集中添加更多的分类,信息熵明显变大了。

知识要点:
①信息熵:是度量样本集合纯度最常用的一种指标,信息的期望值。
《机器学习》(周志华 著):假定当前样本集合D中第k类样本所占的比例为pk(k=1,2,…,∣γ∣),p_{k}(k=1,2,…,|γ|),pkk=1,2,,γ则D的信息熵定义为Ent(D)=−∑k=1∣γ∣pklog2pkEnt(D)=-\sum _{k=1}^{|γ|}p_{k}log_{2}p_{k}Ent(D)=k=1γpklog2pk
信息熵Ent(D)的值越小,则信息的纯度就越高。

(2)划分数据集

1、我们将对每个特征划分数据集的结果计算一次信息熵,然后判断按照哪个特征划分数据集是最好的划分方式,下面我们先定义一个函数,用来实现按照给定的特征划分数据集这一功能:

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

这段代码其实很简单,但是有个地方需要解释一下,就是:

reducedFeatVec = featVec[:axis]
reducedFeatVec.extend(featVec[axis+1:])

虽然我知道这里肯定在剔除axis特征,并输出剩下元素组成的特征向量,但是一开始还是没绕过弯来,一直还以为是自己“切片”没学好了…下面我通过在python交互环境下进行测试操作,来更好地理解这两句话真正干了什么。

******
PyDev console: starting.
Python 3.6.7 |Anaconda, Inc.| (default, Oct 28 2018, 19:44:12) [MSC v.1915 64 bit (AMD64)] on win32
>>>a=[1, 1, 0]
>>>b=a[:0]
>>>b
[]
>>>c=a[:1]
>>>c
[1]
>>>d=a[:2]
>>>d
[1, 1]
>>>d.extend(a[3:])
>>>d
[1, 1]
>>>d.append(a[3:])
>>>d
[1, 1, []]

从上面这一波操作可以看出,通过第一步操作,可以将axis以前的元素存到reduceFeatVec列表中,而通过第二步操作,可以将axis以后的元素也同样存进去,这样就可以剔除axis了。最后extend()和append()的区别就不做赘述了。好吧,归根到底,还是“切片”没学好,哈哈~

2、那么下面我们就跟着书中的例程继续走,在python命令提示符内输入下面命令,执行后得到划分后结果:

******
PyDev console: starting.
Python 3.6.7 |Anaconda, Inc.| (default, Oct 28 2018, 19:44:12) [MSC v.1915 64 bit (AMD64)] on win32
>>>import trees
>>>myDat, labels = trees.createDataSet()
>>>myDat
[[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]
>>>trees.splitDataSet(myDat, 0, 1)
[[1, 'yes'], [1, 'yes'], [0, 'no']]
>>>trees.splitDataSet(myDat, 0, 0)
[[1, 'no'], [1, 'no']]

我们可以很直观看出, 通过最后两条命令,数据集通过“不浮出水面是否可以生存”这一特征被划分。

3、以上无论是用来计算香农信息熵的calcShannonEnt函数,还是用来划分数据集的splitDataSet函数,其实都是我们提前做好的两个“工具包”,因为我们从决策树的原理上理解也很容易看出,这两个函数的计算肯定不止一次,需要根据数据集的需要进行循环计算,并在前后评估信息增益,从而才能找到我们想要的结果——最优的数据集划分方法。
那么下面就进入了这一步,我们在trees.py添加chooseBestFeactureToSplit函数:

def chooseBestFeatureToSplit(dataSet):
    numFeatures = len(dataSet[
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值