机器学习实战之一---简单讲解决策树

机器学习实战之一---简单讲解决策树

https://blog.csdn.net/class_brick/article/details/78855510

前言:本文基于《机器学习实战》一书,采用python语言,对于机器学习当中的常用算法进行说明。

一、 综述

定义:首先来对决策树进行一个定义,决策树是一棵通过事物的特征来进行判断分支后得到该事物所需要的预测的属性的树。

流程:提取特征à计算信息增益à构建决策树à使用决策树进行预测

关键:树的构造,通过信息增益(熵)得到分支点和分支的方式。

优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据。

缺点:可能会产生过度匹配问题(过拟合)。

适用数据类型:数值型和标称型。

以下是一棵决策树的简单例子,通过邮件的一些特征,来判断一个邮件的类型。

图1

二、 特征提取

此处的特征指的就是用以构造决策树的实体集的特征,此处给出一个用以构造决策树的例子。


cheep


quality


buy


1


1


Yes


1


1


Yes


1


0


No


0


1


No


0


1


No

表1

简单的对表1中的数据进行一个说明,表1表征了小明在购物时基于一个商品便宜(cheep)与否(1/0)以及质量(quality)好坏(1/0)做出的购买选择。

此处的特征可以用一个python函数来创建:

def createDataSet():
    dataSet = [ #数据集对应表格
        [1, 1, ‘yes‘],
        [1, 1, ‘yes‘],
        [1, 0, ‘no‘],
        [0, 1, ‘no‘],
        [0, 1, ‘no‘]
    ]
    labels = [‘cheep‘, ‘quality‘]#标签对应价格与质量
    return dataSet, labels

三、 计算信息增益

1、信息增益的介绍

信息增益是决策树在构造过程中节点的位置即特征判断的先后顺序的主要依据,计算信息增益可以帮助我们在多个特征当中选取选取对获得预测值帮助最大的特征,然后以此来对树当中的节点顺序进行划分。

结合二当中给出的例子,一件商品有价格便宜与否以及质量好坏两个特征,我们需要做的是把这两个特征作为节点放到树中,然后通过便不便宜以及质量好不好来对是否购买这件商品做出决策。而这里就存在一个问题,先判断价格还是先判断质量,这里就可以通过信息增益来做出一个决断。在每一次构造树的时候进行一次信息增益值的计算,然后将信息增益值最大的特征作为优先进行分支的节点。

计算信息增益的公式如下:

其中p(xi)为事件发生的概率。

2、信息增益的python实现

既然得到了信息增益的计算公式,那么这里就用python写一个函数来实现它,数据集采取二当中的例子。

以下函数实现了信息增益的计算:

def calcShannonEnt(dataSet):#入参是一个数据集
    numEntries = len(dataSet)#首先取得数据集中的数据个数
    labelCounts = {}#标签的集
    for featVec in dataSet: #得到每一个数据的标记值
        currentLabel = featVec[-1]  #取得最后一列的标记值
        if currentLabel not in labelCounts.keys(): #如果该标记没有被存到标记集合当中
            labelCounts[currentLabel] = 0 #计算该标记的哈希值记录到标记集当中并赋值为0
        labelCounts[currentLabel] += 1 #对该标记的数量加一
    shannonEnt = 0.0 #初始信息增益为0
    for key in labelCounts: #依次遍历每一个标记
        prob = float(labelCounts[key])/numEntries #得到该标记的概率值
        shannonEnt -= prob * log(prob,2) #求得信息增益
    return shannonEnt

知道了怎么计算信息增益,就可以通过信息增益来对节点的顺序进行选择,进一步构造出一棵决策树。

四、 构造决策树

总的来说,构造决策树是一个递归的过程,首先通过计算信息增益取出一个特征作为判断的节点,然后将取出该特征的剩余数据集继续循环提取特征。

1、首先给出一个函数,该函数的作用是提取给定特征值为给定值的所有数据的数据集。

