机器学习之决策树

本文介绍了决策树分类方法,探讨了信息增益、信息增益率和基尼指数在决策树构建中的作用,以及ID3算法和C4.5算法的选择。通过实例展示了如何利用信息熵和特征选择来优化决策树结构,以提高分类准确性并减少过拟合风险。
摘要由CSDN通过智能技术生成

目录

概念

决策树停止划分的条件:

信息增益

信息增益率(C4.5)

基尼指数

构建决策树实例

1.ID3

 2.基尼指数

总结

概念

决策树(decision tree):是一种基本的分类与回归方法,这里讨论的的是分类的决策树。决策树分类是指从根节点开始,对实例的某一特征进行测试,根据测试结果将实例分配到其子节点,此时每个子节点对应着该特征的一个取值,如此递归的对实例进行测试并分配,直到到达叶节点,最后将实例分到叶节点的类中。

  • 优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据
  • 缺点:可能会产生过度匹配问题
  • 适用数据类型:数值型和标称型

构建决策树:特征选择、决策树的生成、决策树的修建

  1. 构建根节点,将所有训练数据都放在根节点,选择一个最优特征,按着这一特征将训练数据集分割成子集,使得各个子集有一个在当前条件下最好的分类。
  2.  如果这些子集已经能够被基本正确分类,那么构建叶节点,并将这些子集分到所对应的叶节点去。
  3. 如果还有子集不能够被正确的分类,那么就对这些子集选择新的最优特征,继续对其进行分割,构建相应的节点,如果递归进行,直至所有训练数据子集被基本正确的分类,或者没有合适的特征为止。
  4. 每个子集都被分到叶节点上,即都有了明确的类,这样就生成了一颗决策树。

决策树停止划分的条件:

  • 类别完全相同则停止划分;
  • 无特征可分(这种方式容易过拟合);即使无特征可分,仍不能将数据集划分成仅包含唯一类别的分组,所以挑选出现次数最多的类别作为返回值。
  • 设定阈值:某个特征的(内部结点)的信息增益小于一定的阈值。

信息增益

信息熵

  • x_{i}表示多个类别中的第i个类别,p(x_{i})表示数据集中类别为x_{i}的数据在数据集中出现的概率,假设共有n个类别x_{1},...,x_{n},信息熵Ent(X)的定义如下

                              Ent(X)=-\sum_{i=1}^{n}p(x_{i})log_{2}p(x_{i})

从公式中可以看出,如果概率是0或1时,熵就是0,不确定性是最低的。熵越大,不确定性就越高。 

条件熵 

  • 条件熵Ent(X|A)表示特征A为某个值的条件下,类别为X的熵

                             Ent(X|A)=\sum_{i=1}^{n}p_{i}Ent(X|A=a_{i})

信息增益(ID3)

信息增益 = 信息熵 - 条件熵

特征A对数据集D的信息增益记为Gain(X,A),公式为: 

                             Gain(X,A)=Ent(X)-Ent(X|A)

例子:X1、X2都是属性

样本X1X2分类
1TT+
2TT+
3TF-
4FF+
5FT-
6FT-

 计算已知A事件为X1下的信息增益(只看当前特征值与分类结果)

log_{2}(\frac{x}{y})=log_{2}x-log_{2}y

log_{2}1=0        log_{2}2=1        log_{2}3=1.585        log_{2}4=2        log_{2}5=2.322  

log_{2}6=2.585

Ent(D)=-(\frac{1}{2}log_{2}\frac{1}{2}+\frac{1}{2}log_{2}\frac{1}{2})=1

Ent(D|X1)=-\frac{1}{2}(\frac{2}{3}log_{2}\frac{2}{3}+\frac{1}{3}log_{2}\frac{1}{3})-\frac{1}{2}(\frac{2}{3}log_{2}\frac{2}{3}+\frac{1}{3}log_{2}\frac{1}{3})=0.918

Gain(D|X1)=Ent(D)-Ent(D|X1)=1-0,918=0.082

