python决策树之C4.5算法详解


Posted in Python onDecember 20, 2017

本文为大家分享了决策树之C4.5算法,供大家参考,具体内容如下

1. C4.5算法简介

  C4.5算法是用于生成决策树的一种经典算法,是ID3算法的一种延伸和优化。C4.5算法对ID3算法主要做了一下几点改进:

  (1)通过信息增益率选择分裂属性,克服了ID3算法中通过信息增益倾向于选择拥有多个属性值的属性作为分裂属性的不足;
  (2)能够处理离散型和连续型的属性类型,即将连续型的属性进行离散化处理;
  (3)构造决策树之后进行剪枝操作;
  (4)能够处理具有缺失属性值的训练数据。

2. 分裂属性的选择——信息增益率

  分裂属性选择的评判标准是决策树算法之间的根本区别。区别于ID3算法通过信息增益选择分裂属性,C4.5算法通过信息增益率选择分裂属性。

  属性A的“分裂信息”(split information):

python决策树之C4.5算法详解

其中,训练数据集S通过属性A的属性值划分为m个子数据集,|Sj|表示第j个子数据集中样本数量,|S|表示划分之前数据集中样本总数量。

  通过属性A分裂之后样本集的信息增益:

python决策树之C4.5算法详解

信息增益的详细计算方法,可以参考博客“决策树之ID3算法及其Python实现”中信息增益的计算。

  通过属性A分裂之后样本集的信息增益率:

python决策树之C4.5算法详解

  通过C4.5算法构造决策树时,信息增益率最大的属性即为当前节点的分裂属性,随着递归计算,被计算的属性的信息增益率会变得越来越小,到后期则选择相对比较大的信息增益率的属性作为分裂属性。

3. 连续型属性的离散化处理

  当属性类型为离散型,无须对数据进行离散化处理;当属性类型为连续型,则需要对数据进行离散化处理。C4.5算法针对连续属性的离散化处理,核心思想:将属性A的N个属性值按照升序排列;通过二分法将属性A的所有属性值分成两部分(共有N-1种划分方法,二分的阈值为相邻两个属性值的中间值);计算每种划分方法对应的信息增益,选取信息增益最大的划分方法的阈值作为属性A二分的阈值。详细流程如下:
(1)将节点Node上的所有数据样本按照连续型属性A的具体取值,由小到大进行排列,得到属性A的属性值取值序列(xA1,...,xAN)
(2)在序列(xA1,...,xAN)中共有N-1种二分方法,即共产生N-1个分隔阈值。对于第i种二分方法,其二分阈值θi=xAi+xAi+12。它将该节点上的数据集划分为2个子数据集(xA1,...,xAi)(xAi+1,...,xAN)。计算此种二分结果下的信息增益。
(3)分别计算N-1种二分结果下的信息增益,选取信息增益最大的二分结果作为对属性A的划分结果,并记录此时的二分阈值。

4. 剪枝——PEP(Pessimistic Error Pruning)剪枝法

  由于决策树的建立完全是依赖于训练样本,因此该决策树对训练样本能够产生完美的拟合效果。但这样的决策树对于测试样本来说过于庞大而复杂,可能产生较高的分类错误率。这种现象就称为过拟合。因此需要将复杂的决策树进行简化,即去掉一些节点解决过拟合问题,这个过程称为剪枝。
  剪枝方法分为预剪枝和后剪枝两大类。预剪枝是在构建决策树的过程中,提前终止决策树的生长,从而避免过多的节点产生。预剪枝方法虽然简单但实用性不强,因为很难精确的判断何时终止树的生长。后剪枝是在决策树构建完成之后,对那些置信度不达标的节点子树用叶子结点代替,该叶子结点的类标号用该节点子树中频率最高的类标记。后剪枝方法又分为两种,一类是把训练数据集分成树的生长集和剪枝集;另一类算法则是使用同一数据集进行决策树生长和剪枝。常见的后剪枝方法有CCP(Cost Complexity Pruning)、REP(Reduced Error Pruning)、PEP(Pessimistic Error Pruning)、MEP(Minimum Error Pruning)。
  C4.5算法采用PEP(Pessimistic Error Pruning)剪枝法。PEP剪枝法由Quinlan提出,是一种自上而下的剪枝法,根据剪枝前后的错误率来判定是否进行子树的修剪,因此不需要单独的剪枝数据集。接下来详细介绍PEP(Pessimistic Error Pruning)剪枝法。
  对于一个叶子节点,它覆盖了n个样本,其中有e个错误,那么该叶子节点的错误率为(e+0.5)/n,其中0.5为惩罚因子(惩罚因子一般取值为0.5)。
  对于一棵子树,它有L个叶子节点,那么该子树的误判率为:

python决策树之C4.5算法详解

其中,ei表示子树第i个叶子节点错误分类的样本数量,ni表示表示子树第i个叶子节点中样本的总数量。

  假设一棵子树错误分类一个样本取值为1,正确分类一个样本取值为0,那么子树的误判次数可以认为是一个伯努利分布,因此可以得到该子树误判次数的均值和标准差:

python决策树之C4.5算法详解

把子树替换成叶子节点后,该叶子节点的误判率为:

python决策树之C4.5算法详解

其中,e′=∑Li=1ein′=∑Li=1ni

同时,该叶子结点的误判次数也是一个伯努利分布,因此该叶子节点误判次数的均值为:

python决策树之C4.5算法详解

剪枝的条件为:

python决策树之C4.5算法详解

满足剪枝条件时,则将所得叶子节点替换该子树,即为剪枝操作。

5. 缺失属性值的处理

  训练样本集中有可能会出现一些样本缺失了一些属性值,待分类样本中也会出现这样的情况。当遇到这样的样本集时该如何处理呢?含有缺失属性的样本集会一般会导致三个问题:

  (1)在构建决策树时,每一个分裂属性的选取是由训练样本集中所有属性的信息??益率来决定的。而在此阶段,如果训练样本集中有些样本缺少一部分属性,此时该如何计算该属性的信息??益率;

  (2)当已经选择某属性作为分裂属性时,样本集应该根据该属性的值来进行分支,但对于那些该属性的值为未知的样本,应该将它分支到哪一棵子树上;

  (3)在决策树已经构建完成后,如果待分类样本中有些属性值缺失,则该样本的分类过程如何进行。

  针对上述因缺失属性值引起的三个问题,C4.5算法有多种解决方案。
  面对问题一,在计算各属性的信息??益率时,若某些样本的属性值未知,那么可以这样处理:计算某属性的信息??益率时忽略掉缺失了此属性的样本;或者通过此属性的样本中出现频率最高的属性值,?值给缺失了此属性的样本。
  面对问题二,假设属性A已被选择作为决策树中的一个分支节点,在对样本集进行分支的时候,对于那些属性A的值未知的样本,可以送样处理:不处理那些属性A未知的样本,即简单的忽略它们;或者根据属性A的其他样本的取值,来对未知样本进行赋值;或者为缺失属性A的样本单独创建一个分支,不过这种方式得到的决策树模型结点数显然要??加,使模型更加复杂了。
  面对问题三,根据己经生成的决策树模型,对一个待分类的样本进行分类时,若此样本的属性A的值未知,可以这样处理:待分类样本在到达属性A的分支结点时即可结束分类过程,此样本所属类别为属性A的子树中概率最大的类别;或者把待分类样本的属性A赋予一个最常见的值,然后继续分类过程。

6. C4.5算法流程

python决策树之C4.5算法详解

7. C4.5算法优缺点分析

优点:

(1)通过信息增益率选择分裂属性,克服了ID3算法中通过信息增益倾向于选择拥有多个属性值的属性作为分裂属性的不足;
(2)能够处理离散型和连续型的属性类型,即将连续型的属性进行离散化处理;
(3)构造决策树之后进行剪枝操作;
(4)能够处理具有缺失属性值的训练数据。

