手把手生成决策树(dicision tree)

手把手生成决策树(dicision tree)

主要參考资料:

Peter HARRINGTON.机器学习实战[M].李锐,李鹏,曲亚东,王斌译.北京:人民邮电出版社, 2013.

李航.统计学习方法[M].北京:清华大学出版社, 2012



原文链接:http://blog.csdn.net/xuelabizp/article/details/50979469

1.什么是决策树

决策树是一种主要的分类和回归方法。本文主要解说用于分类的决策树。

决策树就是依据相关的条件进行分类的一种树形结构,比方某高端约会站点针对女客户约会对象见面的安排过程就是一个决策树:

依据给定的数据集创建一个决策树就是机器学习的课程,创建一个决策树可能会花费较多的时间。可是使用一个决策树却很快。

创建决策树时最关键的问题就是选取哪一个特征作为分类特征。好的分类特征能够最大化的把数据集分开,将无序变为有序。

这里就出现了一个问题。怎样描写叙述一个数据集有序的程度?在信息论和概率统计中,表示随机变量不确定性的度量,即有序的程度。

现给出一个集合D。本文全部的讨论都以该集合为例:

序号 不浮出水面能否够生存 是否有脚蹼 是否为鱼类
1
2
3
4
5

创建该集合的代码例如以下:

def create_data_set():
    dataSet =   [[1,1,‘yes‘],
                [1,1,‘yes‘],
                [1,0,‘no‘],
                [0,1,‘no‘],
                [0,1,‘no‘]]
    labels = [‘no surfacing‘, ‘flippers‘] #不浮出水面能否够生存。是否有脚蹼
    return dataSet, labels

2.熵,信息增益和信息增益比

2.1熵(entropy)

博主第一次接触“熵”这个字。是在高中的化学课上,可是感觉“熵”在化学课上的含义和信息论中的含义没什么差别。都是表示混乱的程度,熵越大,越混乱,比方一杯浑浊水的熵就比一杯纯净的水熵大。

在信息论和概率统计中。设X是一个取有限个值的离散随机变量,其概率分布为:

P(X=xi)=pi,i=1,2,3,..,n(1)

则随机变量X的熵定义为:

H(X)=?∑i=1npilog2pi(2)

若pi=0。则规定0log0=0。须要说明的是。熵仅仅依赖于X的分布。而不依赖于X的值。依据(2)式就能够计算出上面给定的集合D的熵:

H(D)=?(?25log225?35log235)=0.971

编写计算熵的函数,当中dataSet是建立决策树的数据集,每行最后一个元素表示类别:

def cal_Ent(dataSet): #依据给定数据集计算熵
    num = len(dataSet)
    labels = {}
    for row in dataSet: #统计全部标签的个数
        label = row[-1]
        if label not in labels.keys():
            labels[label] = 0
        labels[label] += 1
    Ent = 0.0
    for key in labels: #计算熵
        prob = float(labels[key]) / num
        Ent -= prob * log(prob, 2)
    return Ent

2.2信息增益(information gain)

信息增益表示得知特征X的信息而使得类Y的信息的不确定性降低的程度。

换一个角度解释一下。一杯浑浊的水Y,其熵为H1,如今将当中悬浮的一类物质X去除。这杯水的熵下降为H2,则物质X对于这杯水的信息增益就为H1?H2。

特征X对数据集D的信息增益记为g(D,X),计算公式例如以下:

g(D,X)=H(D)?H(D|X)(3)

当中H(D|X)为特征X给定条件下D的经验条件熵。

先解释什么是条件熵:

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

条件熵的计算公式例如以下:

H(Y|X)=∑i=1npiH(Y|X=xi)(4)

当熵和条件熵中的概率由数据预计得到时,所相应的熵与条件熵分别称为经验熵经验条件熵

决策树选择某个特征作为其分类特征的依据就是该特征对于集合的信息增益最大,即去除该特征后,集合变得最有序。

仍旧以给定的集合D为例,依据计算信息增益准则选择最优分类特征。

以X1表示“不浮出水面能否够生存”。则

g(D,X1)=H(D)?[35H(D1)+25H(D2)]=0.971?[35(?23log223?13log213)+25(?22log222)]=0.420

当中D1,D2表示D中X1取“是”和“否”的样本子集。

以X2表示“是否有脚蹼”,则

g(D,X2)=H(D)?[45H(D1)+15H(D2)]=0.971?[45(?24log224?24log224)+15(?11log211)]=0.171

当中D1,D2表示D中X2取“是”和“否”的样本子集。

比較各个特征的信息增益。X1的信息增益较大,所以选择X1作为分类的最优特征。

