5.10 决策树与ID3算法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5.10 决策树与ID3算法相关的知识,希望对你有一定的参考价值。

参考技术A https://blog.csdn.net/dorisi_h_n_q/article/details/82787295

决策树(decision tree)是一个树结构(可以是二叉树或非二叉树)。决策过程是从根节点开始,测试待分类项中相应的特征属性,并按照其值选择输出分支,直到到达叶子节点,将叶子节点存放的类别作为决策结果。

决策树的关键步骤是分裂属性。就是在某节点处按某一特征属性的不同划分构造不同的分支,目标是让各个分裂子集尽可能地“纯”。即让一个分裂子集中待分类项属于同一类别。

简而言之,决策树的划分原则就是:将无序的数据变得更加有序

分裂属性分为三种不同的情况 :

构造决策树的关键性内容是进行属性选择度量,属性选择度量(找一种计算方式来衡量怎么划分更划算)是一种选择分裂准则,它决定了拓扑结构及分裂点split_point的选择。

属性选择度量算法有很多,一般使用自顶向下递归分治法,并采用不回溯的贪心策略。这里介绍常用的ID3算法。

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,所做出的是在某种意义上的局部最优解。

此概念最早起源于物理学,是用来度量一个热力学系统的无序程度。
而在信息学里面,熵是对不确定性的度量。
在1948年,香农引入了信息熵,将其定义为离散随机事件出现的概率,一个系统越是有序,信息熵就越低,反之一个系统越是混乱,它的信息熵就越高。所以信息熵可以被认为是系统有序化程度的一个度量。

熵定义为信息的期望值,在明晰这个概念之前,我们必须知道信息的定义。如果待分类的事务可能划分在多个分类之中,则符号x的信息定义为:

在划分数据集之前之后信息发生的变化称为信息增益。
知道如何计算信息增益,就可计算每个特征值划分数据集获得的信息增益,获得信息增益最高的特征就是最好的选择。

条件熵 表示在已知随机变量的条件下随机变量的不确定性,随机变量X给定的条件下随机变量Y的条
件熵(conditional entropy) ,定义X给定条件下Y的条件概率分布的熵对X的数学期望:

根据上面公式,我们假设将训练集D按属性A进行划分,则A对D划分的期望信息为

则信息增益为如下两者的差值

ID3算法就是在每次需要分裂时,计算每个属性的增益率,然后选择增益率最大的属性进行分裂

步骤:1. 对当前样本集合,计算所有属性的信息增益;

是最原始的决策树分类算法,基本流程是,从一棵空数出发,不断的从决策表选取属性加入数的生长过程中,直到决策树可以满足分类要求为止。CLS算法存在的主要问题是在新增属性选取时有很大的随机性。ID3算法是对CLS算法的改进,主要是摒弃了属性选择的随机性。

基于ID3算法的改进,主要包括:使用信息增益比替换了信息增益下降度作为属性选择的标准;在决策树构造的同时进行剪枝操作;避免了树的过度拟合情况;可以对不完整属性和连续型数据进行处理;使用k交叉验证降低了计算复杂度;针对数据构成形式,提升了算法的普适性。

信息增益值的大小相对于训练数据集而言的,并没有绝对意义,在分类问题困难时,也就是说在训练数据集经验熵大的时候,信息增益值会偏大,反之信息增益值会偏小,使用信息增益比可以对这个问题进行校正,这是特征选择
的另一个标准。
特征对训练数据集的信息增益比定义为其信息增益gR( D,A) 与训练数据集的经验熵g(D,A)之比 :

gR(D,A) = g(D,A) / H(D)

sklearn的决策树模型就是一个CART树。是一种二分递归分割技术,把当前样本划分为两个子样本,使得生成的每个非叶子节点都有两个分支,因此,CART算法生成的决策树是结构简洁的二叉树。
分类回归树算法(Classification and Regression Trees,简称CART算法)是一种基于二分递归分割技术的算法。该算法是将当前的样本集,分为两个样本子集,这样做就使得每一个非叶子节点最多只有两个分支。因此,使用CART
算法所建立的决策树是一棵二叉树,树的结构简单,与其它决策树算法相比,由该算法生成的决策树模型分类规则较少。

