机器学习--DIY笔记与感悟--②决策树(1)

在完成了K临近之后,今天我们开始下一个算法--->决策树算法。

一、决策树基础知识

如果突然问你"有一个陌生人叫X,Ta今天需要带伞吗?", 你一定会觉得这个问题就像告诉你"两千米外有一个超市,问超市里面有多少卷卫生纸"一样突兀. 可能几秒钟之后你会说"这要依情况而定, 如果今天烈日炎炎并且X是一个皮肤白皙的中国姑娘,或者外面下着大雨并且X是一个不得不去步行上班的屌丝码农, 那么Ta今天需要带伞, 否则不要."

当谈及这个看似无聊的问题的时候我们在谈什么?恩,在谈方法. 我们经常会遇到简单但又困难的抉择. 说简单,是因为候选方案简单而且清晰. 例如,要不要出国留学,要不要辞职创业,要不要投资黄金等等. 但是这些看似简单的选项背后却是困难的抉择. 面对这些困难的抉择, 一开始, 很可能不知所措. 值得庆幸的是, 很多时候, 这些看似不可能解决的问题, 最终可以被化解成一连串越来越简单的问题, 然后解决掉. 这个方法可以粗俗总结为: "如果这样这样这样, 那么选择A; 如果那样那样那样, 那么选择B", 当然这种方法有一个更加简洁形象的名字--决策树(Decision Tree)。

现在大家应该对决策树应该有了一个大致的了解。简单来说,决策树就是内心的一个决策过程,既:如果我要达成某个结果,那么我需要先怎么样,然后怎么样,满足什么样的条件balabala.....

举一个通俗的栗子,各位立志于脱单的单身男女在找对象的时候就已经完完全全使用了决策树的思想。假设一位母亲在给女儿介绍对象时,有这么一段对话:

母亲:给你介绍个对象。
女儿:年纪多大了?
母亲:26。
女儿:长的帅不帅?
母亲:挺帅的。
女儿:收入高不?
母亲:不算很高,中等情况。
女儿:是公务员不?
母亲:是,在税务局上班呢。
女儿:那好,我去见见。

画成树状图即为:

上图则为一个简单的决策树。

二、决策树理论--信息论

大家不要被高大上的信息论给吓到了,决策树算法中涉及信息论的知识很少,也就是几个概念。所以了解了对应的概念就没有问题了。

这里我准备使用一个例子来讲述相应理论。

ID 年龄 有工作 有自己的房子 信贷情况 类别(是否发放贷款)
1 青年 一般
2 青年
3 青年
4 青年 一般
5 青年 一般
6 中年 一般
7 中年
8 中年
9 中年 非常好
10 中年 非常好
11 老年 非常好
12 老年
13 老年
14 老年 非常好
15 老年 一般

上面我加载了一张数据表格。这张表格的内容为贷款申请样本数据表。也就是说这张表格中每一行的结果均为是否成功申请到贷款。而能否成功申请到贷款取决于一些神秘的力量。

神秘的力量是什么呢?这个力量与四个特征有某些神奇的关系(这个关系就是我们要找的决策树)--申请人的年龄、是否有工作、是否有房子、信贷情况。

之后我们就要使用信息论中--熵的概念来提炼出哪一个特征对结果影响更大。

这里引入熵的概念:

通常,一个信源发送出什么符号是不确定的,衡量它可以根据其出现的概率来度量。概率大,出现机会多,不确定性小;反之就大。

通俗来说,在这个例子中,计算“是否发放贷款”这个信息的熵(这里表示为H),得到的H值的大小表示为该结果的不确定性。而H的值越大,不确定性越大。

对应的计算公式为:

根据此公式计算经验熵H(D),分析贷款申请样本数据表中的数据。最终分类结果只有两类,即放贷和不放贷。根据表中的数据统计可知,在15个数据中,9个数据的结果为放贷,6个数据的结果为不放贷。所以数据集D的经验熵H(D)为:

经过计算可知,数据集D的经验熵H(D)的值为0.971。不确定度也就是为0.971Z这么大(这里不是概率)

三、编写代码计算熵

