3 决策树及Python实现

news2024/9/30 11:35:06

1 主要思想

1.1 数据

在这里插入图片描述

1.2 训练和使用模型

训练:建立模型(树)
测试:使用模型(树)
在这里插入图片描述
Weka演示ID3(终端用户模式)

  • 双击weka.jar
  • 选择Explorer
  • 载入weather.arff
  • 选择trees–>ID3
  • 构建树,观察结果

建立决策树流程

  • Step 1. 选择一个属性
  • Step 2. 将数据集分成若干子集
  • Step 3.1 对于决策属性值唯一的子集, 构建叶结点
  • Step 3.2 对于决策属性值不唯一的子集, 递归调用本函数

演示: 利用txt文件, 按照决策树的属性划分数据集

2 信息熵

问题: 使用哪个属性进行数据的划分?
随机变量 Y Y Y的信息熵为 ( Y Y Y为决策变量):
H ( Y ) = E [ I ( y i ) ] = ∑ i = 1 n p ( y i ) log ⁡ 1 p ( y i ) = − ∑ i = 1 n p ( y i ) log ⁡ p ( y i ) , H(Y) = E[I(y_i)] = \sum_{i=1}^n p(y_i)\log \frac{1}{p(y_i)} = - \sum_{i=1}^n p(y_i)\log p(y_i), H(Y)=E[I(yi)]=i=1np(yi)logp(yi)1=i=1np(yi)logp(yi),
其中 0 log ⁡ 0 = 0 0 \log 0 = 0 0log0=0.
随机变量 Y Y Y关于 X X X的条件信息熵为( X X X为条件变量):
H ( Y ∣ X ) = ∑ i = 1 m p ( x i ) H ( Y ∣ X = x i ) = − ∑ i , j p ( x i , y j ) log ⁡ p ( y j ∣ x i ) . \begin{array}{ll} H(Y | X) & = \sum_{i=1}^m p(x_i) H(Y | X = x_i)\\ & = - \sum_{i, j} p(x_i, y_j) \log p(y_j | x_i). \end{array} H(YX)=i=1mp(xi)H(YX=xi)=i,jp(xi,yj)logp(yjxi).
X X X Y Y Y带来的信息增益: H ( Y ) − H ( Y ∣ X ) H(Y) - H(Y | X) H(Y)H(YX).

3 程序分析

版本1. 使用sklearn (调包侠)
这里使用了数据集是数值型。

import numpy as np
import scipy as sp
import time, sklearn, math
from sklearn.model_selection import train_test_split
import sklearn.datasets, sklearn.neighbors, sklearn.tree, sklearn.metrics

def sklearnDecisionTreeTest():
    #Step 1. Load the dataset
    tempDataset = sklearn.datasets.load_breast_cancer()
    x = tempDataset.data
    y = tempDataset.target

    # Split for training and testing
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2)

    #Step 2. Build classifier
    tempClassifier = sklearn.tree.DecisionTreeClassifier(criterion='entropy')
    tempClassifier.fit(x_train, y_train)

    #Step 3. Test
    #precision, recall, thresholds = sklearn.metrics.precision_recall_curve(y_test, tempClassifier.predict(x_test))
    tempAccuracy = sklearn.metrics.accuracy_score(y_test, tempClassifier.predict(x_test))
    tempRecall = sklearn.metrics.recall_score(y_test, tempClassifier.predict(x_test))
    
    #Step 4. Output
    print("precision = {}, recall = {}".format(tempAccuracy, tempRecall))

sklearnDecisionTreeTest()

版本2. 自己重写重要函数

  1. 信息熵
#计算给定数据集的香农熵
def calcShannonEnt(paraDataSet):
    numInstances = len(paraDataSet)
    labelCounts = {}	#定义空字典
    for featVec in paraDataSet:
        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])/numInstances
        shannonEnt -= prob * math.log(prob, 2) #以2为底
    return shannonEnt
  1. 划分数据集