编写选择最佳决策特征的函数,当中dataSet是建立决策树的数据集,每行最后一个元素表示类别:

#依照给定特征划分数据集,返回第axis个特征的值为value的全部数据
def split_data_set(dataSet, axis, value):
    retDataSet = []
    for row in dataSet:
        if (row[axis]) == value:
            reducedRow = row[:axis]
            reducedRow.extend(row[axis+1:])
            retDataSet.append(reducedRow)
    return retDataSet

#选择最佳决策特征
def choose_best_feature(dataSet):
    num = len(dataSet[0]) - 1 #特征数
    baseEnt = cal_Ent(dataSet)
    bestInfoGain = 0.0
    bestFeature = -1
    for i in range(num):
        featlist = [example[i] for example in dataSet] #按列遍历数据集,选取一个特征的全部值
        uniqueVals = set(featlist) #一个特征能够取的值
        newEnt = 0.0
        for value in uniqueVals:
            subDataSet = split_data_set(dataSet, i, value)
            prob = len(subDataSet) / float(len(dataSet))
            newEnt += prob * cal_Ent(subDataSet)
        infoGain = baseEnt - newEnt #信息增益
        if (infoGain > bestInfoGain):
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature

ID3决策树在生成的过程中。依据信息增益来选择特征。

2.3信息增益比(information gain ratio)

以信息增益作为划分训练数据集的特征。存在偏向于选择取值较多的特征的问题,使用信息增益比能够对这一问题进行校正。

特征X对训练数据集D的信息增益比gR(D,X)定义为其信息增益g(D,X)与训练数据集D关于特征X的值的熵HX(D)之比。

信息增益比计算公式例如以下:

gR(D,X)=g(D,X)HX(D)(5)

当中

HX(D)=?∑i=1n|Di||D|log2|Di||D|(6)

以给定的集合D为例,计算信息增益比。

HX1(D)=?(?35log235?25log225)=0.971

gR(D,X1)=g(D,X1)HX1(D)=0.4200.971=0.433

HX2(D)=?(?45log245?15log215)=0.722

gR(D,X2)=g(D,X2)HX2(D)=0.1710.722=0.237

依据信息增益比,选择X1作为分类的最优特征。

C4.5决策树在生成的过程中。依据信息增益比来选择特征。

3.实现一个决策树

3.1创建或加载数据集

首先须要创建或加载训练的数据集,第一节用的是创建数据集的方法,只是更经常使用的是利用open()函数打开文件,加载一个数据集。

3.2生成决策树

决策树一般使用递归的方法生成。

编写递归函数有一个好习惯。就是先考虑结束条件。

生成决策树结束的条件有两个:其一是划分的数据都属于一个类,其二是全部的特征都已经使用了。在另外一种结束情况中。划分的数据有可能不全属于一个类,这个时候须要依据多数表决准则确定这个子数据集的分类。

在非结束的条件下。首先选择出信息增益最大的特征,然后依据其分类。

分类開始时,记录分类的特征到决策树中。然后在特征标签集中删除该特征。表示已经使用过该特征。依据选中的特征将数据集分为若干个子数据集,然后将子数据集作为參数递归创建决策树,终于生成一棵完整的决策树。

#多数表决法则
def majorityCnt(classList):
    print classList
    classCount = {}
    for vote in classList: #统计数目
        if vote not in classCount.keys(): classCount[vote] = 0
        classCount += 1
    sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
    return classCount[0][0]

# 生成决策树
def create_tree(dataSet, labels):
    labelsCloned = labels[:]
    classList = [example[-1] for example in dataSet] #[yes,yes,no,no,no]
    if classList.count(classList[0]) == len(classList): #仅仅有一种类别,则停止划分
        return classList[0]
    if len(dataSet[0]) == 1: #没有特征,则停止划分
        return majorityCnt(classList)
    #print dataSet
    bestFeat = choose_best_feature(dataSet)
    bestFeatLabel = labelsCloned[bestFeat] #最佳特征的名字
    myTree = {bestFeatLabel:{}}
    del(labelsCloned[bestFeat])
    featValues = [example[bestFeat] for example in dataSet] #获取最佳特征的全部属性
    uniqueVals = set(featValues)
    for value in uniqueVals: #建立子树
        subLabels = labelsCloned[:] #深拷贝,不能改变原始列表的内容,由于每个子树都要使用
        myTree[bestFeatLabel][value] = create_tree(split_data_set(dataSet, bestFeat, value), subLabels)
    return myTree

生成的决策树例如以下所看到的:

3.3使用决策树

使用决策树对输入进行分类的函数也是一个递归函数。