CART分类算法的基本思想是:对训练样本集进行递归划分自变量空间,并依次建立决策树模型,然后采用验证数据的方法进行树枝修剪,从而得到一颗符合要求的决策树分类模型。

CART分类算法和C4.5算法一样既可以处理离散型数据,也可以处理连续型数据。CART分类算法是根据基尼(gini)系
数来选择测试属性,gini系数的值越小,划分效果越好。设样本集合为T,则T的gini系数值可由下式计算:

CART算法优点:除了具有一般决策树的高准确性、高效性、模式简单等特点外,还具有一些自身的特点。
如,CART算法对目标变量和预测变量在概率分布上没有要求,这样就避免了因目标变量与预测变量概率分布的不同造成的结果;CART算法能够处理空缺值,这样就避免了因空缺值造成的偏差;CART算法能够处理孤立的叶子结点,这样可以避免因为数据集中与其它数据集具有不同的属性的数据对进一步分支产生影响;CART算法使用的是二元分支,能够充分地运用数据集中的全部数据,进而发现全部树的结构;比其它模型更容易理解,从模型中得到的规则能获得非常直观的解释。

CART算法缺点:CART算法是一种大容量样本集挖掘算法,当样本集比较小时不够稳定;要求被选择的属性只能产生两个子结点,当类别过多时,错误可能增加得比较快。

sklearn.tree.DecisionTreeClassifier

1.安装graphviz.msi , 一路next即可

ID3算法就是在每次需要分裂时,计算每个属性的增益率,然后选择增益率最大的属性进行分裂

按照好友密度划分的信息增益:

按照是否使用真实头像H划分的信息增益

**所以,按先按好友密度划分的信息增益比按真实头像划分的大。应先按好友密度划分。

考研数据结构与算法树与二叉树

考研数据结构与算法(六)树与二叉树

文章目录

一、树的概念和基础术语

1.1 定义

树是 n ( n > = 0 ) n ( n >= 0 ) n(n>=0) 个节点的有限集。当 n = 0 n = 0 n=0 时,称为空树。 在任意-非空树中应满足:

  • ①有且仅有一个特定的称为根的结点
  • ②当 n > 1 n > 1 n>1 时, 其余节点可分为 m ( m > 0 ) m (m > 0) m(m>0)个互不相交的 有限集 T 1 , T 2 , T 3 … … , T m T_1,T_2,T_3……,T_m T1,T2,T3……,Tm , 其中每个集合本身又是一颗树,并且称为根的子树

显然,树的定义是递归的,即在树的定义中又用到了其自身,树是一种递归的数据结构。 树作为一种逻辑结构,同时也是一种分层结构,具有以下两个特点:

  • 树的根结点没有前驱, 除根结点外的所有结点有且只有一个前驱
  • 树中所有结点可以有零个或多个后继

从这个结构上来看的话,树是一个层级的结构,对于每一个非根节点而言,和上层只有一个结点关联,我们称这个上层结点为父节点 ,又由于根节点没有上层结点,那么我们会发现在 n n n 个结点的树有且仅有 n − 1 n-1 n1 条边

1.2 基础术语