#dataSet 是数据集,axis是第几个特征,value是该特征的取值。
def splitDataSet(dataSet, axis, value):
    resultDataSet = []
    for featVec in dataSet:
        if featVec[axis] == value:
            #当前属性不需要
            reducedFeatVec = featVec[:axis]
            reducedFeatVec.extend(featVec[axis+1:])
            resultDataSet.append(reducedFeatVec)
    return resultDataSet
  1. 选择最好的特征划分
#该函数是将数据集中第axis个特征的值为value的数据提取出来。
#选择最好的特征划分
def chooseBestFeatureToSplit(dataSet):
    #决策属性不算
    numFeatures = len(dataSet[0]) - 1
    baseEntropy = calcShannonEnt(dataSet)
    bestInfoGain = 0.0
    bestFeature = -1
    for i in range(numFeatures):
        #把第i列属性的值取出来生成一维数组
        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
  1. 构建叶节点
#如果剩下的数据中无特征,则直接按最大百分比形成叶节点
def majorityCnt(classList):
    classCount = {}
    for vote in classList:
        if vote not in classCount.keys():
            classCount[vote] = 0
        classCount += 1;
    sortedClassCount = sorted(classCount.iteritems(), key = operator.itemgette(1), reverse = True)
    return sortedClassCount[0][0]
  1. 创建决策树
#创建决策树
def createTree(dataSet, paraFeatureName):
    featureName = paraFeatureName.copy()
    classList = [example[-1] for example in dataSet]

    #Already pure
    if classList.count(classList[0]) == len(classList):
        return classList[0]

    #No more attribute
    if len(dataSet[0]) == 1:
    #if len(dataSet) == 1:
        return majorityCnt(classList)
    
    bestFeat = chooseBestFeatureToSplit(dataSet)
    #print(dataSet)
    #print("bestFeat:", bestFeat)
    bestFeatureName = featureName[bestFeat]
    myTree = {bestFeatureName:{}}
    del(featureName[bestFeat])
    featvalue = [example[bestFeat] for example in dataSet]
    uniqueVals = set(featvalue)
    for value in uniqueVals:
        subfeatureName = featureName[:]
        myTree[bestFeatureName][value] = createTree(splitDataSet(dataSet, bestFeat, value), subfeatureName)
    return myTree
  1. 分类和返回预测结果
#Classify and return the precision
def id3Classify(paraTree, paraTestingSet, featureNames, classValues):
    tempCorrect = 0.0
    tempTotal = len(paraTestingSet)
    tempPrediction = classValues[0]
    for featureVector in paraTestingSet:
        print("Instance: ", featureVector)
        tempTree = paraTree
        while True:
            for feature in featureNames:
                try:
                    tempTree[feature]
                    splitFeature = feature
                    break
                except:
                    i = 1 #Do nothing

            attributeValue = featureVector[featureNames.index(splitFeature)]
            print(splitFeature, " = ", attributeValue)

            tempPrediction = tempTree[splitFeature][attributeValue]
            if tempPrediction in classValues:
                break
            else:
                tempTree = tempPrediction
        print("Prediction = ", tempPrediction)
        if featureVector[-1] == tempPrediction:
            tempCorrect += 1

    return tempCorrect/tempTotal
  1. 构建测试代码
def mfID3Test():
    #Step 1. Load the dataset
    weatherData = [['Sunny','Hot','High','FALSE','N'],
        ['Sunny','Hot','High','TRUE','N'],
        ['Overcast','Hot','High','FALSE','P'],
        ['Rain','Mild','High','FALSE','P'],
        ['Rain','Cool','Normal','FALSE','P'],
        ['Rain','Cool','Normal','TRUE','N'],
        ['Overcast','Cool','Normal','TRUE','P'],
        ['Sunny','Mild','High','FALSE','N'],
        ['Sunny','Cool','Normal','FALSE','P'],
        ['Rain','Mild','Normal','FALSE','P'],
        ['Sunny','Mild','Normal','TRUE','P'],
        ['Overcast','Mild','High','TRUE','P'],
        ['Overcast','Hot','Normal','FALSE','P'],
        ['Rain','Mild','High','TRUE','N']]

    featureName = ['Outlook', 'Temperature', 'Humidity', 'Windy']
    classValues = ['P', 'N']
    tempTree = createTree(weatherData, featureName)
    print(tempTree)
    #print(createTree(mydata, featureName))

    #featureName = ['Outlook', 'Temperature', 'Humidity', 'Windy']
    print("Before classification, feature names = ", featureName)
    tempAccuracy = id3Classify(tempTree, weatherData, featureName, classValues)
    print("The accuracy of ID3 classifier is {}".format(tempAccuracy))

