决策树创建

决策树:

优点: 计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可处理不相关特征数据。
缺点: 易过拟合

ID3、C4.5、CART树

ID3:
特征选择准则:信息增益
缺失值处理:没有考虑
优缺点:

  1. 不能处理连续数据,只能连续离散化处理
  2. 采用信息增益易偏向取值较多的特征(不如信息增益率)
  3. 缺失值不好处理
  4. 没有剪枝,易过拟合

C4.5:
特征选择准则:信息增益率
缺失值处理:可处理
优缺点:

  1. 产生的规则易于理解,准确率高,实现简单
  2. 对数据多次顺序扫描和排序,效率低
  3. 适合小规模数据集,需将数据放到内存中

CART:
特征选择准则:基尼系数

决策树一般流程

  1. 收集数据
  2. 准备数据:树构造算法只适用于标称型数据,因此数值型数据必须离散化
  3. 分析数据:可以使用任何方法,构造树完成后,应该检查图形是否符合预期
  4. 训练算法:构造树的数据结构
  5. 测试算法:使用经验树计算错误率
  6. 使用算法:可适用于任何监督学习算法,而使用决策树可以更好地理解数据的内在含义

以下示例来自于《机器学习实战》,使用 ID3 算法:

ID3 通过计算信息增益来得出哪个特征值用于划分数据集(信息增益最高的特征值就是最好的选择)
信息增益与信息熵:
在这里插入图片描述
在这里插入图片描述

用Python计算信息熵

from math import log

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

def calcShannonEnt(dataSet):
    numEntries = len(dataSet)        ## 计算数据集实例数
    labelCounts = {}
    for featVec in dataSet: #the the number of unique elements and their occurance(为所有可能分类创建字典)
        currentLabel = featVec[-1]       ## 键值为最后一列的数值
        if currentLabel not in labelCounts.keys(): labelCounts[currentLabel] = 0
        labelCounts[currentLabel] += 1    ## 记录每个类别的出现次数
    ##print(labelCounts)    ## 加入一行查看labelCounts字典
    shannonEnt = 0.0
    for key in labelCounts:
        prob = float(labelCounts[key])/numEntries
        shannonEnt -= prob * log(prob,2) #log base 2
    return shannonEnt

Mydata, labels = createDataSet()     ## 调用
calcShannonEnt(Mydata)

输出:

Out[18]: 0.9709505944546686

查看labelCounts字典

{'yes': 2, 'no': 3}

熵越高,数据越乱
我们可以在数据集中添加更多分类观察熵的变化:

Mydata[0][-1] = 'maybe'
Mydata

查看修改后Mydata

[[1, 1, 'maybe'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, 'no']]

重新计算

calcShannonEnt(Mydata)

分类由两个变为三个,熵也随之变大

1.3709505944546687

得到熵后,我们就可以按照获取最大信息增益的方法划分数据集。

划分数据集

对每个特征划分数据集的结果计算一次信息熵,然后判断按照哪个特征划分数据集是最好的划分方式。

按照给定特征划分数据集
def splitDataSet(dataSet, axis, value):
    retDataSet = []              ## 新建列表(Python在函数传递中是列表引用,在函数中的操作会直接影响原列表)
    for featVec in dataSet:
        if featVec[axis] == value:
            reducedFeatVec = featVec[:axis]     #chop out axis used for splitting(切掉用于分割的轴)(python包头不包尾)
            reducedFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reducedFeatVec)   ## 用append添加列表形成没有使用过的特征的新的数据集
    return retDataSet

调用splitDataSet()函数:

splitDataSet(Mydata, 0, 1)

输出:

[[1, 'yes'], [1, 'yes'], [0, 'no']]

来看一下当前Mydata:
在这里插入图片描述
splitDataSet(dataSet, axis, value)
splitDataSet(Mydata, 0, 1)返回的是第0个位置的特征值属性为1的集合。

接下里,将遍历整个数据集,循环计算香农熵和splitDataSet()函数,找到最好的特征划分方式。熵计算将会告诉我们如何划分数据集是最好的数据组织方式。

