机器学习笔记4-sklearn&决策树(上)

决策树两大核心

如何划分数据集;何时停止划分数据集

一、决策树构造

特征选择,决策树生成,决策树修剪

决策树简介

决策树由结点(node)和有向边(directed edged)组成。结点有两种类型:内部结点(internal node)和叶结点(lead node)。内部结点表示一个特征或属性,叶结点表示一个类。如下图,长方形和椭圆都是结点,其中,长方形结点属于内部结点,代表判断模块(decision block),椭圆形属于叶结点,代表终止模块(terminating block)。
在这里插入图片描述

构建决策树的一般流程

  • 收集数据:可以使用任何方法
  • 准备数据:树构造算法只适合标称型数据,因此数值型数据必须离散化。 将这些所有收集的信息按照一定规则整理出来,并进行排版。
  • 分析数据:可以使用任何方法,构造树完成之后,检查图形是否符合预期。
  • 训练算法:决策树学习,构造一个决策树。
  • 测试算法:使用经验树计算错误率。
  • 使用算法:使用决策树可以更好的理解数据的内在含义。

香农熵

信息量

信息量是对信息的度量,就跟时间的度量是秒一样,当我们观察到的这个变量的一个具体值的时候,我们接受到了多少信息呢?多少信息用信息量来衡量,我们接受到的信息量跟具体发生的时间有关。
信息的大小跟随机事件的概率有关。越小概率的实践发生了产生的信息量越大,越大概率的事件发生了产生的信息量越小,如太阳从东边升起来,没什么信息量。
特征一:
一个具体事件的信息量应该是随着其发生概率而递减的,且不能为负
特征二:
如果我们有两个不相关的事件 x x x y y y,那么我们观察到的两个事件同时发生的信息应该等于观察到的事件各自发生时获得的信息之和。
h ( x , y ) = h ( x ) + h ( y ) h(x,y)=h(x)+h(y) h(x,y)=h(x)+h(y)由于x,y是两个不相关的事件,则满足:
p ( x , y ) = p ( x ) ∗ p ( y ) p(x,y)=p(x)*p(y) p(x,y)=p(x)p(y)根据上面推导,我们很容易看出 h ( x ) h(x) h(x)一定与 p ( x ) p(x) p(x)的对数有关,因为只有对数形式的真数相乘之后,对应对数才能是相加形式 h ( x ) = − log ⁡ 2 p ( x ) h(x)=-\log_2{p(x)} h(x)=log2p(x)其中,负号是为了确保信息一定是正数或者是0,不能是负数;底数可以是任意值,2对应的值是比特。

信息熵

定义一:
信息量度量的是一个具体事件发生所带来的信息,而信息熵是在结果出来之前对可能产生的信息量的期望——考虑该随机变量的所有可能取值,即所有可能发生事件所带来的信息量的期望。
定义二:
信息熵作为一个系统复杂程度的度量,如果系统越复杂,出现的不同情况种类越多,不确定性越大,那么其信息熵较大。(系统越复杂,系统事件越多,里面单一事件p出现的概率越低,此时(事件p概率*信息量)即( p log ⁡ 2 1 / p p\log_2{1/p} plog21/p)概率越大) 如果一个系统简单,出现不同情况种类很少,此时信息熵较小,极端情况为一种时,对应概率为1,则其信息熵为0。
H ( x ) = − ∑ i = 1 n p ( x i ) log ⁡ p ( x i ) H(x)=-\sum_{i=1}^n{p(x_i)\log{p(x_i)}} H(x)=i=1np(xi)logp(xi)

经验熵(香农熵)

