Python机器学习算法之决策树算法的实现与优缺点


Posted in Python onMay 13, 2021

1.算法概述

决策树算法是在已知各种情况发生概率的基础上,通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法。

分类算法是利用训练样本集获得分类函数即分类模型(分类器),从而实现将数据集中的样本划分到各个类中。分类模型通过学习训练样本中属性集与类别之间的潜在关系,并以此为依据对新样本属于哪一类进行预测。

Python机器学习算法之决策树算法的实现与优缺点

决策树算法是直观运用概率分析的一种图解法,是一种十分常用的分类方法,属于有监督学习。

决策树是一种树形结构,其中每个内部结点表示在一个属性上的测试,每个分支代表一个测试输出,每个叶子结点代表一种类别。

决策树学习是以实例为基础的归纳学习,它采用自顶向下的递归方法,其基本思想是以信息熵为度量构造一颗熵值下降最快的树,到叶子结点处的熵值为零,此时每个叶子节点中的实例都属于同一类。

决策树学习算法的最大优点是,它可以自学习,在学习的过程中不需要使用者了解过多的背景知识,只需要对训练实例进行较好的标注,就能够进行学习。

2.算法种类

ID3算法

  • ID3算法中根据信息论的信息增益评估和选择特征。每次选择信息增益最大的候选特征,作为判断模块。
  • 信息增益与属性的值域大小成正比。属性取值种类越多,越有可能成为分裂属性。
  • ID3也不能处理连续分布的数据。

C4.5算法

  • C4.5算法使用信息增益率代替信息增益,进行特征选择,克服了信息增益选择特征时偏向于特征值个数较多的不足。
  • C4.5算法具体算法步骤与ID3类似。
  • C4.5能够完成对连续属性的离散化处理,能够对不完整数据进行处理。

C5.0算法

  • C5.0算法是Quinlan在C4.5算法的基础上提出的商用改进版本,目的是对含有大量数据的数据集进行分析。
  • C5.0算法与C4.5算法相比有以下优势:
    • 决策树构建时间要比C4.5算法快上数倍,同时生成的决策树规模也更小,拥有更少的叶子结点数
    • 使用了提升法(boosting),组合多个决策树来做出分类,使准确率大大提高
    • 提供可选项由使用者视情况决定,例如是否考虑样本的权重、样本错误分类成本等

CART算法

  • CART决策树的生成就是递归地构建二叉决策树的过程。
  • CART用基尼系数最小化准则来进行特征选择,生成二叉树。
  • Gini系数计算公式:

Python机器学习算法之决策树算法的实现与优缺点

3.算法示例

Python机器学习算法之决策树算法的实现与优缺点

在机器学习中,决策树是一种预测模型,它代表的是对象属性与对象值之间的一种映射关系。

决策树的目的是拟合一个可以通过指定输入值预测最终输出值得模型。

Python机器学习算法之决策树算法的实现与优缺点

4.决策树构建示例

描述

Python机器学习算法之决策树算法的实现与优缺点

分析

Python机器学习算法之决策树算法的实现与优缺点

计算

Python机器学习算法之决策树算法的实现与优缺点

结论

Python机器学习算法之决策树算法的实现与优缺点

5.算法实现步骤

选择属性是构建一颗决策树非常关键的一步,被选择的属性会成为决策树的一个节点,并且不断递归地选择最优的属性就可以最终构建决策树。

Python机器学习算法之决策树算法的实现与优缺点

计算数据集S中的每个属性的熵 H(xi)选取数据集S中熵值最小(或者信息增益最大,两者等价)的属性在决策树上生成该属性节点使用剩余结点重复以上步骤生成决策树的属性节点

 6.算法相关概念

1948年,香农提出了“信息熵”的概念,熵是接收的每条信息中所包含信息的平均量,是不确定性的量度,而不是确定性的量度,因为越随机的信源的熵越大。熵被定义为概率分布的对数的相反数。

信息熵的公式:Python机器学习算法之决策树算法的实现与优缺点

信息增益

“信息增益”是用来衡量一个属性区分数据样本的能力,当使用某一个属性作为一棵决策树的根节点时,该属性的信息增益量就越大。决策树会选择最大化信息增益来对结点进行划分。

Python机器学习算法之决策树算法的实现与优缺点