对于一颗这样的树而言:

  • 考虑结点 K K K 。根 A A A 到结点 K K K 的唯一路径上的任意结点,称为结点 K K K祖先。 如结点 B B B 是 结点 K K K 的祖先,而结点 K K K 是结点 B B B 的子孙。路径上最接近结点 K K K 的结点 E E E 称为 K K K 的双亲, 而 K K K 为结点 E E E 的孩子。根 A A A 是树中唯一没有双亲的结点。有相同双亲的结点称为兄弟,如结点 K K K 和结点 L L L 有相同的双亲 E E E , 即 K K K L L L 为兄弟。
  • 树中一个结点的孩子个数称为该结点的度, 树中结点的最大度数称为树的度。 如结点 B B B 的 度为 2 2 2 ,结点 D D D 的度为 3 3 3 ,树的度为 3 3 3
  • 度大于 0 0 0 的结点称为 分支结点(又称非终端结点); 度为 0 0 0 (没有子女结点)的结点称为 叶子结点(又称终端结点)。
  • 结点的深度是从根结点开始自顶向下逐层累加的,结点的高度是从叶结点开始自底向上逐层累加的。树的高度(或深度)是树中结点的最大层数。 上图中树的高度为 4 4 4
  • 有序树和无序树。树中结点的各子树从左到右是有次序的,不能互换,称该树为有序树,否则称为无序树 。
  • 路径和路径长度。 树中两个结点之间的路径是由这两个结点之间所经过的结点序列构成 ,而路径长度是路径上所经过的边的个数。(注意:由于树中的分支是有向的,即从1又亲指向孩子,所以树中的路径是从上向下的, 同一双亲的两个孩子之间不存在路径)
  • 森林是 m ( m > = 0 ) m (m>=0) m(m>=0)互不相交的树的集合。 森林的概念与树的概念十分相近,因为只要把树的根结点删去就成了森林。

1.3 树的性质

  • 树中的结点数等于所有结点的度数加一
  • 度为 m m m 的树中第 i i i 层上至多有 m i − 1 m^i-1 mi1 个结点 ( i > = 1 ) (i>=1) (i>=1)
  • 高度为 h h h m m m 叉树至多有 ( m h − 1 ) / ( m 一 1 ) (m^h - 1 )/(m 一 1) (mh1)/(m1)个结点。
  • 具有 n n n 个结点的 m m m 叉树的最小高度为 ⌈ l o g m ( n ( m − 1 ) + 1 ) ⌉ \\left \\lceil log_m(n(m-1)+1) \\right \\rceil logm(n(m1)+1)

小结:这一部分的考点应该会着重于围绕树的性质,比如第一条,给你某些度的结点数和总结点数,问你叶子节点的个数,类似,以及围绕其他性质可以衍生处更多问题

二、二叉树

2.1 二叉树定义

每一个结点至多只有两棵子树(即度小于等于 2 2 2 ),并且二叉树是一颗有序树,其子树有左右之分 ,同样的,节点数为 0 0 0 的树为空树

二叉树的基本五种形态如下:

这里需要注意二叉树和度为 2 2 2 的树的区别:

  • ①度为 2 2 2 的树至少有 3 3 3 个结点,而二叉树可以为空
  • ②度为 2 2 2 的树没有左右次序的区分,而二叉树是一颗有序树有左右子树的区分

2.2 二叉树性质

在提性质前,先介绍两种特殊的二叉树:

2.2.1 满二叉树

简单理解一下,对于每一层的结点都塞满的树就是二叉树,比如说下图的就是高度为 2 、 3 2、3 23 的满二叉树

不难发现一个点,一颗深度为 k k k 且有 2 k − 1 2^k - 1 2k1 个结点的二叉树为满二叉树

2.2.2 完全二叉树

对于一颗高度为 k   ( k > 1 ) k \\ (k>1) k (k>1) 的二叉树其 k − 1 k-1 k1 层是一颗满二叉树,并且第 k k k 层是按照从左到右依次插入的结点就为完全二叉树,很显然一颗满二叉树也是一颗完全二叉树,而一颗完全二叉树不一定是满二叉树,我们看几个完全二叉树的例子:

2.2.3 二叉排序树

递归定义:

  • 左子树上所有结点的关键字均小于根结点的关键字;
  • 右子树上的所有结点的关键宇均大于根结点的关键宇;
  • 左子树和右子树又各是一棵二叉排序树。

2.2.4 平衡二叉树

树上任一结点的左子树和右子树的深度之差不超过 1 1 1 的二叉树即为平衡二叉树