分类函数须要三个參数:决策树。特征列表,待分类数据。特征列表是联系决策树和待分类数据的桥梁,决策树的特征通过特征列表获得其索引,再通过索引訪问待分类数据中该特征的值。

def classify(tree, featLabels, testVec):
    firstJudge = tree.keys()[0]
    secondDict = tree[firstJudge]
    featIndex = featLabels.index(firstJudge) #获得特征索引
    for key in secondDict: #进入相应的分类集合
        if key == testVec[featIndex]: #按特征分类
            if type(secondDict[key]).__name__ == ‘dict‘: #假设分类结果是一个字典,则说明还要继续分类
                classLabel = classify(secondDict[key], featLabels, testVec)
            else: #分类结果不是字典。则分类结束
                classLabel = secondDict[key]
    return classLabel

3.4保存或者加载决策树

生成决策树是比較花费时间的,所以决策树生成以后存储起来。等要用的时候直接读取就可以。

def store_tree(tree, fileName): #保存树
    import pickle
    fw = open(fileName, ‘w‘)
    pickle.dump(tree, fw)
    fw.close()

def grab_tree(fileName): #读取树
    import pickle
    fr = open(fileName)
    return pickle.load(fr)

4.决策树可视化

使用字典的形式表示决策树对于人类来说还是有点抽象,假设能以图像的方式呈现就很方便了。很幸运,matplotlib中有模块能够使决策树可视化。这里就不解说了,直接“拿来使用”。将treePlotter.py复制到我们文件的根文件夹。直接导入treePlotter,然后调用treePlotter.createPlot()函数就可以:

import treePlotter
treePlotter.createPlot(tree)

如上面的决策树可视化后例如以下:

5.使用决策树预測隐形眼镜类型

隐形眼镜数据集包括患者的眼睛状况以及医生推荐的隐形眼镜类型。患者信息有4维,分别表示年龄,视力类型,是否散光,眼睛状况。隐形眼镜类型有3种,各自是软材质,硬材质和不适合带隐形眼镜。

想要把我们编写的脚本应用于别的数据集?没问题,仅仅要改动加载数据集的函数就可以,其它的函数不须要改变,详细例如以下:

#加载数据
def file2matrix():
    file = open("lenses.data.txt")
    allLines = file.readlines()
    row = len(allLines)
    dataSet = []
    for line in allLines:
        line = line.strip()
        listFromLine = line.split()
        dataSet.append(listFromLine)
    labels = [‘age‘, ‘prescription‘, ‘astigmatic‘, ‘tear rate‘] #年龄,视力类型,是否散光。眼睛状况
    return dataSet, labels

生成的决策树可视化后例如以下:

事实上博主还尝试了其它的数据集,只是决策树实在是太复杂了。太大了。密密麻麻根本看不清楚。谁有兴趣能够尝试一下别的数据集。

6.总结

  • 源代码在我的GitHub中。包括了可视化脚本以及数据集
  • MachineLearningAction仓库里面有常见的机器学习算法处理常见数据集的各种实例。欢迎訪问
  • 决策树的长处
    • 决策树易于理解和解释,尤其是可视化后的决策树很直观
    • 决策树分类很快
  • 决策树的缺点
    • easy过拟合
    • 对缺失数据的数据集处理困难
    • 忽略数据集中特征的相互关联
  • 常见的决策树有ID3,C4.5和CART决策树
    • C4.5较之ID3更优。信息增益比能够解决信息增益选取取值较多的特征的问题
    • C4.5决策树生成的过程中有剪枝。能够降低决策树的拟合度
    • C4.5能够处理数值型数据,而ID3仅仅能处理标称型数据
  • 决策树能够应用在贷款发放,约会见面等方面
时间: 2025-01-05 04:32:33

手把手生成决策树(dicision tree)的相关文章

转载:算法杂货铺——分类算法之决策树(Decision tree)

作者:张洋 算法杂货铺——分类算法之决策树(Decision tree) 2010-09-19 16:30 by T2噬菌体, 44346 阅读, 29 评论, 收藏, 编辑 3.1.摘要 在前面两篇文章中,分别介绍和讨论了朴素贝叶斯分类与贝叶斯网络两种分类算法.这两种算法都以贝叶斯定理为基础,可以对分类及决策问题进行概率推断.在这一篇文章中,将讨论另一种被广泛使用的分类算法——决策树(decision tree).相比贝叶斯算法,决策树的优势在于构造过程不需要任何领域知识或参数设置,因此在实际

机器学习算法实践:决策树 (Decision Tree)(转载)