7.算法实现代码

import numpy as np
import math
from collections import Counter

# 创建数据
def create_data():
    X1 = np.random.rand(50, 1)*100
    X2 = np.random.rand(50, 1)*100
    X3 = np.random.rand(50, 1)*100
    
    def f(x):
        return 2 if x > 70 else 1 if x > 40 else 0
    
    y = X1 + X2 + X3
    Y = y > 150
    Y = Y + 0
    r = map(f, X1)
    X1 = list(r)
    
    r = map(f, X2)
    X2 = list(r)
    
    r = map(f, X3)
    X3 = list(r)
    x = np.c_[X1, X2, X3, Y]
    return x, ['courseA', 'courseB', 'courseC']


# 计算集合信息熵的函数
def calculate_info_entropy(dataset):
    n = len(dataset)
    # 我们用Counter统计一下Y的数量
    labels = Counter(dataset[:, -1])
    entropy = 0.0
    # 套用信息熵公式
    for k, v in labels.items():
        prob = v / n
        entropy -= prob * math.log(prob, 2)
    return entropy

# 实现拆分函数
def split_dataset(dataset, idx):
  	# idx是要拆分的特征下标
    splitData = defaultdict(list)
    for data in dataset:
      	# 这里删除了idx这个特征的取值,因为用不到了
        splitData[data[idx]].append(np.delete(data, idx))
    return list(splitData.values()), list(splitData.keys())

# 实现特征的选择函数
def choose_feature_to_split(dataset):
    n = len(dataset[0])-1
    m = len(dataset)
    # 切分之前的信息熵
    entropy = calculate_info_entropy(dataset)
    bestGain = 0.0
    feature = -1
    for i in range(n):
      	# 根据特征i切分
        split_data, _ = split_dataset(dataset, i)
        new_entropy = 0.0
        # 计算切分后的信息熵
        for data in split_data:
            prob = len(data) / m
            new_entropy += prob * calculate_info_entropy(data)
        # 获取信息增益
        gain = entropy - new_entropy
        if gain > bestGain:
            bestGain = gain
            feature = i
    return feature

# 决策树创建函数
def create_decision_tree(dataset, feature_names):
    dataset = np.array(dataset)
    counter = Counter(dataset[:, -1])
    # 如果数据集值剩下了一类,直接返回
    if len(counter) == 1:
        return dataset[0, -1]
    
    # 如果所有特征都已经切分完了,也直接返回
    if len(dataset[0]) == 1:
        return counter.most_common(1)[0][0]
    
    # 寻找最佳切分的特征
    fidx = choose_feature_to_split(dataset)
    fname = feature_names[fidx]
    
    node = {fname: {}}
    feature_names.remove(fname)
    
    # 递归调用,对每一个切分出来的取值递归建树
    split_data, vals = split_dataset(dataset, fidx)
    for data, val in zip(split_data, vals):
        node[fname][val] = create_decision_tree(data, feature_names[:])
    return node

# 决策树节点预测函数
def classify(node, feature_names, data):
  	# 获取当前节点判断的特征
    key = list(node.keys())[0]
    node = node[key]
    idx = feature_names.index(key)
    
    # 根据特征进行递归
    pred = None
    for key in node:
      	# 找到了对应的分叉
        if data[idx] == key:
          	# 如果再往下依然还有子树,那么则递归,否则返回结果
            if isinstance(node[key], dict):
                pred = classify(node[key], feature_names, data)
            else:
                pred = node[key]
                
    # 如果没有对应的分叉,则找到一个分叉返回
    if pred is None:
        for key in node:
            if not isinstance(node[key], dict):
                pred = node[key]
                break
    return pred

8.算法优缺点

 优点:小规模数据集有效

缺点

  • 处理连续变量不好
  • 类别比较多时,错误增加得比较快
  • 不能处理大量数据

9.算法优化

决策树算法是一种非常经典的算法,其训练过程中主要依靠获得数据间的熵及信息增益作为划分依据,分类效果较好。但一般情况下我们训练决策树均是在数据量较小的数据集进行,当训练分类器所用的训练数据足够大时,决策树会出现树身过高、拟合效果差等问题。因此,如何高效准确的构建决策树成为模式识别领域的一项研究热点。