Ent(D|X2)=-\frac{4}{6}(\frac{1}{2}log_{2}\frac{1}{2}+\frac{1}{2}log_{2}\frac{1}{2})-\frac{2}{6}(\frac{1}{2}log_{2}\frac{1}{2}+\frac{1}{2}log_{2}\frac{1}{2})=1

Gain(D|X2)=Ent(D)-Ent(D|X2)=1-1=0

0.082>0,因此选X1为第一个特征

信息增益率(C4.5)

    \frac{Gain(D,A)}{Ent(A)}

基尼指数

G(p)=\sum_{k=1}^{k}p_{k}*(1-p_{k})=1-\sum_{k=1}^{k}p_{k}^{2}

构建决策树实例

1.ID3

根据公式算法得出一个数据集的信息熵

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

通过ID3算法选择信息增益最大的特征,结果返回信息增益的最大索引

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

def chooseBestFeatureToSplit(dataSet):  # 选择信息增益最大的特征
    numFeatures = len(dataSet[0]) - 1
    baseEntropy = 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 = baseEntropy - newEntropy
        if infoGain > bestInfoGain:
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature

导入数据集,取数据集中的偶数项作为训练集,取奇数项作为测试集

def file_train(filename):  # 取数据集偶数作为训练集
    fr = open(filename)
    lines = fr.readlines()
    res = []
    i = 0
    for line in lines:
        line = line.strip()
        temp = line.split(",")
        if i % 2 == 0:  # 取总数据集里的偶数
            res.append(temp)
        i += 1
    labels = ["top-left-square", "top-middle-square", "top-right-square",
     "middle-left-square", "middle-middle-square", "middle-right-square",
     "bottom-left-square","bottom-middle-square","bottom-right-square"]
    return res, labels

def file_test(filename):  # 取数据集的奇数作为测试集
    fr = open(filename)
    lines = fr.readlines()
    res = []
    i = 0
    for line in lines:
        line = line.strip()
        temp = line.split(",")
        if i % 2 == 1:  # 取总数据集里的奇数
            res.append(temp)
        i += 1
    labels = ["top-left-square", "top-middle-square", "top-right-square", "middle-left-square", "middle-middle-square", "middle-right-square","bottom-left-square","bottom-middle-square","bottom-right-square"]
    return res, labels

生成的决策树 

 2.基尼指数

def calcProbabilityEnt(dataSet):
    numEntries = len(dataSet)
    feaCounts = 0
    fea1 = dataSet[0][len(dataSet[0])-1]
    for feaVec in dataSet:
        if feaVec[-1] == fea1:
            feaCounts += 1
    probabilityEnt = float(feaCounts) / numEntries
    return probabilityEnt
    
#选择最好的数据集划分方式
def chooseBestFeatureToSplit(dataSet):
    numFeatures = len(dataSet[0]) - 1  #特征数量,numfeature为特征的维度,因为最后一列为标签,所以需要减去1
    if numFeatures == 1: 
        return 0
    bestGini = 1     #最佳基尼指数
    bestFeature = -1     #最优的划分特征初始化为-1
    for i in range(numFeatures):   #遍历所有的特征
        featList = [example[i] for example in dataSet]
        feaGini = 0    #定义特征的值的基尼系数
        uniqueVals = set(featList) 
        for value in uniqueVals: #遍历该特征维度下对应的所有特征值
            subDataSet = splitDataSet(dataSet, i, value)
            prob = len(subDataSet)/float(len(dataSet))
            probabilityEnt = calcProbabilityEnt(subDataSet)
            feaGini += prob * (2 * probabilityEnt * (1 - probabilityEnt))
        if (feaGini < bestGini):
            bestGini = feaGini
            bestFeature = i   #记录基尼指数最小的索引值
    return bestFeature

 

总结

ID3算法中,选择的是信息增益来进行特征选择,信息增益大的特征优先选择。基尼指数的意义是从数据集D中随机抽取两个样本类别标识不一致的概率。基尼指数越小,数据集的纯度越高。相比于信息增益,信息增益比等作为特征选择方法,基尼指数省略了对数计算,运算量比较小,也比较容易理解,所以CART树选择使用基尼系数用来做特征选择。在这个模型中用ID3算出的准确率比基尼指数的高一些。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值