【机器学习实战】决策树 python代码实现

2023-10-27


typora-copy-images-to: upload

第三章 决策树

3.1决策树的构造

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

一般流程:

收集数据 准备数据 分析数据 训练算法 测试算法 使用算法

image-20221004200305039

数据重新加载的问题

代码实现
# coding:UTF-8
from math import log


# 计算给定数据集的香农嫡
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


def createDataSet():
    dataSet = [[1, 1, 'yes'], [1, 1, 'yes'], [0, 1, 'no'], [0, 1, 'no']]
    labels = ['no surfacing', 'flippers']
    return dataSet, labels


def main():
    myDat, labels = createDataSet()
    print(myDat)
    print("%f" % calcShannonEnt(myDat))


if __name__ == "__main__":
    main()

实现截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wktrh11D-1664967392793)(https://cdn.jsdelivr.net/gh/hudiework/img@main/image-20221004200407218.png)]

获取最大信息增益的方法获取数据集 实现代码
 myDat[0][-1] = 'maybe'
    print(myDat)
    print("-------------")
    print(calcShannonEnt(myDat))
实现截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RgXGT47J-1664967392793)(https://cdn.jsdelivr.net/gh/hudiework/img@main/image-20221004200334343.png)]

3.2 划分数据集

3-2 按照给定特征划分数据集
# 选择最好的数据集划分方式
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
3.1.3 递归构建决策树

创建树的代码:

def createTree(dataSet, labels):
    classList = [example[-1] for example in dataSet]
    if classList.count(classList[0]) == len(classList):
        return classList[0]
    if len(dataSet[0]) == 1:
        return majorityCnt(classList)
    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[:]
        myTree[bestFeatLabel][value] = createTree(splitDataSet \
                                                      (dataSet, bestFeat, value), sublabels)
    return myTree
运行代码
myDat, labels = createDataSet()
mytree = createTree(myDat,labels)
print(mytree)
实现截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qyptJh00-1664967392793)(https://cdn.jsdelivr.net/gh/hudiework/img@main/image-20221004200245619.png)]

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

注解工具annotations

代码实现
from pylab import mpl
 
# 设置中文显示字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
# 设置正常显示符号
mpl.rcParams["axes.unicode_minus"] = False
def createPlot():
    fig = plt.figure(1, facecolor='white')
    fig.clf()
    createPlot.ax1 = plt.subplot(111, frameon=False)
    plotNode(U'Decision Node', (0.5, 0.1), (0.1, 0.5), decisionNode)
    plotNode(U'Leaf Node', (0.8, 0.1), (0.3, 0.8), leafNode)
    plt.show()
实现截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l4B1iqLy-1664967392794)(https://cdn.jsdelivr.net/gh/hudiework/img@main/image-20221005132825703.png)]

3.2.2 构造注解树

程序清单3-6 获取叶节点的树目和树的层数
MAC pycharm打不开

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MlxewiAV-1664967392794)(https://cdn.jsdelivr.net/gh/hudiework/img@main/image-20221005140639325.png)]

代码实现
def getNumLeafs(myTree):
    numLeafs = 0
    firstStr = list(myTree.keys())[0]
    secondDict = myTree[firstStr]
    for key in secondDict.keys():
        if type(secondDict[key]).__name__ == 'dict':
            numLeafs += getNumLeafs(secondDict[key])
        else:
            numLeafs += 1
    return numLeafs


def getTreeDepth(myTree):
    maxDepth = 0
    firstStr = list(myTree.keys())[0]
    secondDict = myTree[firstStr]
    for key in secondDict.keys():
        if type(secondDict[key]).__name__ == 'dict':
            thisDepth = 1 + getTreeDepth(secondDict[key])
        else:
            thisDepth = 1
        if thisDepth > maxDepth:
            maxDepth = thisDepth
    return maxDepth


def retrieveTree(i):
    listOfTrees = [{'no surfacing': {0: 'no', 1: {'flippers': \
                                                      {0: 'no', 1: 'yes'}}}},
                   {'no surfacing': {0: 'no', 1: {'flippers': \
                                                      {0: {'head': {0: 'no', 1: 'yes'}}, 1: 'no'}}}}
                   ]
    return listOfTrees[i]
结果截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-poBP9cv7-1664967392794)(https://cdn.jsdelivr.net/gh/hudiework/img@main/image-20221005143942150.png)]

程序清单3-7 plotTree函数
程序代码
def plotMidText(cntrPt, parentPt, txtString):
    xMid = (parentPt[0] - cntrPt[0]) / 2.0 + cntrPt[0]
    yMid = (parentPt[1] - cntrPt[1]) / 2.0 + cntrPt[1]
    createPlot.ax1.text(xMid, yMid, txtString)


def plotTree(myTree, parentPt, nodeTxt):
    numLeafs = getNumLeafs(myTree)
    depth = getTreeDepth(myTree)
    firstStr = list(myTree.keys())[0]
    cntrPt = (plotTree.xOff + (1.0 + float(numLeafs)) / 2.0 / plotTree.totalW, \
              plotTree.yOff)
    plotMidText(cntrPt, parentPt, nodeTxt)
    plotNode(firstStr, cntrPt, parentPt, decisionNode)
    secondDict = myTree[firstStr]
    plotTree.yOff = plotTree.yOff - 1.0 / plotTree.totalD
    for key in secondDict.keys():
        if type(secondDict[key]).__name__ == 'dict':
            plotTree(secondDict[key], cntrPt, str(key))
        else:
            plotTree.xOff = plotTree.xOff + 1.0 / plotTree.totalW
            plotNode(secondDict[key], (plotTree.xOff, plotTree.yOff), \
                     cntrPt, leafNode)
            plotMidText((plotTree.xOff, plotTree.yOff,), cntrPt, str(key))
    plotTree.yOff = plotTree.yOff + 1.0 / plotTree.totalD


def createPlot(inTree):
    fig = plt.figure(1, facecolor='white')
    fig.clf()
    axprops = dict(xticks=[], yticks=[])
    createPlot.ax1 = plt.subplot(111, frameon=False, **axprops)
    plotTree.totalW = float(getNumLeafs(inTree))
    plotTree.totalD = float(getTreeDepth(inTree))
    plotTree.xOff = - 0.5 / plotTree.totalW;
    plotTree.yOff = 1.0;
    plotTree(inTree, (0.5, 1.0), '')
    plt.show()
执行代码
matplotlib.use('TkAgg')
mytree = retrieveTree(0)
# print(getNumLeafs(mytree))
# print(getTreeDepth(mytree))
createPlot(mytree)
实现截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ICreMC7z-1664967392794)(https://cdn.jsdelivr.net/gh/hudiework/img@main/image-20221005172516454.png)]

3.3 测试和存储分类器

3.3.1 测试算法:使用决策树进行分类 程序3-8 使用决策树的分类函数

def classify(inputTree, featLabels, testVec):
    firstStr = list(inputTree.keys())[0]
    secondDict = inputTree[firstStr]
    featIndex = featLabels.index(firstStr)
    for key in secondDict.keys():
        if testVec[featIndex] == key:
            if type(secondDict[key]).__name__ == 'dict':
                classLabel = classify(secondDict[key], featLabels, testVec)
            else:
                classLabel = secondDict[key]
    return classLabel

实现代码
matplotlib.use('TkAgg')
myDat, labels = createDataSet()

mytree = retrieveTree(0)
# print(getNumLeafs(mytree))
# print(getTreeDepth(mytree))
# createPlot(mytree)
print(classify(mytree, labels, [1, 0]))
print(classify(mytree, labels, [1, 1]))
实现截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3118drTK-1664967392794)(https://cdn.jsdelivr.net/gh/hudiework/img@main/image-20221005173540215.png)]

3.3.2 使用算法:决策树的存储 3-9 使用pickle模块存储决策树

代码实现
def storeTree(inputTree, filename):
    import pickle
    fw = open(filename, 'wb')
    pickle.dump(inputTree, fw)
    fw.close()


def grabTree(filename):
    import pickle
    fr = open(filename, 'rb')
    return pickle.load(fr)
执行代码
mytree = retrieveTree(0)
print(mytree)
storeTree(mytree, 'classifierStorage.txt')
print(grabTree('classifierStorage.txt'))
实现截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fl8VDsSB-1664967392795)(https://cdn.jsdelivr.net/gh/hudiework/img@main/image-20221005180153803.png)]

使用决策树预测隐形眼镜类型

执行代码
matplotlib.use('TkAgg')
mytree = retrieveTree(0)
print(mytree)
storeTree(mytree, 'classifierStorage.txt')
# print(grabTree('classifierStorage.txt'))

fr = open('lenses.txt')
lenses = [inst.strip().split('\t') for inst in fr.readlines()]
# print("--------")
# print(lenses)
lensesLabels = ['age', 'prescipt', 'astigmatic', 'tearRate']
lensesTree = createTree(lenses, lensesLabels)
print(lensesTree)
createPlot(lensesTree)
实现截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8BlGHhSG-1664967392795)(https://cdn.jsdelivr.net/gh/hudiework/img@main/image-20221005185537583.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KOS7GKdd-1664967458351)(https://cdn.jsdelivr.net/gh/hudiework/img@main/image-20221005185537583.png)]

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【机器学习实战】决策树 python代码实现 的相关文章

随机推荐

  • 区块链节点和区块区别_《区块链百问百答》-区块链的节点竞选,到底是什么...

    上期讲解的区块链在医疗领域的应用 你看了吗 本期视频将解答大家关于节点竞选的困惑 现在跟随由LemoChain策划的 区块链百问百答 来认识一下吧 https www zhihu com video 1139492556072271872
  • 删除字符串最后一个字符的几种方法

    偶然看到的 记录一下 以免忘记 字符串 string s 1 2 3 4 5 目标 删除最后一个 方法 1 用的最多的是Substring 这个也是我一直用的 s s Substring 0 s Length 1 2 用 RTrim 这个我
  • 网络安全-php安全知识点

    目录 语法与注释 输出 变量 弱类型安全 超级全局常量 函数 常用 字符串相关 正则表达式 子字符串位置 数据库相关 mysqli pdo 伪协议相关 反序列化漏洞 serialize函数 unserialize函数 魔法函数 举例 写给和
  • MYSQL——解决多维度随机组合查询场景:grouping sets函数

    一 引入 注意 通常用在构建数据集市和复杂随机组合场景查询时使用 对于经常需要对数据进行多维度的聚合分析的场景 您既需要对A列做聚合 也要对B列做聚合 同时要对A B两列做聚合 因此需要多次使用union all 案例 比如此处有一张表te
  • C++算法之快速排序

    C 算法之快速排序 文章目录 C 算法之快速排序 一 快速排序引出 二 快排步骤 三 代码实现 四 复杂度分析 一 快速排序引出 我们知道 给一个长度为n的序列排序 有三种很简单的算法 选择排序 冒泡排序 插入排序 这三种算法的复杂度均为O
  • SpingBoot集成Swagger和Knife4j

    1 项目开发中编写接口文档实在是痛苦 于是打算引入swagger 之后发现swagger不够舒服 便又引入knife4j springboot的相关依赖不再贴 下面是swagger和knife4j的相关依赖 版本有需求的可以上maven中央
  • 百度群组链接分享 - 铁人圈子

    百度网盘群组链接分享 铁人圈子 铁人圈子 tierenpan com 是一个分享百度网盘群组的发布平台 可以在铁人圈子上实时分享你的群组链接 并且和其他网友互动交流分享资源 群组分享 百度群组链接分享 地址 https www tieren
  • shape文件格式简单说明

    一 简介 ShapeFile是Esri开发的一种空间数据格式 她是一种矢量数据存储格式 通常用于描述几何体形状 点 线 面 及相关属性 二 组成说明 2 1 必须文件 shp 图形格式 用于描述几何体形状 shx 图形索引格式 记录每一个几
  • 一文带你彻底搞懂二叉树(Python实现)——真香

    文章目录 前言 树 树中的一些术语 树的分类 树的存储表示 二叉树 二叉树的性质 二叉树的实现 二叉树结点的实现 二叉树的创建 广度优先遍历 先序 中序 后序遍历 后记 前言 终于到了数据结构中的关键部分了 二叉树 说起二叉树啊 简直是我当
  • PTA 浙大版《C语言程序设计(第4版)》题目集 习题4-6 水仙花数

    原题链接 问题描述 水仙花数是指一个N位正整数 N 3 它的每个位上的数字的N次幂之和等于它本身 例如 153 13 53 33 本题要求编写程序 计算所有N位水仙花数 输入格式 输入在一行中给出一个正整数N 3 N 7 输出格式 按递增顺
  • abp Application层获取请求的Header内容

    abp 如何在应用层返回header自定义的内容 参考 https blog csdn net u012659600 article details 99579369 首先在AppService中注入HttpContextAccessor
  • Ubuntu 更新 CMake 版本

    项目中有时候会出现CMake版本小于最低要求的情况 实际上没有有必要这么高的要求 但是在不能改对方代码的情况下 只能去升级自身的版本了 尝试了网上说的直接update之后再次安装的方式 结果版本号没有改变 sudo apt get upda
  • css文字超出隐藏显示...

    单行 overflow hidden white space nowrap text overflow ellipsis 多行 display webkit box webkit box orient vertical webkit lin
  • Windows10开启Hyper-v并安装Linux CentOS虚拟机

    Windows10开启Hyper v虚拟机配置静态网络 1 Windows10 开启Hyper v 右键单击 Windows 按钮并选择 应用和功能 选择相关设置下右侧的 程序和功能 选择 打开或关闭 Windows 功能 选择 Hyper
  • Element 标签页样式修改

    deep el tabs nav wrap after height 1px deep el tabs item height 50px font size 16px font family PingFang SC font weight
  • Java编程实现Softmax函数功能

    Java编程实现Softmax函数功能 Softmax函数是一种常用的数学函数 广泛应用于机器学习和深度学习领域 尤其在分类问题中起到重要作用 本文将介绍如何使用Java编程实现Softmax函数 并提供相应的源代码 首先 我们来了解一下S
  • centos7启动docker: dial tcp 104.18.123.25:443: i/o timeout.

    在centos7上安装好了docker之后 测试docker是否安装成功 使用官方给出的sudo docker run hello world 解决 再运行一遍命令即可
  • 自定义 scrollview 标头部分的滑动速度慢(scrollview 子控件滑动速度不一致)

    scrollview 子控件滑动速度不一致 先来个布局图 向上滑动时 图片向上划出的速度较下面的蓝色view慢 现在我们先来看布局文件
  • 基于tensorflow的手势检测和手势识别分类

    项目目的 在手机端实现用户手势的检测并且识别用户所做的手势 遇到的问题 首先在手部检测的解决办法中 我尝试过用opencv进行手部识别 但存在的问题是背景对手的识别的影响太大 如果采用颜色进行手和背景的区分的话 又会受到光照等影响 总体而言
  • 【机器学习实战】决策树 python代码实现

    typora copy images to upload 第三章 决策树 3 1决策树的构造 优点 计算复杂度不高 输出结果易于理解 对中间值的缺失不敏感 可以处理不相关的特征数据 缺点 可能会产生过度匹配的问题 适用数据类型 数据型和标称