def main():
    sklearnDecisionTreeTest()
    mfID3Test()

main()

4 讨论

符合人类思维的模型;
信息增益只是一种启发式信息;
与各个属性值“平行”的划分。

其它决策树:

  • C4.5:处理数值型数据
  • CART:使用gini指数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/375024.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

简单易懂又非常牛逼的Spring源码解析,推断构造与bean的实例化

简单易懂又非常牛逼的Spring源码解析,推断构造与bean的实例化原理解析实例化bean的入口工厂方法实例化推断构造初次筛选二次筛选bean的实例化代码走读实例化bean的入口createBeanInstance方法内部的流程推断构造初次筛选二次筛选bean的实例化总结往期文章&#xff1…

十六、vue3.0之富文本编辑器的选择

在工作过程中我们会遇到很多的时候会使用到富文本编辑器,市场上流行的也是各种各样的,那么究竟如何选择呢,今天就给大家讲讲有哪一些,方便大家的选择。 一、TinyMCE TinyMCE 是富文本编辑器领域的头部玩家之一,主流富文本编辑器,功能非常全,你需要的大多数功能它都支持…

深力科电子-MachXO3系列 LCMXO3LF-1300C-5BG256C 控制和桥接FPGA器件

深力科电子-lattice莱迪斯MachXO3系列 LCMXO3LF-1300C-5BG256C 控制和桥接FPGA器件 ,FPGA 现场可编程逻辑器件,小尺寸,高性能!在工业领域,它可以用于网络控制器,PLC,网络边缘计算,机器视觉和工业机器人&…

万字解析 Linux 中 CPU 利用率是如何算出来的?

在线上服务器观察线上服务运行状态的时候,绝大多数人都是喜欢先用 top 命令看看当前系统的整体 cpu 利用率。例如,随手拿来的一台机器,top 命令显示的利用率信息如下 这个输出结果说简单也简单,说复杂也不是那么容易就能全部搞明白…

【java web篇】使用JDBC操作数据库

📋 个人简介 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜📝 个人主页:馆主阿牛🔥🎉 支持我:点赞👍收藏⭐️留言&#x1f4d…

学习Java前,应该了解的这些知识(新手必学)

Java语言广泛应用于编写web应用程序、移动开发、安卓开发等,市场上对Java人才需求量很大,有数据显示,Java工程师的薪资待遇随着人才市场的需求逐步递增,由此可见,Java人才需求量呈现持续上升趋势,供不应求。…

LevelDB架构介绍以及读、写和压缩流程

LevelDB 基本介绍 是一个key/value存储,key值根据用户指定的comparator排序。 特性 keys 和 values 是任意的字节数组。数据按 key 值排序存储。调用者可以提供一个自定义的比较函数来重写排序顺序。提供基本的 Put(key,value),Get(key),…

企业电子招标采购源码之电子招标投标全流程!

随着各级政府部门的大力推进,以及国内互联网的建设,电子招投标已经逐渐成为国内主流的招标投标方式,但是依然有很多人对电子招投标的流程不够了解,在具体操作上存在困难。虽然各个交易平台的招标投标在线操作会略有不同&#xff0…

13-mvc框架原理与实现方式