当熵中的概率由数据估计(特别是极大似然估计)得到时,所对应的熵称为经验熵(empirical entropy)。定义训练数据集D,则训练数据集D的经验熵为H(D),|D|表示其样本容量,及样本个数。设有K个类 C k C_k Ck ∣ C k ∣ |C_k| Ck为属于类 C k C_k Ck的样本个数,则经验熵公式可以写为:
H ( D ) = − ∑ k = 1 K ∣ c k ∣ ∣ D ∣ log ⁡ 2 C k ∣ D ∣ H(D)=-\sum_{k=1}^K{\frac{|c_k|}{|D|}\log_2{\frac{C_k}{|D|}}} H(D)=k=1KDcklog2DCk例如,分析贷款申请样本数据表中的数据,分类结果只有两类,即放贷和不放贷。根据表中的数据统计可知,在15个数据中,9个数据的结果为放贷,6个数据的结果为不放贷,则数据集D的经验熵为:
H ( D ) = − 9 15 log ⁡ 2 9 15 − 6 15 log ⁡ 2 6 15 = 0.971 H(D)= -{9 \over 15}\log_2{9\over15}-{6\over15}\log_2{6\over15}=0.971 H(D)=159log2159156log2156=0.971

#!/user/bin/env python
# -*- coding:utf-8 -*-
#@Time  : 2020/3/1 19:43
#@Author: fangyuan
#@File  : 决策树香农熵.py

from math import log

def createDataSet():
    # 数据集
    dataSet = [[0,0,0,0,'no'],
               [0, 0, 0, 1, 'no'],
               [0, 1, 0, 1, 'yes'],
               [0, 1, 1, 0, 'yes'],
               [0, 0, 0, 0, 'no'],
               [1, 0, 0, 0, 'no'],
               [1, 0, 0, 1, 'no'],
               [1, 1, 1, 1, 'yes'],
               [1, 0, 1, 2, 'yes'],
               [1, 0, 1, 2, 'yes'],
               [2, 0, 1, 2, 'yes'],
               [2, 0, 1, 1, 'yes'],
               [2, 1, 0, 1, 'yes'],
               [2, 1, 0, 2, 'yes'],
               [2, 0, 0, 0, 'no']
    ]
    # 分类属性
    labels = ['年龄','有工作','有自己的房子','信贷情况']
    # 返回数据集和分类属性
    return dataSet,labels

def calcShannonEnt(dataSet):
    # 返回数据集行数
    numEntries = len(dataSet)
    # 保存每个Label出现次数的字典
    labelCounts = {}
    # 对每组特征向量进行统计
    for featVec in dataSet:
        # 提取标签Label信息
        currentLabel = featVec[-1]
        # 如果标签Label没有放入统计次数的字典,添加进去
        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel] = 0
        # Label计数
        labelCounts[currentLabel] +=1
    # 经验熵(香农熵)
    shannonEnt = 0.0
    # 计算香农熵
    for key in labelCounts:
        # 选择该标签Label的概率
        prob = float(labelCounts[key])/numEntries
        # 利用公式计算
        shannonEnt -= prob*log(prob,2)
    # 返回香农熵
    return shannonEnt

if __name__ == '__main__':
    dataSet,features = createDataSet()
    print(dataSet)
    print(calcShannonEnt(dataSet))
信息增益

  解决两大核心问题其一,如何划分数据集。一次划分数据集对应的熵减去下次划分数据集对应的熵之差称为信息增益。信息增益是相对于特征而言的,信息增益越大,特征对最终的分类结果影响也就越大,我们应该选择对最终分类结果影响最大的那个特征作为我们的分类特征。
  通俗理解,信息熵越大越混乱,比如给一个女孩子介绍对象,小姑娘一听要去相亲见面,心里面怦怦直跳,非常混乱,也不知道这个男孩子怎么样。然后给她引入3个特征,比如说身高180,头发黑色,身体健全,很显然身高180对女孩子最有吸引力,其他两个特征是所有相亲者必备的没有吸引力。加入这个特征后,女孩子心里会更加平静,即maximum(信息熵)=怦怦直跳复杂度-(身高180)更加平静复杂度>怦怦直跳复杂度-(黑色头发)更加平静复杂度. 所以说,信息增益就是引入新特征添加约束后,与之前信息熵的差值。
在这里插入图片描述在这里插入图片描述

条件熵

