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计算圆周长、面积、球体体积并画出圆
Apr 08 Python
python使用百度翻译进行中翻英示例
Apr 14 Python
python读写二进制文件的方法
May 09 Python
Python基于回溯法子集树模板解决数字组合问题实例
Sep 02 Python
python方向键控制上下左右代码
Jan 20 Python
Python 监测文件是否更新的方法
Jun 10 Python
Python中list的交、并、差集获取方法示例
Aug 01 Python
详解如何用TensorFlow训练和识别/分类自定义图片
Aug 05 Python
Python3操作Excel文件(读写)的简单实例
Sep 02 Python
Numpy与Pytorch 矩阵操作方式
Dec 27 Python
基于tensorflow for循环 while循环案例
Jun 30 Python
Python学习之time模块的基本使用
Jan 17 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运行速度的一些小技巧分享
2012/07/03 PHP
获取php页面执行时间,数据库读写次数,函数调用次数等(THINKphp)
2013/06/03 PHP
JavaScript 字符串连接性能优化
2008/12/20 Javascript
用js实现的模拟jquery的animate自定义动画(2.5K)
2010/07/20 Javascript
JavaScript传递变量: 值传递?引用传递?
2011/02/22 Javascript
jQuery遍历Form示例代码
2013/09/03 Javascript
Avalon中文长字符截取、关键字符隐藏、自定义过滤器
2016/05/18 Javascript
JavaScript事件学习小结(一)事件流
2016/06/09 Javascript
jquery 动态合并单元格的实现方法
2016/08/26 Javascript
javascript设计模式之中介者模式学习笔记
2017/02/15 Javascript
详解vue.js2.0父组件点击触发子组件方法
2017/05/10 Javascript
Ionic3实现图片瀑布流布局
2017/08/09 Javascript
Vue.js递归组件实现组织架构树和选人功能
2019/07/04 Javascript
Vue发布项目实例讲解
2019/07/17 Javascript
vue通过数据过滤实现表格合并
2020/11/30 Javascript
[03:00]2014DOTA2国际邀请赛 Titan淘汰潸然泪下Ohaiyo专访
2014/07/15 DOTA
Python 文件操作实现代码
2009/10/07 Python
python网络编程实例简析
2014/09/26 Python
python绘图方法实例入门
2015/05/19 Python
Python 实现使用dict 创建二维数据、DataFrame
2018/04/13 Python
python爬取cnvd漏洞库信息的实例
2019/02/14 Python
Python+OpenCV+pyQt5录制双目摄像头视频的实例
2019/06/28 Python
Python threading.local代码实例及原理解析
2020/03/16 Python
浅谈在JupyterNotebook下导入自己的模块的问题
2020/04/16 Python
尼克松手表官网:Nixon手表
2019/03/17 全球购物
出国留学自荐信
2013/10/25 职场文书
医学检验专业大学生求职信
2013/11/18 职场文书
金融专业个人求职信范文
2013/11/28 职场文书
业务员的岗位职责
2014/03/15 职场文书
统计专业自荐书
2014/07/06 职场文书
防灾减灾宣传标语
2014/10/07 职场文书
本科毕业论文致谢怎么写
2015/05/14 职场文书
2016保送生自荐信范文
2016/01/29 职场文书
个人落户申请书怎么写?
2019/06/28 职场文书
创业计划书之冷饮店
2019/09/27 职场文书
用Python监控你的朋友都在浏览哪些网站?
2021/05/27 Python