## 选择最好的数据集划分方式
def chooseBestFeatureToSplit(dataSet):
    numFeatures = len(dataSet[0]) - 1      #the last column is used for the labels(最后一列用于标签)
    baseEntropy = calcShannonEnt(dataSet)  ## 计算香农熵
    bestInfoGain = 0.0; bestFeature = -1
    for i in range(numFeatures):        #iterate over all the features(迭代所有功能)
        featList = [example[i] for example in dataSet]#create a list of all the examples of this feature(建个列表把第i个特征值和所有可能值存进去)(相当于按特征值的一列存)
#        print("featList = {}".format(featList))
        uniqueVals = set(featList)       #get a set of unique values(取特征值存在的所有情况的唯一元素值)
        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     #calculate the info gain(计算信息增益); ie reduction in entropy
        if (infoGain > bestInfoGain):       #compare this to the best gain so far(与目前最好的相比)
            bestInfoGain = infoGain         #if better than current best, set to best
            bestFeature = i
    return bestFeature                      #returns an integer(返回整数)(返回最好特征划分的索引值)

chooseBestFeatureToSplit(Mydata)
Out: 0

思路大概是:先算出当前结点的香农熵,然后遍历所有特征值,把遍历当前的特征值 i 的所有值存到新的List(特征值所对应的那一列的所有数值),并提取出唯一值(比如11122,取1,2),嵌套遍历每一个唯一值并用唯一值划分(例如:就是找到该特征值全是1的个数,然后去算熵),累加每个唯一值的信息熵,跳出嵌套循环,求得当前特征值 i 的信息增益,并于当前最大信息增益做判断,保存最大值,并保存当前特征值的序号,最后跳出所有特征值的遍历,返回最大信息增益的特征值位置。

递归构建决策树

## 创建树
def createTree(dataSet,labels):     ## 输入数据集和标签列表(虽然算法本身并不需要标签这个变量,只是为了给出数据明确的定义)
    classList = [example[-1] for example in dataSet]    ## 包含了所有类别标签
    if classList.count(classList[0]) == len(classList):   ## 若当前数据集所有标签都一致,则停止划分
        return classList[0]                  #stop splitting when all of the classes are equal
    if len(dataSet[0]) == 1: #stop splitting when there are no more features in dataSet
        return majorityCnt(classList)    ## 若使用完了所有的特征但仍没有划分完成,调用majorityCnt()函数,返回出现次数最多的类别
    ## 开始创建树
    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[:]       #copy all of labels, so trees don't mess up existing labels
        myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)
    return myTree  

调用

mytree = createTree(Mydata, labels)
mytree

输出:

{'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}

包含了好多嵌套字典。。。。。。
嵌套过程大概是这样的:
在这里插入图片描述

在Python中使用Matplotlib注解绘制树形图

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Graphviz是一个开源的图形可视化工具,可以用来创建各种类型的图表,包括决策树。下面是一个用Python语言结合Graphviz创建决策树的实例: 首先,我们需要安装Graphviz和python-graphviz库。 1. 打开终端,输入以下命令安装Graphviz: ```shell sudo apt-get install graphviz ``` 2. 接着,安装python-graphviz库: ```shell pip install graphviz ``` 然后,我们可以使用以下代码创建一个简单的决策树。 ```python from sklearn.datasets import load_iris from sklearn import tree import graphviz # 加载鸢尾花数据集 iris = load_iris() X, y = iris.data, iris.target # 创建决策树模型 clf = tree.DecisionTreeClassifier() clf = clf.fit(X, y) # 使用export_graphviz方法创建决策树图形 dot_data = tree.export_graphviz(clf, out_file=None, feature_names=iris.feature_names, class_names=iris.target_names, filled=True, rounded=True, special_characters=True) # 显示决策树图形 graph = graphviz.Source(dot_data) graph.view() ``` 运行以上代码后,将会弹出一个窗口显示决策树的图形。 注意,以上代码创建了一个基本的决策树,只是用来作为示例。在实际应用中,可能需要使用更复杂的数据集和调整一些参数来创建更准确的决策树模型。 总结起来,使用Graphviz创建决策树的步骤包括加载数据集、创建决策树模型、使用export_graphviz方法生成决策树图形,最后使用graphviz库显示图形。这样我们就能通过图形直观地理解决策树模型的决策过程了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值