条件熵H(Y|X)表示在已知随机变量X的条件下随机变量Y的不确定性,随机变量X给定的条件下随机变量Y的条件熵(conditional entropy)H(Y|X),定义X给定条件下Y的条件概率分布的熵对X的数学期望: H ( Y ∣ X ) = ∑ i = 1 n p i H ( Y ∣ X = x i ) H(Y|X)=\sum_{i=1}^n{p_iH(Y|X=x_i)} H(YX)=i=1npiH(YX=xi)这里: p i = P ( X = x i ) , i = 1 , 2 , . . . , n p_i=P(X=x_i),i=1,2,...,n pi=P(X=xi),i=1,2,...,n

同理,当条件熵中的概率由数据估计(特别是极大似然估计)得到时,所对应的条件熵成为条件经验熵(empirical conditional entropy)。
前面提到,信息增益是相对于特征而言的。所以,特征A对于训练数据集D的信息增益g(D,A),定义为集合D的经验熵H(D)与特征A给定条件下D的经验条件熵H(D|A)之差,即 g ( D , A ) = H ( D ) − H ( D ∣ A ) g(D,A)=H(D)-H(D|A) g(D,A)=H(D)H(DA)一般地,熵H(D)与条件熵H(D|A)之差成为互信息(mutual information)。决策树学习中的信息增益等价于训练数据集中类与特征的互信息。
根据特征A的取值将D划分为n个子集 D 1 , D 2 , . . . , D N , ∣ D i ∣ D_1,D_2,...,D_N,|D_i| D1,D2,...,DN,Di D i D_i Di的样本个数。子集 D i D_i Di中属于 C k C_k Ck的样本集合为 D i k D_ik Dik ∣ D i k ∣ |D_ik| Dik为其样本个数。 H ( D ∣ A ) = ∑ i = 1 n ∣ D i ∣ ∣ D ∣ H ( D i ) = − ∑ i = 1 n ∣ D i ∣ ∣ D ∣ ∑ k = 1 K ∣ D i k ∣ ∣ D ∣ log ⁡ 2 ∣ D i k ∣ ∣ D ∣ H(D|A)=\sum_{i=1}^n{{|D_i| \over |D|}H(D_i)}=-\sum_{i=1}^n{{|D_i| \over |D|}}\sum_{k=1}^K{{|D_{ik}| \over |D|}}\log_2{|D_{ik}| \over |D|} H(DA)=i=1nDDiH(Di)=i=1nDDik=1KDDiklog2DDik

