**决策树基础以及Python代码实现**

本文介绍了决策树的基本概念,包括信息熵、数据集划分和最优特征选择,并提供了Python代码实现的概述。

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

一、一些定义:
1. 信息: 西瓜有好瓜和坏瓜,好瓜的信息为

l(xi)=log2p(xi)
p(xi)为好瓜的概率,根据-log函数的图像,如果好瓜的概率越大,信息会趋近于0,也就是从一堆瓜里选出好瓜所需要的信息量越少。
2. 信息熵:熵是信息的期望值
Ent(D)=k=1npklog2pk
D是西瓜数据集,Ent(D)的值越小,D的纯度越高。
在西瓜只分为好瓜和坏瓜的情况下,p(x1)是好瓜的概率,p(x2)为坏瓜的概率,p(x1)+p(x2)=1,这时候信息熵在它们均为0.5时达到最大,若是纯度较高,即好瓜的概率较大,则信息熵比较小。

3.信息增益:假定离散属性a有V个可能的取值,若使用属性a对样本集D进行划分,则会有V个分支节点,第v个分支节点上的样本DvDv中也有好瓜和坏瓜,可以计算出Dv的信息熵,信息增益的公式为:
Gain(D,a)=Ent(D)v=1V|DV||D|Ent(Dv)
|Dv|Dv中的样本个数,|D|为D中的样本个数。一般而言,信息增益越大,意味着通过属性a划分所获得的“纯度提升”越大。
4.增益率:一般而言,选择的属性可取值数目越多,信息增益会越大,所以为了减少这种不利影响,C4.5不直接用信息增益,而是用‘增益率’(gain ratio)来选择划分最优属性。
Gain.ratio(D,a)=Gain(D,a)IV(a)

其中
IV(a)=v=1V|Dv||D|log2|Dv||D|

IV(a)是属性a的信息熵,一般属性a的可能取值数目越多,IV(a)通常会越大。C4.5算法不是直接选择增益率最大的划分属性,因为增益率准则对可取值数目较小的属性有所偏好,C4.5是先从候选划分属性中找出信息增益率高于平均水平的属性,再从中选择增益率最高的。(折中选择)
5.基尼系数:基尼值:
Gini(D)=k=1nkkpkpk
=1k=1np2k
不难看出,Gini越小,则数据集D的纯度越高。和信息熵的作用是一样的。属性a的基尼指数:
Gini.index(D,a)=v=1n|Dv||D|Gini(Dv)
选择基尼指数最小的属性作为最优划分属性,基尼指数与信息增益的方法一样,只是测量数据集的纯度公式不一样。CART决策树就是用基尼系数准则。
二、决策树算法
1.ID3算法:应用信息增益准则,选择信息增益最大的属性。
2.C4.5算法:信息增益准则偏好可取值数目多的属性,而增益率偏好可取值数目少的属性,因此C4.5算法综合了信息增益准则和增益率准则,首先从候选属性中找出信息增益高于平均水平的属性,再从中选择增益率最高的。
3.CART决策树:使用基尼指数来划分属性,选择基尼指数最小的属性作为最优属性划分,和ID3算法殊途同归,只是衡量数据集纯度的方法不一样。
三、Python代码:
1.计算给定数据集的信息熵
from math import log
from pandas import DataFrame
from collections import Counter
def ShannonEnt(dataSet):  #自定义一个函数
    data = DataFrame(data = dataSet) #把列表转化为表格型数据
    num = len(data)  #data的行数
    labelCounts = Counter(data[3])#对相应列的不同元素计数,这是第四列
    shannonEnt = 0.0 #初始化信息熵的值
    for key in labelCounts:  #遍历labelCounts中的关键字
        prob = float(labelCounts[key])/num  #计算第四列不同元素出现的概率
        shannonEnt -= prob*log(prob,2) 
        #shannonEnt = shannonEnt-prob*log(prob,2)
    return shannonEnt

2.按照给定特征划分数据集

def splitDataSet(dataSet, axis, value):
    retDataSet = []  #初始化数据集
    for featVec in dataSet:  #遍历列表中的每一行
        if featVec[axis] == value: 
        #如果该行的第axis+1(给定特征的列)值=value
            reducedFeatVec = featVec[:axis] 
            reducedFeatVec.extend(featVec[axis+1:]) #该行去掉给定特征的列
            retDataSet.append(reducedFeatVec)#扩充满足条件的行
        return retDataSet

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

def chooseBestFeatureToSplit(dataSet):
    numFeatures = len(dataSet[0])-1  #第一行的个数-1
    baseEntropy = ShannonEnt(dataSet)
    bestInfoGain = 0.0
    bestFeature = -1   
    for i in range(numFeatures):  
    #[i for i in range(3)]->[0,1,2]
        featList = [example[i] for example in dataSet]
        #选取dataSet的第i+1列
        uniqueVals = set(featList) #去掉重复值
        newEntropy = 0.0
        for value in uniqueVals:  #遍历uniqueVals中的每个值
            subDataSet = splitDataSet(dataSet,i,value)
            #根据第i个特征划分数据集
            prob = len(subDataSet)/float(len(dataSet))
            newEntropy += prob * ShannonEnt(subDataSet)
        infoGain = baseEntropy - newEntropy 
            #信息增益公式
        if(infoGain > bestInfoGain):
           bestInfoGain = infoGain
           bestFeature = i #选取信息增益最大的特征值
    return bestFeature
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值