1、mvc原理 # mvc 与框架## 1.mvc 是什么1. m:model,模型(即数据来源),主要是针对数据库操作 2. v:view,视图,html 页面。视图由一个一个模板构成(模板是视图的一个具体展现或载体,视图是模板的一个抽象) 3. c:controller,控制器,用于mv之间的数据交互## 2.最简单的 mvc 就是一…

Java+Swing+Mysql实现超市管理系统

一、系统介绍1.开发环境操作系统:Win10开发工具 :IDEA2018JDK版本:jdk1.8数据库:Mysql8.02.技术选型JavaSwingMysql3.功能模块4.系统功能1.系统登录登出管理员可以登录、退出系统2.商品信息管理管理员可以对商品信息进行查询、添加…

MapReduce小试牛刀

部署完hadoop单机版后,试下mapreduce是怎么分析处理数据的 Word Count Word Count 就是"词语统计",这是 MapReduce 工作程序中最经典的一种。它的主要任务是对一个文本文件中的词语作归纳统计,统计出每个出现过的词语一共出现的次…

【云原生kubernetes】k8s 常用调度策略使用详解

一、前言 通过之前的学习,我们了解到k8s集群中最小工作单位是pod,对于k8s集群来说,一个pod的完整生命周期是由一系列调度策略来控制,这些调度策略具体是怎么工作的呢?本文将详细讨论下这个问题。 二、k8s调度策略简介…

K8S---Pod进阶资源限制以及探针

目录 一、Pod 进阶 1、资源限制 2、Pod 和 容器 的资源请求和限制: 3、CPU 资源单位 4、内存 资源单位 5、实例操作 5.1 示例1 5.2 示例2 6、重启策略(restartPolicy) 6.1 示例1 二、健康检查:又称为探针(P…

华为OD机试题,用 Java 解【机器人走迷宫】问题

最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…

电动针阀流量控制和电气比例阀压力控制在液氮低温控制中的应用

摘要:为了解决室温至液氮温区温控系统中需要昂贵的低温电动阀门进行液氮介质流量调节的问题,本文提供了三种不同精度的液氮温区内的低温温度控制解决方案。解决方案的技术核心是通过采用电动针阀和电气比例阀在室温环境下来快速调节外部气源流量或压力大…

Nginx网站服务——编译安装、基于授权和客户端访问控制

文章目录一、Nginx概述1.1、Nginx的特点1.2、Nginx编译安装1.3、Nginx运行控制1.4、Nginx和Apache的区别二、编译安装Nginx服务的操作步骤2.1、关闭防火墙,将安装nginx所需软件包传到/opt目录下2.2、安装依赖包2.3、创建运行用户、组(Nginx 服务程序默认…

【2023全网最全教程】从0到1开发自动化测试框架(建议收藏)

一、序言 随着项目版本的快速迭代、APP测试有以下几个特点: 首先,功能点多且细,测试工作量大,容易遗漏;其次,代码模块常改动,回归测试很频繁,测试重复低效;最后&#x…

Java 多线程 --- 多线程的相关概念

Java 多线程 --- 多线程的相关概念Race Condition 问题并发编程的性质 --- 原子性, 可见性, 有序性上下文切换 (Context Switch)线程的一些故障 --- 死锁, 活锁, 饥饿死锁 (Deadlock)活锁(Livelock)死锁和活锁的区别饥饿(Starvation)背景: 操作系统 — 线程/进程 同步 Race Co…

Windows操作系统的体系结构、运行环境和运行状态

我是荔园微风,作为一名在IT界整整25年的老兵,今天我们来重新审视一下Windows这个我们熟悉的不能再熟悉的系统。说Windows操作系统的运行环境和运行状态,首先要介绍一下Windows操作系统的体系结构,然后再要说到最重要的两个概念:核…

【架构师】零基础到精通——微服务体系

博客昵称:架构师Cool 最喜欢的座右铭:一以贯之的努力,不得懈怠的人生。 作者简介:一名Coder,软件设计师/鸿蒙高级工程师认证,在备战高级架构师/系统分析师,欢迎关注小弟! 博主小留言…