Python机器学习之决策树

一、要求

二、原理

决策树是一种类似于流程图的结构,其中每个内部节点代表一个属性上的“测试”,每个分支代表测试的结果,每个叶节点代表一个测试结果。类标签(在计算所有属性后做出的决定)。从根到叶的路径代表分类规则。
决策树学习的目的是为了产生一棵泛化能力强,即处理未见示例能力强的决策树。因此如何构建决策树,是后续预测的关键!而构建决策树,就需要确定类标签判断的先后,其决定了构建的决策树的性能。决策树的分支节点应该尽可能的属于同一类别,即节点的“纯度”要越来越高,只有这样,才能最佳决策。

经典的属性划分方法:

  • 信息增益
  • 增益率
  • 基尼指数

本次实验采用了信息增益,因此下面只对信息增益进行介绍。

三、信息增益的计算方法

其中D为样本集合,a为样本集合中的属性,Dv表示D样本集合中a属性为v的样本集合。

Ent(x)函数是计算信息熵,表示的是样本集合的纯度信息,信息熵的计算方法如下:

其中pk表示样本中最终结果种类中其中一个类别所占的比例,比如有10个样本,其中5个好,5个不好,则其中p1 = 5/10, p2 = 5/10。

一般而言,信息增益越大,则意味着使用属性α来进行划分所获得的“纯度提升”越大,因此在选择属性节点的时候优先选择信息增益高的属性!

四、实现过程

本次设计用到了pandas和numpy库,主要利用它们来对数据进行快速的处理和使用。
首先将数据读入:

可以看到数据集的标签是瓜的不同的属性,而表格中的数据就是不同属性下的不同的值等。

if(len(set(D.好瓜)) == 1):
        #标记返回
        return D.好瓜.iloc[0]
    elif((len(A) == 0) or Check(D, A[:-1])):
        #选择D中结果最多的为标记
        cnt = D.groupby('好瓜').size()
        maxValue = cnt[cnt == cnt.max()].index[0]
        return maxValue
    else:
        A1 = copy.deepcopy(A)
        attr = Choose(D, A1[:-1])
        tree = {attr:{}}
        for value in set(D[attr]):
            tree[attr][value] = TreeGen(D[D[attr] == value], A1)
    return tree

TreeGen函数是生成树主函数,通过对它的递归调用,返回下一级树结构(字典)来完成生成决策树。

在生成树过程中,有二个终止迭代的条件,第一个就是当输入数据源D的所有情况结果都相同,那么将这个结果作为叶节点返回;第二个就是当没有属性可以再往下分,或者D中的样本在A所有属性下面的值都相同,那么就将D的所有情况中结果最多的作为叶节点返回。

其中Choose(D:pd.DataFrame, A:list)函数是选择标签的函数,其根据输入数据源和剩下的属性列表算出对应标签信息增益,选择能使信息增益最大的标签返回

def Choose(D:pd.DataFrame, A:list):
    result = 0.0
    resultAttr = ''
    for attr in A:
        tmpVal = CalcZengYi(D, attr)
        if(tmpVal > result):
            resultAttr = attr
            result = tmpVal
    A.remove(resultAttr)
    return resultAttr

最后是结果:

{‘纹理': {‘稍糊': {‘触感': {‘硬滑': ‘否', ‘软粘': ‘是'}}, ‘清晰': {‘根蒂': {‘硬挺': ‘否', ‘蜷缩': ‘是', ‘稍蜷': {‘色泽': {‘青绿': ‘是', ‘乌黑': {‘触感': {‘硬滑': ‘是', ‘软粘': ‘否'}}}}}}, ‘模糊': ‘否'}}

绘图如下:

五、程序

主程序

#!/usr/bin/python3
# -*- encoding: utf-8 -*-
'''
@Description:决策树:
@Date     :2021/04/25 15:57:14
@Author      :willpower
@version      :1.0
'''
import pandas as pd
import numpy as np
import treeplot
import copy
import math
"""
@description  :计算熵值
---------
@param  :输入为基本pandas类型dataFrame,其中输入最后一行为实际结果
-------
@Returns  :返回熵值,类型为浮点型
-------
"""
def CalcShang(D:pd.DataFrame):
    setCnt = D.shape[0]
    result = 0.0
    # for i in D.groupby(D.columns[-1]).size().index:
    #遍历每一个值
    for i in set(D[D.columns[-1]]):
        #获取该属性下的某个值的次数
        cnt = D.iloc[:,-1].value_counts()[i]
        result = result + (cnt/setCnt)*math.log(cnt/setCnt, 2)
    return (-1*result)
"""
@description  :计算增益
---------
@param  :输入为DataFrame数据源,然后是需要计算增益的属性值
-------
@Returns  :返回增益值,浮点型
-------
"""
def CalcZengYi(D:pd.DataFrame, attr:str):
    sumShang = CalcShang(D)
    setCnt = D.shape[0]
    result = 0.0
    valus = D.groupby(attr).size()
    for subVal in valus.index:
        result = result + (valus[subVal]/setCnt)*CalcShang(D[D[attr] == subVal])
    return sumShang - result
"""
@description  :选择最佳的属性
---------
@param  :输入为数据源,以及还剩下的属性列表
-------
@Returns  :返回最佳属性
-------
"""
def Choose(D:pd.DataFrame, A:list):
    result = 0.0
    resultAttr = ''
    for attr in A:
        tmpVal = CalcZengYi(D, attr)
        if(tmpVal > result):
            resultAttr = attr
            result = tmpVal
    A.remove(resultAttr)
    return resultAttr
"""
@description  :检查数据在每一个属性下面的值是否相同
---------
@param  :输入为DataFrame以及剩下的属性列表
-------
@Returns  :返回bool值,相同返回1,不同返回0
-------
"""
def Check(D:pd.DataFrame, A:list):
    for i in A:
        if(len(set(D[i])) != 1):
            return 0
    return 1
"""
@description  :生成树主函数
---------
@param  :数据源DataFrame以及所有类型
-------
@Returns  :返回生成的字典树
-------
"""
def TreeGen(D:pd.DataFrame, A:list):
    if(len(set(D.好瓜)) == 1):
        #标记返回
        return D.好瓜.iloc[0]
    elif((len(A) == 0) or Check(D, A[:-1])):
        #选择D中结果最多的为标记
        cnt = D.groupby('好瓜').size()
        #找到结果最多的结果
        maxValue = cnt[cnt == cnt.max()].index[0]
        return maxValue
    else:
        A1 = copy.deepcopy(A)
        attr = Choose(D, A1[:-1])
        tree = {attr:{}}
        for value in set(D[attr]):
            tree[attr][value] = TreeGen(D[D[attr] == value], A1)
    return tree
"""
@description  :验证集
---------
@param  :输入为待验证的数据(最后一列为真实结果)以及决策树模型
-------
@Returns  :无
-------
"""
def Test(D:pd.DataFrame, model:dict):
    for i in range(D.shape[0]):
            data = D.iloc[i]
            subModel = model
            while(1):
                attr = list(subModel)[0]
                subModel = subModel[attr][data[attr]]
                if(type(subModel).__name__ != 'dict'):
                    print(subModel, end='')
                    break
    print('')
name = ['色泽', '根蒂', '敲声', '纹理', '脐部', '触感', '好瓜']
df = pd.read_csv('./savedata.txt', names=name)
# CalcZengYi(df, '色泽')
resultTree = TreeGen(df, name)
print(resultTree)
# print(df[name[:-1]])
Test(df[name[:-1]], resultTree)
treeplot.plot_model(resultTree,"resultTree.gv")

绘图程序

from graphviz import Digraph

def plot_model(tree, name):
    g = Digraph("G", filename=name, format='png', strict=False)
    first_label = list(tree.keys())[0]
    g.node("0", first_label)
    _sub_plot(g, tree, "0")
    g.view()
root = "0"

def _sub_plot(g, tree, inc):
    global root

    first_label = list(tree.keys())[0]
    ts = tree[first_label]
    for i in ts.keys():
        if isinstance(tree[first_label][i], dict):
            root = str(int(root) + 1)
            g.node(root, list(tree[first_label][i].keys())[0])
            g.edge(inc, root, str(i))
            _sub_plot(g, tree[first_label][i], root)
        else:
            root = str(int(root) + 1)
            g.node(root, tree[first_label][i])
            g.edge(inc, root, str(i))

./savedata.txt

青绿,蜷缩,浊响,清晰,凹陷,硬滑,是
乌黑,蜷缩,沉闷,清晰,凹陷,硬滑,是
乌黑,蜷缩,浊响,清晰,凹陷,硬滑,是
青绿,蜷缩,沉闷,清晰,凹陷,硬滑,是
浅白,蜷缩,浊响,清晰,凹陷,硬滑,是
青绿,稍蜷,浊响,清晰,稍凹,软粘,是
乌黑,稍蜷,浊响,稍糊,稍凹,软粘,是
乌黑,稍蜷,浊响,清晰,稍凹,硬滑,是
乌黑,稍蜷,沉闷,稍糊,稍凹,硬滑,否
青绿,硬挺,清脆,清晰,平坦,软粘,否
浅白,硬挺,清脆,模糊,平坦,硬滑,否
浅白,蜷缩,浊响,模糊,平坦,软粘,否
青绿,稍蜷,浊响,稍糊,凹陷,硬滑,否
浅白,稍蜷,沉闷,稍糊,凹陷,硬滑,否
乌黑,稍蜷,浊响,清晰,稍凹,软粘,否
浅白,蜷缩,浊响,模糊,平坦,硬滑,否
青绿,蜷缩,沉闷,稍糊,稍凹,硬滑,否

六、遇到的问题

graphviz Not a directory: ‘dot'

解决办法

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

(0)

相关推荐

  • Python机器学习之Kmeans基础算法

    一.K-means基础算法简介 k-means算法是一种聚类算法,所谓聚类,即根据相似性原则,将具有较高相似度的数据对象划分至同一类簇,将具有较高相异度的数据对象划分至不同类簇.聚类与分类最大的区别在于,聚类过程为无监督过程,即待处理数据对象没有任何先验知识,而分类过程为有监督过程,即存在有先验知识的训练数据集. 二.算法过程 K-means中心思想:事先确定常数K,常数K意味着最终的聚类(或者叫簇)类别数,首先随机选定初始点为质心,并通过计算每一个样本与质心之间的相似度(这里为欧式距离),将样

  • python机器学习之神经网络

    手写数字识别算法 import pandas as pd import numpy as np from sklearn.neural_network import MLPRegressor #从sklearn的神经网络中引入多层感知器 data_tr = pd.read_csv('BPdata_tr.txt') # 训练集样本 data_te = pd.read_csv('BPdata_te.txt') # 测试集样本 X=np.array([[0.568928884039633],[0.37

  • Python机器学习之决策树算法

    一.决策树原理 决策树是用样本的属性作为结点,用属性的取值作为分支的树结构. 决策树的根结点是所有样本中信息量最大的属性.树的中间结点是该结点为根的子树所包含的样本子集中信息量最大的属性.决策树的叶结点是样本的类别值.决策树是一种知识表示形式,它是对所有样本数据的高度概括决策树能准确地识别所有样本的类别,也能有效地识别新样本的类别. 决策树算法ID3的基本思想: 首先找出最有判别力的属性,把样例分成多个子集,每个子集又选择最有判别力的属性进行划分,一直进行到所有子集仅包含同一类型的数据为止.最后

  • Python机器学习之决策树算法实例详解

    本文实例讲述了Python机器学习之决策树算法.分享给大家供大家参考,具体如下: 决策树学习是应用最广泛的归纳推理算法之一,是一种逼近离散值目标函数的方法,在这种方法中学习到的函数被表示为一棵决策树.决策树可以使用不熟悉的数据集合,并从中提取出一系列规则,机器学习算法最终将使用这些从数据集中创造的规则.决策树的优点为:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据.缺点为:可能产生过度匹配的问题.决策树适于处理离散型和连续型的数据. 在决策树中最重要的就是如何选取

  • python机器学习实现决策树

    本文实例为大家分享了python机器学习实现决策树的具体代码,供大家参考,具体内容如下 # -*- coding: utf-8 -*- """ Created on Sat Nov 9 10:42:38 2019 @author: asus """ """ 决策树 目的: 1. 使用决策树模型 2. 了解决策树模型的参数 3. 初步了解调参数 要求: 基于乳腺癌数据集完成以下任务: 1.调整参数criterion,使

  • Python机器学习算法库scikit-learn学习之决策树实现方法详解

    本文实例讲述了Python机器学习算法库scikit-learn学习之决策树实现方法.分享给大家供大家参考,具体如下: 决策树 决策树(DTs)是一种用于分类和回归的非参数监督学习方法.目标是创建一个模型,通过从数据特性中推导出简单的决策规则来预测目标变量的值. 例如,在下面的例子中,决策树通过一组if-then-else决策规则从数据中学习到近似正弦曲线的情况.树越深,决策规则越复杂,模型也越合适. 决策树的一些优势是: 便于说明和理解,树可以可视化表达: 需要很少的数据准备.其他技术通常需要

  • 机器学习python实战之决策树

    决策树原理:从数据集中找出决定性的特征对数据集进行迭代划分,直到某个分支下的数据都属于同一类型,或者已经遍历了所有划分数据集的特征,停止决策树算法. 每次划分数据集的特征都有很多,那么我们怎么来选择到底根据哪一个特征划分数据集呢?这里我们需要引入信息增益和信息熵的概念. 一.信息增益 划分数据集的原则是:将无序的数据变的有序.在划分数据集之前之后信息发生的变化称为信息增益.知道如何计算信息增益,我们就可以计算根据每个特征划分数据集获得的信息增益,选择信息增益最高的特征就是最好的选择.首先我们先来

  • python机器学习之线性回归详解

    一.python机器学习–线性回归 线性回归是最简单的机器学习模型,其形式简单,易于实现,同时也是很多机器学习模型的基础. 对于一个给定的训练集数据,线性回归的目的就是找到一个与这些数据最吻合的线性函数. 二.OLS线性回归 2.1 Ordinary Least Squares 最小二乘法 一般情况下,线性回归假设模型为下,其中w为模型参数 线性回归模型通常使用MSE(均方误差)作为损失函数,假设有m个样本,均方损失函数为:(所有实例预测值与实际值误差平方的均值) 由于模型的训练目标为找到使得损

  • python机器学习之决策树分类详解

    决策树分类与上一篇博客k近邻分类的最大的区别就在于,k近邻是没有训练过程的,而决策树是通过对训练数据进行分析,从而构造决策树,通过决策树来对测试数据进行分类,同样是属于监督学习的范畴.决策树的结果类似如下图: 图中方形方框代表叶节点,带圆边的方框代表决策节点,决策节点与叶节点的不同之处就是决策节点还需要通过判断该节点的状态来进一步分类. 那么如何通过训练数据来得到这样的决策树呢? 这里涉及要信息论中一个很重要的信息度量方式,香农熵.通过香农熵可以计算信息增益. 香农熵的计算公式如下: p(xi)

  • python机器学习理论与实战(二)决策树

    决策树也是有监督机器学习方法. 电影<无耻混蛋>里有一幕游戏,在德军小酒馆里有几个人在玩20问题游戏,游戏规则是一个设迷者在纸牌中抽出一个目标(可以是人,也可以是物),而猜谜者可以提问题,设迷者只能回答是或者不是,在几个问题(最多二十个问题)之后,猜谜者通过逐步缩小范围就准确的找到了答案.这就类似于决策树的工作原理.(图一)是一个判断邮件类别的工作方式,可以看出判别方法很简单,基本都是阈值判断,关键是如何构建决策树,也就是如何训练一个决策树. (图一) 构建决策树的伪代码如下: Check i

随机推荐