使用增量训练的方式迭代训练决策树
融合Bagging与Boosting技术训练多棵决策树
对于波动不大、方差较小的数据集, 可以探寻一种比较稳定的分裂准则作为解决办法

总结

到此这篇关于Python机器学习算法之决策树算法的文章就介绍到这了,更多相关Python决策树算法内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python 时间处理datetime实例
Sep 06 Python
python中文乱码不着急,先看懂字节和字符
Dec 20 Python
python:pandas合并csv文件的方法(图书数据集成)
Apr 12 Python
python统计字母、空格、数字等字符个数的实例
Jun 29 Python
Python requests库用法实例详解
Aug 14 Python
python 文本单词提取和词频统计的实例
Dec 22 Python
Python小进度条显示代码
Mar 05 Python
python Pillow图像处理方法汇总
Oct 16 Python
python 两个一样的字符串用==结果为false问题的解决
Mar 12 Python
python是怎么被发明的
Jun 15 Python
几款Python编译器比较与推荐(小结)
Oct 15 Python
python3.9和pycharm的安装教程并创建简单项目的步骤
Feb 03 Python
Python爬虫基础之爬虫的分类知识总结
pytorch中的numel函数用法说明
May 13 #Python
pytorch损失反向传播后梯度为none的问题
如何使用Python实现一个简易的ORM模型
May 12 #Python
用python删除文件夹中的重复图片(图片去重)
May 12 #Python
Pyhton模块和包相关知识总结
python 下划线的多种应用场景总结
May 12 #Python
You might like
PHP程序员最常犯的11个MySQL错误小结
2010/11/20 PHP
php上传文件,创建递归目录的实例代码
2013/10/18 PHP
php 判断网页是否是utf8编码的方法
2014/06/06 PHP
超详细的php用户注册页面填写信息完整实例(附源码)
2015/11/17 PHP
php图片添加水印例子
2016/07/20 PHP
php版微信公众平台实现预约提交后发送email的方法
2016/09/26 PHP
搭建自己的PHP MVC框架详解
2017/08/16 PHP
Laravel框架Eloquent ORM修改数据操作示例
2019/12/03 PHP
如何让动态插入的javascript脚本代码跑起来。
2007/01/09 Javascript
for 循环性能比较 提高for循环的效率
2009/03/19 Javascript
javascript右下角弹层及自动隐藏(自己编写)
2013/11/20 Javascript
js使用removeChild方法动态删除div元素
2014/08/01 Javascript
浅谈JavaScript中的字符编码转换问题
2015/07/07 Javascript
用户代理字符串userAgent可实现的四个识别
2015/09/20 Javascript
谈谈jQuery Ajax用法详解
2015/11/27 Javascript
AngularJS 执行流程详细介绍
2016/08/18 Javascript
浅谈angularjs module返回对象的坑(推荐)
2016/10/21 Javascript
微信小程序城市定位的实现实例(获取当前所在国家城市信息)
2017/05/17 Javascript
Bootstrap Fileinput 4.4.7文件上传实例详解
2018/07/25 Javascript
Nuxt.js 数据双向绑定的实现
2019/02/17 Javascript
基于vue+uniapp直播项目实现uni-app仿抖音/陌陌直播室功能
2019/11/12 Javascript
jquery实现直播弹幕效果
2019/11/28 jQuery
node.js中process进程的概念和child_process子进程模块的使用方法示例
2020/02/11 Javascript
Python使用回溯法子集树模板获取最长公共子序列(LCS)的方法
2017/09/08 Python
python中强大的format函数实例详解
2018/12/05 Python
opencv调整图像亮度对比度的示例代码
2019/09/27 Python
css3.0 图形构成实例练习二
2013/03/19 HTML / CSS
大学生怎样进行自我评价
2013/12/07 职场文书
关于爱情的广播稿
2014/01/16 职场文书
家长学校实施方案
2014/03/15 职场文书
甜品蛋糕店创业计划书
2014/09/21 职场文书
党员个人剖析材料(四风问题)
2014/10/07 职场文书
2014年行政执法工作总结
2014/12/11 职场文书
办公室主任岗位竞聘书
2015/09/15 职场文书
Nginx访问日志及错误日志参数说明
2021/03/31 Servers
深入理解以DEBUG方式线程的底层运行原理
2021/06/21 Java/Android