《机器学习实战》chapter03 决策树

机器学习(三)——决策树构建 决策树 阅读详情

分类生成决策树

import operator
from math import log
import pickle


# 计算香农熵
def calcShannonEnt(dataSet):
    """1、计算每个类别的频数"""
    numEntries = len(dataSet)
    # 类别字典,保存不同类别的频数
    labelCounts = {}
    for featVec in dataSet:
        currentLabel = featVec[-1]
        # 如果当前类别不在字典中,将其加入
        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel] = 0
        # 当前类别数量+1
        labelCounts[currentLabel] += 1
    """2、用香农熵公式计算香农熵"""
    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'],
               [1, 0, 'no'],
               [0, 1, 'no'],
               [0, 1, 'no']]
    labels = ['no surfacing', 'flippers']
    return dataSet, labels


# 划分数据集,以axis索引位的特征为根节点
def splitDataSet(dataSet, axis, value):
    retDataSet = []
    for featVec in dataSet:
        if featVec[axis] == value:
            reduceFeatVec = featVec[:axis]
            reduceFeatVec.extend(featVec[axis + 1:])
            retDataSet.append(reduceFeatVec)
    return retDataSet


# 选择最好的数据集划分形式
def choseBestFeatureToSplit(dataSet):
    # 特征个数, 有一个是类别(去掉)
    numFeature = len(dataSet[0]) - 1
    baseEntropy = calcShannonEnt(dataSet)
    bestInfoGain = 0.0
    bestFeature = -1
    # 计算以第i个特征作为划分节点时的信息增益,选择信息增益最大的特征作为划分节点
    for i in range(numFeature):
        # 取当前数据集的第i个特征(第i列的所有值)
        featList = [example[i] for example in dataSet]
        # 当前特征的可能取值范围(去重复)
        uniqueValues = set(featList)
        newEntropy = 0.0
        # 计算当前特征的信息增益
        for value in uniqueValues:
            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 majorityCnt(classList):
    classCount = {}
    for vote in classList:
        if vote not in classCount.keys():
            classCount[vote] = 0
        classCount[vote] += 1
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]


# 递归构建决策树
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 = choseBestFeatureToSplit(dataSet)
    bestFeatLabel = labels[bestFeat]
    myTree = {bestFeatLabel: {}}
    del labels[bestFeat]
    featVlues = [example[bestFeat] for example in dataSet]
    uniqueValues = set(featVlues)
    for value in uniqueValues:
        # 注意分号,复制labels到subLabels,单独开辟了一块内存空间
        # 如果没有分号的则是subLabels指向labels指向的内存
        # 会因修改labels内容而出错
        subLabels = labels[:]
        myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value), subLabels)
    return myTree

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


def storeTree(inputTree, fileName):
    try:
        with open(fileName, 'wb') as fw:
            pickle.dump(inputTree, fw)
    except IOError as e:
        print("File Error : " + str(e))


def grabTree(fileName):
    fr = open(fileName, 'rb')
    return pickle.load(fr)

使用Matplotlib注解绘制树形图

import matplotlib.pyplot as plt

# boxstyle文本框样式, fc(face color)背景透明度
decisionNode = dict(boxstyle="round4, pad=0.5", fc="0.8")
leafNode = dict(boxstyle="circle", fc="0.8")
# 箭头样式
arrow_args = dict(arrowstyle="<-")


# 绘制节点
def plotNode(nodeTxt, centerPt, parentPt, nodeType):
    # 被注释的地方xy(x, y)和插入文本的地方xytext(x, y)
    # xycoords和textcoords指定xy和xytext的坐标系。此处是左下角(0.0,0.0),右上角(1.0,1.0)
    # 文本在文本框中的va(纵向),ha(横向)居中
    createPlot.ax1.annotate(nodeTxt, xy=parentPt, xycoords="axes fraction",
                            xytext=centerPt, textcoords="axes fraction", va="center",
                            ha="center", bbox=nodeType, arrowprops=arrow_args)