def splitDataSet(dataSet, axis, value):#按照指定特征划分数据集,dataset为给定数据集,axis为要筛选的特征,value为该特征的值
    retDataSet = [] #被划分后的数据集
    for featVec in dataSet:  #遍历数据集中的每一个数据
        if featVec[axis] == value: #找到数据集当中特征值为设置的值的数据
            reducedFeatVec = featVec[:axis] #提取该特征之前的元素
            reducedFeatVec.extend(featVec[axis+1:]) #提取该特征之后的元素
            retDataSet.append(reducedFeatVec) #将该数据加入到要返回的数据集当中
    return retDataSet

2、然后是一个在给定数据集当中计算出信息增益最大的特征的函数,以此来筛选特征:

def chooseBestFeatureToSplit(dataSet): #获取数据集中的最佳分支特征
    numFeatures = len(dataSet[0]) - 1 #获取特征数量
    baseEntropy = calcShannonEnt(dataSet) #计算基础熵
    bestInfoGain = 0.0 #设置基础最佳信息增益为0
    bestFeature = -1 #最佳特征索引
    for i in range(numFeatures): #依次遍历每一个特征
        featList = [example[i] for example in dataSet] #获取属于该特征的一列数据
        uniqueVals = set(featList) #将数据列转换为set,过滤重复值
        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

3、可以筛选特征之后,就可以进行递归的构造决策树了:

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 = chooseBestFeatureToSplit(dataSet) #选出特征最为划分依据
    bestFeatLabel = labels[bestFeat]
    myTree = {bestFeatLabel:{}} # 将该特征放到树的节点当中
    del(labels[bestFeat]) #在标签集当中去掉该标签
    featValues = [example[bestFeat] for example in dataSet] #取出属于该特征的所有可能取值
    uniqueVals = set(featValues) #转换为set过滤重复值
    for value in uniqueVals: #通过该特征的不同取值对决策树进行分支
        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 

六、总结

决策树是一种相对基础而简单的预测算法,其中还有一些相关的剪枝和图的绘制等没有在本文中提到的知识,此处是对决策树进行一个最简单的介绍,如有不足,请多指教。

原文地址:https://www.cnblogs.com/DicksonJYL/p/9429673.html

时间: 2024-10-12 02:15:17

机器学习实战之一---简单讲解决策树的相关文章

机器学习实战读书笔记(三)决策树