缺点:
(1)算法的计算效率较低,特别是针对含有连续属性值的训练样本时表现的尤为突出。
(2)算法在选择分裂属性时没有考虑到条件属性间的相关性,只计算数据集中每一个条件属性与决策属性之间的期望信息,有可能影响到属性选择的正确性。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
10种检测Python程序运行时间、CPU和内存占用的方法
Apr 01 Python
在Python中利用Pandas库处理大数据的简单介绍
Apr 07 Python
在Python中调用ggplot的三种方法
Apr 08 Python
python文件操作相关知识点总结整理
Feb 22 Python
Python编写电话薄实现增删改查功能
May 07 Python
python用Pygal如何生成漂亮的SVG图像详解
Feb 10 Python
解决pandas中读取中文名称的csv文件报错的问题
Jul 04 Python
python opencv对图像进行旋转且不裁剪图片的实现方法
Jul 09 Python
Python Selenium 之数据驱动测试的实现
Aug 01 Python
Pandas把dataframe或series转换成list的方法
Jun 14 Python
教你使用一行Python代码玩遍童年的小游戏
Aug 23 Python
Python 统计序列中元素的出现频度
Apr 26 Python
python 3.6 +pyMysql 操作mysql数据库(实例讲解)
Dec 20 #Python
python实现ID3决策树算法
Dec 20 #Python
理解python中生成器用法
Dec 20 #Python
Python利用turtle库绘制彩虹代码示例
Dec 20 #Python
浅谈Python中range和xrange的区别
Dec 20 #Python
python机器学习实战之树回归详解
Dec 20 #Python
使用python 和 lint 删除项目无用资源的方法
Dec 20 #Python
You might like
php+mysql 实现身份验证代码
2010/03/24 PHP
php数字转汉字代码(算法)
2011/10/08 PHP
PHP的加密方式及原理
2012/06/14 PHP
深入PHP变量存储的详解
2013/06/13 PHP
zend Framework中的Layout(模块化得布局)详解
2013/06/28 PHP
PHP循环结构实例讲解
2014/02/10 PHP
php页面,mysql数据库转utf-8乱码,utf-8编码问题总结
2015/08/27 PHP
PHP内核探索之变量
2015/12/22 PHP
详解PHP的Laravel框架中Eloquent对象关系映射使用
2016/02/26 PHP
js(jQuery)获取时间的方法及常用时间类搜集
2013/10/23 Javascript
window.open()详解及浏览器兼容性问题示例探讨
2014/05/29 Javascript
javascript原始值和对象引用实例分析
2015/04/25 Javascript
基于MVC4+EasyUI的Web开发框架形成之旅之界面控件的使用
2015/12/16 Javascript
jQuery插件 Jqplot图表实例
2016/06/18 Javascript
Bootstrap Metronic完全响应式管理模板学习笔记
2016/07/08 Javascript
JSON键值对序列化和反序列化解析
2017/01/24 Javascript
jquery中封装函数传递当前元素的方法示例
2017/05/05 jQuery
微信小程序日历组件calendar详解及实例
2017/06/08 Javascript
JS中this的指向以及call、apply的作用
2018/05/06 Javascript
react.js组件实现拖拽复制和可排序的示例代码
2018/08/20 Javascript
JS使用for in有序获取对象数据
2020/05/19 Javascript
使用 UniApp 实现小程序的微信登录功能
2020/06/09 Javascript
Python使用lxml模块和Requests模块抓取HTML页面的教程
2016/05/16 Python
python pandas 对时间序列文件处理的实例
2018/06/22 Python
windows下安装Python虚拟环境virtualenvwrapper-win
2019/06/14 Python
一文秒懂python读写csv xml json文件各种骚操作
2019/07/04 Python
详解用Pytest+Allure生成漂亮的HTML图形化测试报告
2020/03/31 Python
keras 模型参数,模型保存,中间结果输出操作
2020/07/06 Python
python 获取剪切板内容的两种方法
2020/11/28 Python
Html5 Canvas动画基础碰撞检测的实现
2018/12/06 HTML / CSS
法国和欧洲海边和滑雪度假:Pierre & Vacances
2017/01/04 全球购物
美国体育用品商店:Paragon Sports
2017/10/08 全球购物
Java如何格式化日期
2012/08/07 面试题
商场促销活动策划方案
2014/08/18 职场文书
2016中学教师读书心得体会
2016/01/13 职场文书
2016年全国爱眼日宣传教育活动总结
2016/04/05 职场文书