# 获取叶节点数目
def getNumLeafs(myTree):
    numLeafs = 0
    # Python3与Python2的区别,先转换成list,再按索引取值
    # firstStr = myTree.keys()[0]
    firstStr = list(myTree.keys())[0]
    # 子树
    secondDict = myTree[firstStr]
    for key in secondDict.keys():
        if type(secondDict[key]).__name__ == 'dict':
            # 如果是decisionNode,递归
            numLeafs += getNumLeafs(secondDict[key])
        else:
            # leafNode
            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':
            # 如果是decisionNode(有子节点),递归
            thisDepth = 1 + getTreeDepth(secondDict[key])
        else:
            # leafNode,叶子节点
            thisDepth = 1
        # 修正maxDepth,保证maxDepth是最大值
        if thisDepth > maxDepth:
            maxDepth = thisDepth
    return maxDepth


# 在父子节点之间填充文本信息
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]
    # 修正当前位置,xOff + 当前树的叶子节点数 / 2W + 1 / 2W
    # 加1/2W 是因为初始位置是-1/2W,修正这个位置
    cntrPt = (plotTree.xOff + (1.0 + float(numLeafs)) / (2.0 * plotTree.totalW), plotTree.yOff)
    # 在父子节点间填充文本信息
    plotMidText(cntrPt, parentPt, nodeTxt)
    # decisionNode,绘制
    plotNode(firstStr, cntrPt, parentPt, decisionNode)
    # 当前树的子节点
    secondDict = myTree[firstStr]
    # 深度加1,修正plotTree.yOff - 1/D
    plotTree.yOff = plotTree.yOff - 1.0 / plotTree.totalD
    # 遍历绘制子节点
    for key in secondDict.keys():
        if type(secondDict[key]).__name__ ==  'dict':
            # decisionNode,调用plotTree绘制
            plotTree(secondDict[key], cntrPt, str(key))
        else:
            # 遇到leafNode,修正xOff + 1/W,调用plotNode绘制
            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))
    # 初始偏移量-1/2W,每遇到一个叶节点加1/W,使画出来的树尽可能居中
    # 如3个叶子(1/6, 1/2, 5/6),4个叶子(1/8, 3/8, 5/8, 7/8)
    plotTree.xOff = -0.5 / plotTree.totalW
    # 初始深度0,第一层
    plotTree.yOff = 1.0
    # 绘制图形
    plotTree(inTree, (0.5, 1.0), '')
    plt.show()