2.2.5 性质

  • 非空二叉树上的叶子结点数等于度为 2 2 2 的结点数加 1 1 1, 即 n 0 = n 2 + 1 n_0 = n_2 + 1 n0=n2+1
  • 非空二叉树上第 k k k 层上至多有 2 k − 1 2^k-1 2k1 个结点
  • 高度为 h h h 的二叉树至多有 2 n − 1 2^n - 1 2n1 个结点
  • 对于完全二叉树而言,如果根节点是从 1 1 1 开始计算的话,我们能得到一个有用的信息,即如果通过顺序存储二叉树,那么对于某一个分支节点假设为第 k k k 个元素,那么其左儿子结点位置为: 2 k 2k 2k 其右儿子结点位置为: 2 k + 1 2k+1 2k+1

2.3 二叉树存储结构

2.3.1 顺序存储

通过一组连续的地址进行存储每个结点(就是数组存储),我们按照从上到下,从左到右的次序依次将对应的结点放在对应的位置,显然根节点放在第一个位置(假设从 1 1 1 开始计算),那么他的左儿子就是第二个位置,右儿子就是第三个位置,那么是一颗完全二叉树的话,就可以直接使用顺序存储,通过结点的位置我们也能很快的定位到

2.3.2 链式存储

因为树的结构不确定,不一定会是完全二叉树那样,所以使用顺序存储可能会造成大量的空间浪费,比如最极端的情况就是二叉树退化成链,那么这个时候,每增加一层,都会浪费 2 i − 1 2^i - 1 2i1 个空间,于是为了提高空间利用率,我们还可以通过链式存储二叉树的每个结点,对于每新增一个结点我们只需要申请对于的空间,然后将他的父结点指向它即可。

很显然就能得到这个链式的结点形式:

struct Node 
    ElemType data;
    struct Node *lchild,*rchild;
;

2.4 遍历二叉树

对于一个二叉树而言,是由三个部分组成:根结点( N N N ),左子树( L L L ),右子树( R R R ),那么我们对这三部分的访问顺序进行变化就得到了最基础的三种序列访问方式,即先序遍历( N L R NLR NLR ),中序遍历( L N R LNR LNR ),后序遍历( L R N LRN LRN

2.4.1 先序遍历

字面意思,遍历方式:

  1. 遍历根节点
  2. 遍历左子树
  3. 遍历右子树

不难得出递归代码:

void PreOrder(Node *root) 
    if(root) 
        visit(root);//访问根节点
        PreOrder(root->lchild);//访问左子树
        PreOrder(root->rchild);//访问右子树
    

2.4.2 中序遍历

字面意思,遍历方式:

  1. 遍历左子树
  2. 遍历根节点
  3. 遍历右子树

不难得出递归代码:

void InOrder(Node *root) 
    if(root) 
        InOrder(root->lchild);//访问左子树
        visit(root);//访问根节点
        InOrder(root->rchild);//访问右子树
    

2.4.3 后序遍历

字面意思,遍历方式:

  1. 遍历左子树
  2. 遍历右子树
  3. 遍历根节点

不难得出递归代码:

void PostOrder(Node *root) 
    if(root) 
        PostOrder(root->lchild);//访问左子树
        PostOrder(root->rchild);//访问右子树
        visit(root);//访问根节点
    

2.4.4 递归转非递归

假设有这样的一颗二叉树:

递归其实也就是利用了栈,我们分析用栈模拟的中序遍历的过程:

  • ①沿着根的左孩子,依次入栈,直到左孩子为空,说明己找到可以输出的结点,此时栈内元素依次为 A 、 B 、 D A、B、D ABD
  • ②栈顶元索出栈并访问:若其右孩子为空,继续执行操作②,若其右孩子不空,将右子树转执行操作①

以上面的二叉树为例,我们可以得到栈的空间使用过程如下:

操作次序栈内空间下一步进行的操作
1NULL
2 A A A
3 A 、 B A、B AB
4 A 、 B 、 D A、B、D ABD
5

以上是关于5.10 决策树与ID3算法的主要内容,如果未能解决你的问题,请参考以下文章

深度学习之决策树与迭代决策树(GBDT)

决策树与随机森林

决策树与随机森林

决策树学习

决策树算法 CART和C4.5决策树有啥区别?各用于啥领域?

决策树与随机森林算法

(c)2006-2024 SYSTEM All Rights Reserved IT常识