例如, 以贷款申请样本数据表为例进行说明。看下年龄这一列的数据,也就是特征A1,一共有三个类别,分别是:青年、中年和老年。我们只看年龄是青年的数据,年龄是青年的数据一共有5个,所以年龄是青年的数据在训练数据集出现的概率是十五分之五,也就是三分之一。同理,年龄是中年和老年的数据在训练数据集出现的概率也都是三分之一。现在我们只看年龄是青年的数据的最终得到贷款的概率为五分之二,因为在五个数据中,只有两个数据显示拿到了最终的贷款,同理,年龄是中年和老年的数据最终得到贷款的概率分别为五分之三、五分之四。所以计算年龄的信息增益,过程如下:
g ( D , A 1 ) = H ( D ) − [ 5 15 H ( D 1 ) + 5 15 H ( D 2 ) + 5 15 H ( D 3 ) ] = 0.971 − g(D,A_1)=H(D)-[{5\over15}H(D_1)+{5\over15}H(D_2)+{5\over15}H(D_3)] =0.971- g(D,A1)=H(D)[155H(D1)+155H(D2)+155H(D3)]=0.971 [ 5 15 ( − 2 5 log ⁡ 2 2 5 − 3 5 log ⁡ 2 3 5 ) + 5 15 ( − 3 5 log ⁡ 2 3 5 − 2 5 log ⁡ 2 2 5 ) + [{5\over15}({- {2\over5}}\log_2{{2\over5}}{- {3\over5}}\log_2{{3\over5}})+ {5\over15}({- {3\over5}}\log_2{{3\over5}}{- {2\over5}}\log_2{{2\over5}})+ [155(52log25253log253)+155(53log25352log252)+ 5 15 ( − 4 5 log ⁡ 2 4 5 − 1 5 log ⁡ 2 1 5 ) ] = 0.971 − 0.888 = 0.083 {5\over15}({- {4\over5}}\log_2{{4\over5}}{- {1\over5}}\log_2{{1\over5}})] =0.971-0.888=0.083 155(54log25451log251)]=0.9710.888=0.083 g ( D , A 2 ) = H ( D ) − [ 5 15 H ( D 1 ) + 10 15 H ( D 2 ) ] = 0.971 − [ 5 15 ∗ 0 + g(D,A_2)=H(D)-[{5\over15}H(D_1)+{10\over15}H(D_2)]=0.971- [{5\over15}*0+ g(D,A2)=H(D)[155H(D1)+1510H(D2)]=0.971[1550+ 10 15 ( − 4 10 log ⁡ 2 4 10 − 6 10 log ⁡ 2 6 10 ) = 0.971 − 0.647 = 0.324 {10\over15}({- {4\over10}}\log_2{{4\over10}}{- {6\over10}}\log_2{{6\over10}})=0.971-0.647=0.324 1510(104log2104106log2106)=0.9710.647=0.324

g ( D , A 3 ) = H ( D ) − [ 6 15 H ( D 1 ) + 9 15 H ( D 2 ) ] = 0.971 − [ 6 15 ∗ 0 + g(D,A_3)=H(D)-[{6\over15}H(D_1)+{9\over15}H(D_2)]=0.971- [{6\over15}*0+ g(D,A3)=H(D)[156H(D1)+159H(D2)]=0.971[1560+ 9 15 ( − 3 9 log ⁡ 2 3 9 − 6 9 log ⁡ 2 6 9 ) = 0.971 − 0.551 = 0.420 {9\over15}({- {3\over9}}\log_2{{3\over9}}{- {6\over9}}\log_2{{6\over9}})=0.971-0.551=0.420 159(93log29396log296)=0.9710.551=0.420 g ( D , A 2 ) = 0.971 − 0.608 = 0.363 \begin{aligned}g(D,A_2)=0.971-0.608=0.363\end{aligned} g(D,A2)=0.9710.608=0.363综上,特征 A 3 A_3 A3的信息增益最大,所以其为最优特征

引用链接1
引用链接2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。在编写C程序时,需要注意变量的声明和定义、指针的使用、内存的分配与释放等问题。C语言中常用的数据结构包括: 1. 数组:一种存储同类型数据的结构,可以进行索引访问和修改。 2. 链表:一种存储不同类型数据的结构,每个节点包含数据和指向下一个节点的指针。 3. 栈:一种后进先出(LIFO)的数据结构,可以通过压入(push)和弹出(pop)操作进行数据的存储和取出。 4. 队列:一种先进先出(FIFO)的数据结构,可以通过入队(enqueue)和出队(dequeue)操作进行数据的存储和取出。 5. 树:一种存储具有父子关系的数据结构,可以通过中序遍历、前序遍历和后序遍历等方式进行数据的访问和修改。 6. 图:一种存储具有节点和边关系的数据结构,可以通过广度优先搜索、深度优先搜索等方式进行数据的访问和修改。 这些数据结构在C语言中都有相应的实现方式,可以应用于各种不同的场景。C语言中的各种数据结构都有其优缺点,下面列举一些常见的数据结构的优缺点: 数组: 优点:访问和修改元素的速度非常快,适用于需要频繁读取和修改数据的场合。 缺点:数组的长度是固定的,不适合存储大小不固定的动态数据,另外数组在内存中是连续分配的,当数组较大时可能会导致内存碎片化。 链表: 优点:可以方便地插入和删除元素,适用于需要频繁插入和删除数据的场合。 缺点:访问和修改元素的速度相对较慢,因为需要遍历链表找到指定的节点。 栈: 优点:后进先出(LIFO)的特性使得栈在处理递归和括号匹配等问题时非常方便。 缺点:栈的空间有限,当数据量较大时可能会导致栈溢出。 队列: 优点:先进先出(FIFO)的特性使得
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言中,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言中常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言中常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言中用于封装代码的单元,可以实现代码的复用和模块化。C语言中定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言中用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言中定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言中用于存储同类型数据的结构,可以通过索引访问和修改数组中的元素。字符串是C语言中用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言中用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言中通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值