myTree = {'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}, 3: 'maybe'}}
createPlot(myTree)

测试

from chapter3 import treePlotter
from chapter3 import trees

fr = open('lenses.txt')
lenses = [inst.strip().split('\t') for inst in fr.readlines()]
lensesLabels = ['age', 'prescript', 'astigmatic', 'tearRate']
lensesTree = trees.createTree(lenses, lensesLabels)
print(lensesTree)
treePlotter.createPlot(lensesTree)


机器学习实战(二)决策树DT(Decision Tree、ID3算法) 目录 0. 前言 1. 信息增益(ID3) 2. 决策树(Decision Tree) 3. 实战案例 3.1. 隐形眼镜案例 3.2. 存储决策树 3.3. 决策树画图表示 学习完机器学习实战的决策树,简单的做个笔记。文中部分描述属于个人消化后的理解,仅供参考。 所有代码和数据可以访问 我的 github 如果这篇文章对你有一点小小的帮助,请给个关注喔~我会非常开心的~ ... 阅读详情

相关推荐

上下文工程:构建大模型的认知环境与工业级实践

上下文工程是大语言模型落地应用的核心基础能力,它超越提示词设计,聚焦于为模型系统性构建稳定、精准、可演化的认知环境。其本质是通过锚定层确立角色与约束、增强层注入动态任务知识、调节层实现时效性与个性化适配,从而保障AI输出的准确性、合规性与业务一致性。该技术直接支撑客服对话、政策问答、合同审查等高要求场景,尤其在医疗、金融、政务等强监管领域,决定模型是否具备生产可用性。本文结合医保政策问答系统等真实案例,详解从资产治理、动态组装到热更新的全链路工程实践,覆盖ContextFlow流水线、三层压缩策略及L0-L

weixin_30634661的博客 389

可视化实验一

实验目的 掌握text,xlabel,ylabel,title,annotate等函数的使用 熟悉掌握使用matplotlib画图的标注方法 实验原理 确定坐标范围 plt.axis([xmin, xmax, ymin, ymax]):axis()命令给定了坐标范围 xlim(xmin, xmax)和ylim(ymin, ymax)来调整x,y坐标范围 xlable(), ylable()用于添加x轴和y轴标签 matplotlib.pyplot.xlabel(label, f

ZZULI_星.夜 1270

OpenClaw工程实战

OpenClaw工程实战总览摘要 OpenClaw是一款面向AI Agent开发的全栈式解决方案,采用四层模块化架构(基础设施层、核心引擎层、生态组件层和应用适配层)。文档全面覆盖从环境配置到企业落地的九大技术板块,包含MCP协议实战、多Agent编排、商业级项目实践等核心内容。系统支持全场景部署(本地/云端/边缘设备),集成3286个市场技能,通过Gateway网关实现智能路由与多模型调度。典型应用场景包括企业数字化、开发者提效和全渠道智能助手。

lza_csdn2019的博客 631

决策树(一):基本概念

1.什么是决策树

gsw2276435493gsw的博客 1432

清华Python教材配套资源:Jupyter Notebook实战指南与数据分析机器学习学习路径

Python作为当前最流行的编程语言之一,其核心价值在于强大的生态系统和广泛的应用场景。其工作原理基于解释型语言特性,通过丰富的第三方库支持高效开发。在技术价值层面,Python极大地降低了编程门槛,并成为数据科学和人工智能领域的事实标准工具。特别是在数据分析与机器学习等应用场景中,NumPy、Pandas和Scikit-learn等库提供了从数据清洗、处理到模型构建的全套解决方案。本文聚焦于一套系统性的**Jupyter Notebook**教学资源,它通过交互式编程环境,将**数据分析**和**机器学习

weixin_34161083的博客 527

CentOS7下Node.js v20+安装与常见依赖库问题解决指南

本文详细介绍了在CentOS7系统下安装Node.js v20+的完整流程及常见依赖库问题的解决方案。通过升级glibc到2.28+、配置环境变量以及处理libstdc++版本问题,帮助开发者顺利在老旧系统上部署最新版Node.js,提升开发效率。

weixin_30689307的博客 157

机器学习决策树代码实现

机器学习算法

m0_56695478的博客 240

使用Hyper-V使用下载下来的macOS安装引导安装macos

然后关闭工具返回安装界面选择第二个reinstall,选择119g那个硬盘。我的资源上传了:macOS Monterey on Hyper-V.7z。设置固件的启动顺序,引导安装盘放到第一位,mac安装110g放第二。选择disk utility格式化那个110g。下载解压的macos引导挂载到虚拟硬盘。其他设置安全禁用,检查禁用,集成都选中。新建一个虚拟硬盘装mac,110g。

viviliving的专栏 3024

如何构建高效量化交易系统:机器学习实战指南

Hands-On Machine Learning for Algorithmic Trading 是一个专注于机器学习算法交易的实战项目,提供了从数据获取到模型部署的全套代码实现。这个项目通过Python技术栈帮助开发者构建智能交易策略,利用机器学习技术从金融数据中提取价值信号,实现自动化投资决策。 ## 🚀 项目核心价值:从理论到实践的量化交易桥梁 这个项目的核心价值在于将复杂的机器学习

gitblog_01167的博客 984

[RK3588从入门到精通] 专栏目录及介绍

[RK3588从入门到精通] 专栏目录及介绍

nb124667390的博客 6500

【新华三】DHCP+TFTP+ZTP自动开局实战

设备运行ZTP功能,可以自动获取并自动加载开局文件,实现设备的免现场配置和部署,从而降低人力成本,提升部署效率。使用TFTP服务器工具进行文件的上传和下载,网上很多TFTP server软件,大家可以自行下载。3CDaemon等,可以根据使用自取所需。大家应该都了解ZTP,但是目前发现除了控制器之外仅使用ZTP开局的兄弟并不是很多,因此分享此过程方便大家批量开局,留出更多时间学习更多技术。电脑打开DHCP服务器,TFTP服务器,并通过网线连接到设备的管理口,若设备较多可以通过带外交换机等进行连接,

五大连池的镜子 4982

Python机器学习终极指南:10个开源工具对比与实战技巧

Python机器学习是当今人工智能领域最热门的技术之一,而GitHub上的python-machine-learning-book项目则为初学者和开发者提供了丰富的实战资源和代码示例。本文将深入探讨该项目中的10个核心开源工具,帮助你快速掌握机器学习的关键技能,从数据处理到模型部署,全方位提升你的实战能力。 ## 为什么选择Python进行机器学习? Python凭借其简洁的语法、丰富的库支持

gitblog_01051的博客 883

深入解析UE5内存分析:从Memreport到Unreal Insights

本文深入解析了UE5内存分析的两大核心工具:Memreport与Unreal Insights。Memreport提供详细的内存快照,帮助定位UObject等资源的内存占用;而Unreal Insights则能进行实时监控与历史回溯,精准追踪内存泄漏。掌握这两款工具是优化UE5项目性能、确保大型项目稳定运行的必备技能。

lg888的博客 1013

CANN ops-transformer msa_index_score 算子完全指南:MSA Index Branch block score 的 PyTorch 调用与原理剖析

本篇技术指南以 CANN ops-transformer 开源仓库中的 [torchapi_msa_index_score.md](https://link.gitcode.com/i/16f6a9c1f481eae422634cbbd690b1a0) 为主线,系统讲解 MSA(MiniMax Sparse Attention)Index Branch 中 block score 算子的 PyTo

gitblog_00562的博客 978

智能车‘大脑’的诞生:揭秘电磁循迹代码背后的控制论与系统思维

本文深入探讨智能车电磁循迹系统的核心架构与控制原理,揭示了其作为精密闭环系统如何通过模块化设计、信号处理、PID控制算法及电机驱动实现自主导航。重点分析了电磁信号采集与处理流程框架,为开发者提供从理论到实践的全面指南。

arduino9maker的博客 531

亚马逊跨境电商选品数据分析:Python爬虫实战指南

本文将带领大家构建一套完整的亚马逊选品数据采集与分析系统,使用最新的Python技术栈,从零开始爬取亚马逊商品数据,并进行深度分析。

2201_76125261的博客 299

智慧图书阅读基于HarmonyOS ArkTS 24实现完成为了支持本地持久化(书架列表的progress直接读取避免每次计算),这种“缓存trade-off“在性能敏感场景下是合理的工程选择

在 HarmonyOS NEXT 正式商用的背景下,ArkTS 作为鸿蒙生态的官方应用开发语言,正在从传统的命令式 UI 开发范式向声明式 UI 范式全面迁移。ArkUI 框架以组件化、声明式、状态驱动为核心特征,要求开发者以"描述 UI 应该是什么样"而非"一步步操作 UI 怎么变"的思维方式构建界面。

2301_79516720的博客 301

光学材料仿真软件:FDTD Solutions_(4).材料属性的定义与应用

在光学材料仿真软件中,材料属性的定义和应用是至关重要的一步。正确地定义材料属性可以确保仿真结果的准确性和可靠性。本节将详细介绍如何在FDTD Solutions中定义和应用不同的材料属性,包括介质材料、金属材料、色散材料等,并提供具体的代码示例和数据样例。介质材料是光学仿真中最常见的材料类型之一。在FDTD Solutions中,可以通过多种方式定义介质材料,包括使用预定义的材料库、自定义材料参数或导入材料数据文件。FDTD Solutions内置了一个丰富的材料库,包含了许多常用材料的光学性质。

kkchenjj的博客 1401

LangChain 1.3 完全教程:从入门到精通-Part 7: Documents(文档处理)做好软件测试你要学习这些

"""自定义 Document Loader Demo""""""自定义文档加载器继承 BaseLoader 并实现 lazy_load 方法即可创建自定义加载器。"""self,):"""参数:data_source: 数据源标识(可以是文件路径、URL、数据库连接等)encoding: 文本编码metadata: 附加到所有文档的元数据""""""惰性加载文档(必须实现)返回一个 Document 对象的迭代器。这是 BaseLoader 要求实现的唯一方法。

lw的博客 517

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

小试牛刀Matplotlib

1、plt.subplot()import matplotlib.pyplot as plt # Integer subplot specification must be a three digit number # 前两位代表横竖长度比 # 左边的代表横,中间的代标纵坐标,右边的则表示绘图位置(当横纵比不是1:1时) ax1, ax2, ax3 = plt.subplot(231), plt...

君只见独不见的专栏 1832

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Python中的三引号的用法

python中三引号可以将复杂的字符串进行复制:python三引号允许一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符。三引号的语法是一对连续的单引号或者双引号(通常都是成对的用)。跨多行、换行符、制表符:chat = """how are you? i'm fine, than you,and you?     me too!""" print(chat)加注释:data = ...

君只见独不见的专栏 7万+

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Python中的向量、矩阵(numpy)

1、向量、矩阵表示: numpy的向量表示是通过array数组来实现的 一维向量(行、列): 在numpy中一维向量用一位数组array([1, 1, 1])表示,既能表示行向量也能表示列向量,一维向量转置后还是原来的样子(因为存储结构是数组) from numpy import * v1 = array([0, 0, 0]) v1t = v1.transpose() print(v1...

君只见独不见的专栏 4万+

LeetCode第一刷--leetcode提交格式介绍与273. Integer to English Words

第一次玩Leetcode,对代码提交格式不了解,提交了一上午,略尴尬 leetcode确实有很多有意思的地方,不像以前做各个高校ACM练习,leetcode会给出错误信息(哪个数据的错了),也会提供测试用例自定义窗口,你可以自己设置测试样例 对于输出结果会有个比较窗口,出现你的程序和源程序结果比对,帮你快速定位错误原因 此外,leetcode只需要你写核心代码部分,读取输入函数,函数...

君只见独不见的专栏 1万+

Python获取控制台输入

Python获取控制台输入有两种方式:input()和raw_inputPython3之后raw_input()已经被删除了。Python2中有input和raw_input两个函数,其中raw_input将所有输入作为字符串看待,返回字符串类型。input函数支持表达式、数字类型、字符串类型,接受为表达式时,只返回其执行结果。在Python3中对input和raw_input函数进行了整合,仅保...

君只见独不见的专栏 1万+

Miniconda3及pip换源(conda清华源关闭)

Miniconda3及pip换源 一、更换miniconda3的源,以清华的源为例: 清华源地址:https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/ 安装完miniconda3之后,执行下列命令即可 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anac...

君只见独不见的专栏 8896

Python把数据存储到CSV

CSV(Comma-Separated Values,逗号分隔值)是存储表格数据的常用文件格式。MicrosoftExcel 和很多应用都支持 CSV 格式,因为它很简洁。例如:fruit,costapple,1.00banana,0.30pear,1.25和 Python 一样,CSV 里留白(whitespace)也是很重要的:每一行都用一个换行符分隔,列与列之间用逗号分隔(因此也叫“逗号分隔...

君只见独不见的专栏 8102
上一篇: 小试牛刀Matplotlib
下一篇: 《机器学习实战》chapter04 使用Python进行文本分类
君只见独不见
博客等级 码龄12年 99粉丝 162原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值