前言 最近打算系统学习下机器学习的基础算法,避免眼高手低,决定把常用的机器学习基础算法都实现一遍以便加深印象.本文为这系列博客的第一篇,关于决策树(Decision Tree)的算法实现,文中我将对决策树种涉及到的 算法进行总结并附上自己相关的实现代码.所有算法代码以及用于相应模型的训练的数据都会放到GitHub上(https://github.com/PytLab/MLBox). 本文中我将一步步通过MLiA的隐形眼镜处方数集构建决策树并使用Graphviz将决策树可视化. 决策树学习 决策树

机器学习(二)之决策树(Decision Tree)

Contents 理论基础 熵 信息增益 算法实现 Python 模型的保存与读取 总结 理论基础 决策树(Decision Tree, DT):决策树是一种基本的分类与回归方法.由于模型呈树形结构,可以看做是if-then规则的集合,具有一定的可读性,可视化效果好. 决策树的建立包括3个步骤:特征选择.决策树生成和决策树的修剪. 模型的建立实际上就是通过某种方式,递归地选择最优的特征,并通过数据的划分,将无序的数据变得有序. 因此,在构造决策树时,第一个需要解决的问题就是如何确定出哪个特征在划

数据挖掘-决策树 Decision tree

数据挖掘-决策树 Decision tree 目录 数据挖掘-决策树 Decision tree 1. 决策树概述 1.1 决策树介绍 1.1.1 决策树定义 1.1.2 本质 1.1.3 决策树的组成 1.1.4 决策树的分类 1.1.5 决策过程 1.2 决策树的优化 1.2.1 过拟合 1.3.1 剪枝 2. 理论基础 2.1 香农理论 2.1.1 信息量 2.1.2 平均信息量/信息熵 2.1.3 条件熵 2.1.4 信息增益(Information gain) 2.1.5 信息增益率

【机器学习算法-python实现】决策树-Decision tree(1) 信息熵划分数据集

(转载请注明出处:http://blog.csdn.net/buptgshengod) 1.背景 决策书算法是一种逼近离散数值的分类算法,思路比較简单,并且准确率较高.国际权威的学术组织,数据挖掘国际会议ICDM (the IEEE International Conference on Data Mining)在2006年12月评选出了数据挖掘领域的十大经典算法中,C4.5算法排名第一.C4.5算法是机器学习算法中的一种分类决策树算法,其核心算法是ID3算法. 算法的主要思想就是将数据集依照特

【机器学习算法-python实现】决策树-Decision tree(2) 决策树的实现

(转载请注明出处:http://blog.csdn.net/buptgshengod) 1.背景 接着上一节说,没看到请先看一下上一节关于数据集的划分数据集划分.如今我们得到了每一个特征值得信息熵增益,我们依照信息熵增益的从大到校的顺序,安排排列为二叉树的节点.数据集和二叉树的图见下. (二叉树的图是用python的matplotlib库画出来的) 数据集: 决策树: 2.代码实现部分 由于上一节,我们通过chooseBestFeatureToSplit函数已经能够确定当前数据集中的信息熵最大的

机器学习入门 - 1. 介绍与决策树(decision tree)

机器学习(Machine Learning) 介绍与决策树(Decision Tree) 机器学习入门系列 是 个人学习过程中的一些记录与心得.其主要以要点形式呈现,简洁明了. 1.什么是机器学习? 一个比较概括的理解是: 根据现有的数据,预测未来 2.核心思想 : Generalization 可以理解为,归纳.概括.就像是人的学习一样,找出一件事物与与一件事物的联系 3.归纳性的机器学习(Inductive machine learning) 其核心思想是使用训练数据,并从其中摸索出一套适用

Spark上的决策树(Decision Tree On Spark)

最近花了一些时间学习了Scala和Spark,学习语言和框架这样的东西,除了自己敲代码折腾和玩弄外,另一个行之有效的方法就是阅读代码.MLlib正好是以Spark为基础的开源机器学习库,便借机学习MLlib是如何利用Spark实现分布式决策树.本文主要是剖析MLlib的DecisionTree源码,假设读者已经入门Scala基本语法,并熟悉决策树的基本概念,假如您不清楚,可以参照Coursera上两门课程,一门是Scala之父Martin Odersky的<Functional Programm

【转载】决策树Decision Tree学习

本文转自:http://www.cnblogs.com/v-July-v/archive/2012/05/17/2539023.html 最近在研究规则引擎,需要学习决策树.决策表等算法.发现篇好文对我这个初学者很有指导价值,先转再细品. 1. 什么是决策树 咱们直接切入正题.所谓决策树,顾名思义,是一种树,一种依托于策略抉择而建立起来的树. 机器学习中,决策树是一个预测模型:他代表的是对象属性与对象值之间的一种映射关系.树中每个节点表示某个对象,而每个分叉路径则代表的某个可能的属性值,而每个叶