在编写代码之前,我们先对数据集进行属性标注。

  • 年龄:0代表青年,1代表中年,2代表老年;
  • 有工作:0代表否,1代表是;
  • 有自己的房子:0代表否,1代表是;
  • 信贷情况:0代表一般,1代表好,2代表非常好;
  • 类别(是否给贷款):no代表否,yes代表是。

这样上述表格就可以规范化为

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‘]]

这里放上代码:

#coding:utf-8

"""基于信息量的决策树算法(Decision Tree),计算当前数据的香农熵"""

from math import log

def createData():
    data = [[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 data,labels

def calcu_Entropy(data):
    dataCount = len(data)
#计算data的个数
    labelCounts = {}
#用来计算每个标签出现的次数
    for everVec in data:
        clac_label = everVec[-1]
#取出所需计算的标签(-1代表倒数第一列的值)
        if clac_label not in labelCounts.keys():
            labelCounts[clac_label] = 0
#.keys()函数为:返回当前字典里的键
#上述判断是为了查看当前的字典里是否有此键值,若没有将此键的值更新为0,为了方便以后计算数量
        labelCounts[clac_label] += 1
#当前的键每出现一次,键值就加1(用来计算出现的次数)
    shannonEn = 0.0
#初始化香农熵
    for i in labelCounts:
        prob = float(labelCounts[i]) / float(dataCount)
#prob为每一个键出现的概率
        shannonEn -= prob * log(prob, 2)
#计算香农熵,H = -P1 * log(2,p1) - P2 * log(2,p2)....- Pn * log(2,pn)
    return shannonEn

if __name__ == ‘__main__‘:
    data,labels = createData()
    print calcu_Entropy(data)

经过计算,得到“是否发放贷款”的香农熵为:

四、决策树理论--互信息

互信息(Mutual Information)是信息论里一种有用的信息度量,它可以简单的形容为一个随机变量由于已知另一个随机变量而减少的不肯定性。

它的公式为:

而H(D|A)为条件熵,既在已知A的前提下D的熵。而H(D) - H(D|A)则可以理解为什么都不知道的前提下求得的D的熵 - 已知A的前提下D的熵。又由于熵表示不确定程度,所以这个公式表示了不确定程度的减少,既已知A对D的不确定程度的减少量。

而条件熵的公式为:

这里放入一个链接,如果不是很明白这个概念的同学可以跳转学习下。

http://blog.csdn.net/xwd18280820053/article/details/70739368

这下是不是好理解了一些呢?对于例子来说,看下年龄这一列的数据,也就是特征A1,一共有三个类别,分别是:青年、中年和老年。

我们只看年龄是青年的数据,年龄是青年的数据一共有5个,所以年龄是青年的数据在训练数据集出现的概率是十五分之五,也就是三分之一。

同理,年龄是中年和老年的数据在训练数据集出现的概率也都是三分之一。

现在我们只看年龄是青年的数据的最终得到贷款的概率为五分之二,因为在五个数据中,只有两个数据显示拿到了最终的贷款,同理,年龄是中年和老年的数据最终得到贷款的概率分别为五分之三、五分之四。所以计算年龄的信息增益,过程如下:

同理,计算其余特征的信息增益g(D,A2)、g(D,A3)和g(D,A4)。分别为:

得到A3的互信息最大,既在知道A3的条件下对我们得到结果最有帮助(减少可能性最大)。

五、计算互信息量的代码

这里仍然使用了python 2.7.10版本。

from math import log

def createData():
    data = [[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 data,labels

def calcu_Entropy(data):
    dataCount = len(data)
#计算data的个数
    labelCounts = {}
#用来计算每个标签出现的次数
    for everVec in data:
        clac_label = everVec[-1]
#取出所需计算的标签
        if clac_label not in labelCounts.keys():
            labelCounts[clac_label] = 0
#.keys()函数为:返回当前字典里的键
#上述判断是为了查看当前的字典里是否有此键值,若没有将此键的值更新为0,为了方便以后计算数量
        labelCounts[clac_label] += 1
#当前的键每出现一次,键值就加1(用来计算出现的次数)
    shannonEn = 0.0
#初始化香农熵
    for i in labelCounts:
        prob = float(labelCounts[i]) / float(dataCount)
#prob为每一个键出现的概率
        shannonEn -= prob * log(prob, 2)
#计算香农熵,H = -P1 * log(2,p1) - P2 * log(2,p2)....- Pn * log(2,pn)
    return shannonEn

def choose_column_in_data(data,column,value):
#该函数意义为选择当前数据集中以某一列(例如选择年龄、或者选择是否有房子等)作为依据的数据集合
#其中data是所有数据集,column是所选择列的编号,value为所需要选定的值(例如我需要年龄为青年的人,那么value就为:青年)
    dataConsequence = []
    for everVec in data:
        if everVec[column] == value:
#对每一条数据进行处理,若该数据对应位置的值为value,则进行下一步
            mid = everVec[:column]
            mid.extend(everVec[column+1:])
            dataConsequence.append(mid)
    return dataConsequence

def Choose_Best_Mutua_Information(data):
#此函数含义为选择当前数据中使熵增最大的特征
    bestFeature = -1
#预设最优解
    bestFeatureValue = -1000.0
#预设最大增益
    Featurenum = len(data[0]) - 1
#提取单个数据的特征数量
    baseEntropy = calcu_Entropy(data)
#计算总的熵
    for i in range(Featurenum):
        midList = [example[i] for example in data]
#中间变量暂存所有个体的第i个特征的数据(既将表格竖着存入数组)
        columnType = set(midList)
#打印出每一列特征所包含的数据有哪些类型,例如[0,0,1,1,2,2] -> [0,1,2]
        conditionsEnt = 0.0
#条件熵
        for value in columnType:
#取当前特征下每一个类型出来
            currentData = choose_column_in_data(data,i,value)
#既在data中,选择第i列中值为value的所有数据并组合到一起
            prob = len(currentData) / float(len(data))
#类似于那个例子中的 5/15 * 2/5
            conditionsEnt += prob * calcu_Entropy(currentData)
#H = -P(a) * P(D|a) * log(2,P(D|a))
        increaseEntropy = baseEntropy - conditionsEnt
#得出:已知当前特征(i)时,得到的熵增益
        print "第%d个特征熵的增益为:%.3f" %(i,increaseEntropy)
        if increaseEntropy > bestFeatureValue:
            bestFeatureValue = increaseEntropy
            bestFeature = i
    return bestFeature

data,labels = createData()
final = Choose_Best_Mutua_Information(data)
print "当前数据中熵增益最大的特征的编号为:  编号",final,

得到了结果为:

跟我们计算的值相同。

下一篇我将继续讲解如何构建具体的决策树。

原文地址:https://www.cnblogs.com/Pinging/p/8528723.html

时间: 2024-11-10 13:06:53

机器学习--DIY笔记与感悟--②决策树(1)的相关文章

《机器学习》第三章 决策树学习 笔记加总结

<机器学习>第三章 决策树学习 决策树学习方法搜索一个完整表示的假设空间,从而避免了受限假设空间的不足.决策树学习的归纳偏置是优越选择较小的树. 3.1.简介 决策树学习是一种逼近离散值目标函数的方法,在这种方法中学习到的函数被表示为一棵决策树. 决策树(Decision Tree)是一种简单但是广泛使用的分类器.通过训练数据构建决策树,可以高效的对未知的数据进行分类. 决策数有两大优点: 1)决策树模型可以读性好,具有描述性,有助于人工分析: 2)效率高,决策树只需要一次构建,反复使用,每一

机器学习&amp;数据挖掘笔记_16(常见面试之机器学习算法思想简单梳理)

http://www.cnblogs.com/tornadomeet/p/3395593.html 机器学习&数据挖掘笔记_16(常见面试之机器学习算法思想简单梳理) 前言: 找工作时(IT行业),除了常见的软件开发以外,机器学习岗位也可以当作是一个选择,不少计算机方向的研究生都会接触这个,如果你的研究方向是机器学习/数据挖掘之类,且又对其非常感兴趣的话,可以考虑考虑该岗位,毕竟在机器智能没达到人类水平之前,机器学习可以作为一种重要手段,而随着科技的不断发展,相信这方面的人才需求也会越来越大.

机器学习实战笔记7(Adaboost)

1:简单概念描述 Adaboost是一种弱学习算法到强学习算法,这里的弱和强学习算法,指的当然都是分类器,首先我们需要简单介绍几个概念. 1:弱学习器:在二分情况下弱分类器的错误率会高于50%.其实任意的分类器都可以做为弱分类器,比如之前介绍的KNN.决策树.Na?ve Bayes.logiostic回归和SVM都可以.这里我们采用的弱分类器是单层决策树,它是一个单节点的决策树.它是adaboost中最流行的弱分类器,当然并非唯一可用的弱分类器.即从特征中选择一个特征来进行分类,该特征能是错误率

机器学习读书笔记(开篇)

新近到手一本<机器学习实战>(Peter Harringtom),兴奋之余,本着好记性不如烂笔头的真理,打算将读书的过程记录下来,形成读书笔记,重点记录自己所理解的算法思想与应用示例.本人野生猿一枚,贻笑大方之处,敬请谅解. 机器学习可以揭示数据背后的真实含义,而数据以及基于数据做出的决策是非常重要的,机器学习的实现离不开数据挖掘算法,书中介绍了几个主要的算法,使用Python以及对应的科学计算包,如NumPy与SciPy等进行编程. 第一部分 分类 机器学习读书笔记01 机器学习基础 机器学

ng机器学习视频笔记(九) ——SVM理论基础

ng机器学习视频笔记(九) --SVM理论基础 (转载请附上本文链接--linhxx) 一.概述 支持向量机(support vector machine,SVM),是一种分类算法,也是属于监督学习的一种.其原理和logistics回归很像,也是通过拟合出一个边界函数,来区分各个分类的结果. 二.代价函数与假设函数 由于svm和logistic很相似,故与logistic进行比较.logistic的代价函数如下: 与logistic不同之处在于,SVM是用两个线段表示logistic中的h.在l

机器学习进阶笔记之一 | TensorFlow安装与入门

原文链接:https://zhuanlan.zhihu.com/p/22410917 TensorFlow 是 Google 基于 DistBelief 进行研发的第二代人工智能学习系统,被广泛用于语音识别或图像识别等多项机器深度学习领域.其命名来源于本身的运行原理.Tensor(张量)意味着 N 维数组,Flow(流)意味着基于数据流图的计算,TensorFlow 代表着张量从图象的一端流动到另一端计算过程,是将复杂的数据结构传输至人工智能神经网中进行分析和处理的过程. -- 由 UCloud

机器学习基石笔记6——为什么机器可以学习(2)

转载请注明出处:http://www.cnblogs.com/ymingjingr/p/4271742.html 目录 机器学习基石笔记1——在何时可以使用机器学习(1) 机器学习基石笔记2——在何时可以使用机器学习(2) 机器学习基石笔记3——在何时可以使用机器学习(3)(修改版) 机器学习基石笔记4——在何时可以使用机器学习(4) 机器学习基石笔记5——为什么机器可以学习(1) 机器学习基石笔记6——为什么机器可以学习(2) 机器学习基石笔记7——为什么机器可以学习(3) 机器学习基石笔记8

[自娱自乐] 3、超声波测距模块DIY笔记(三)

前言 上一节我们已经研究了超声波接收模块并自己设计了一个超声波接收模块,在此基础上又尝试用单片机加反相器构成生成40KHz的超声波发射电路,可是发现采用这种设计的发射电路存在严重的发射功率太低问题,对齐的情况下最多只有10CM.本节主要介绍并制造一种大功率超声波发射装置~ 目录 一.浪里淘金,寻找最简超声波功率提高方案 1.1.优化波形发生程序 1.2.尝试各种其他超声模块方案 1.3.用三极管放大信号 1.4.MAX232放大信号方案 二.步步为营,打造高效准确超声测距算法 2.1.接收MCU

机器学习实战笔记6(SVM)

鉴于July大哥的SVM三层境界(http://blog.csdn.net/v_july_v/article/details/7624837)已经写得非常好了,这里我就不详细描述,只是阐述简单的几个概念.如果看SVM三层境界有困惑,我也愿意与大家交流,共同进步. 简单概念描述: (1)      支持向量机(SVM, support vectormachine)就是通过最大化支持向量到分类超平面之间的分类间隔.分类超平面就是我们想要得到的决策曲面:支持向量就是离分类超平面最近的点,而间隔即为支持