3.1 决策树的构造 优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据. 缺点:可能会产生过度匹配问题. 适用数据类型:数值型和标称型. 一般流程: 1.收集数据 2.准备数据 3.分析数据 4.训练算法 5.测试算法 6.使用算法 3.1.1 信息增益 创建数据集 def createDataSet(): dataSet = [[1, 1, 'yes'], [1, 1, 'yes'], [1, 0, 'no'], [0, 1, 'no'], [0, 1, '

决策树代码《机器学习实战》

22:45:17 2017-08-09 KNN算法简单有效,可以解决很多分类问题.但是无法给出数据的含义,就是一顿计算向量距离,然后分类. 决策树就可以解决这个问题,分类之后能够知道是问什么被划分到一个类.用图形画出来就效果更好了,这次没有学哪个画图的,下次. 这里只涉及信息熵的计算,最佳分类特征的提取,决策树的构建.剪枝没有学,这里没有. 1 # -*- oding: itf-8 -*- 2 3 ''' 4 function: <机器学习实战>决策树的代码,画图的部分没有写: 5 note:

机器学习实战笔记3(决策树)

决策树的优势就在于数据形式非常容易理解,而kNN的最大缺点就是无法给出数据的内在含义. 1:简单概念描述 决策树的类型有很多,有CART.ID3和C4.5等,其中CART是基于基尼不纯度(Gini)的,这里不做详解,而ID3和C4.5都是基于信息熵的,它们两个得到的结果都是一样的,本次定义主要针对ID3算法.下面我们介绍信息熵的定义. 事件ai发生的概率用p(ai)来表示,而-log2(p(ai))表示为事件ai的不确定程度,称为ai的自信息量,sum(p(ai)*I(ai))称为信源S的平均信

[机器学习&amp;数据挖掘]机器学习实战决策树plotTree函数完全解析

在看机器学习实战时候,到第三章的对决策树画图的时候,有一段递归函数怎么都看不懂,因为以后想选这个方向为自己的职业导向,抱着精看的态度,对这本树进行地毯式扫描,所以就没跳过,一直卡了一天多,才差不多搞懂,才对那个函数中的plotTree.xOff的取值,以及计算cntrPt的方法搞懂,相信也有人和我一样,希望能够相互交流. 先把代码贴在这里: import matplotlib.pyplot as plt #这里是对绘制是图形属性的一些定义,可以不用管,主要是后面的算法 decisionNode

机器学习实战(代码讲解)

机器学习实战 http://www.cnblogs.com/qwertWZ/p/4582096.html 机器学习实战笔记:http://blog.csdn.net/Lu597203933/article/details/37969799 #第一个kNN分类器 inX-测试数据 dataSet-样本数据 labels-标签 k-邻近的k个样本 def classify0(inX,dataSet, labels, k): #计算距离 dataSetSize = dataSet.shape[0] d

Python3《机器学习实战》学习笔记

运行平台: Windows Python版本: Python3.x IDE: Sublime text3 一 简单k-近邻算法 1 k-近邻法简介 2 距离度量 3 Python3代码实现 31 准备数据集 32 k-近邻算法 33 整体代码 二 k-近邻算法实战之约会网站配对效果判定 1 实战背景 2 准备数据数据解析 3 分析数据数据可视化 4 准备数据数据归一化 5 测试算法验证分类器 6 使用算法构建完整可用系统 三 k-近邻算法实战之sklearn手写数字识别 1 实战背景 2 Skl

机器学习day12 机器学习实战adaboost集成方法与重新进行疝马病的预测

今天终于完成了分类器的学习,SVM基本不怎么会,很是头疼,先放一下吧,有机会问问大神讲解一下.接下来的几天进行监督学习回归部分的学习,先看看adaboost的理解. 我们再决定一个重要的事情时,往往不是听取一个人的意见,听取大家的意见,然后投票表决最终结果.这一个特点也可以应用于机器学习的算法中来,每一个人都是弱的分类器,若是指一个人的力量很小,很多人汇集在一起就构成了强分类器.好比政府的投票系统. 有一个有趣的现象,若每个人都有51%的几率选择正确,则汇集很多人的投票信息之后选择正确的人比选择

机器学习实战教程(五):朴素贝叶斯实战篇之新浪新闻分类

原文链接: Jack-Cui,https://cuijiahua.com/blog/2017/11/ml_5_bayes_2.html 一.前言 上篇文章机器学习实战教程(四):朴素贝叶斯基础篇之言论过滤器讲解了朴素贝叶斯的基础知识.本篇文章将在此基础上进行扩展,你将看到以下内容: 拉普拉斯平滑 垃圾邮件过滤(Python3) 新浪新闻分类(sklearn) 二.朴素贝叶斯改进之拉普拉斯平滑 上篇文章提到过,算法存在一定的问题,需要进行改进.那么需要改进的地方在哪里呢?利用贝叶斯分类器对文档进行

机器学习实战笔记2(k-近邻算法)

1:算法简单描述 给定训练数据样本和标签,对于某测试的一个样本数据,选择距离其最近的k个训练样本,这k个训练样本中所属类别最多的类即为该测试样本的预测标签.简称kNN.通常k是不大于20的整数,这里的距离一般是欧式距离. 2:python代码实现 创建一个kNN.py文件,将核心代码放在里面了. (1)   创建数据 #创造数据集 def createDataSet(): group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]]) labe