当前位置:首页 > 技术 > 正文内容

机器学习--决策树分类算法及应用

Lotus2022-12-08 13:28技术

1. 决策树分类算法原理

1.1 概述

决策树(decision tree)——是一种被广泛使用的分类算法。

相比贝叶斯算法,决策树的优势在于构造过程不需要任何领域知识或参数设置

在实际应用中,对于探测式的知识发现,决策树更加适用

1.2 算法思想

通俗来说,决策树分类的思想类似于找对象。现想象一个女孩的母亲要给这个女孩介绍男朋友,于是有了下面的对话:

      女儿:多大年纪了?

      母亲:26。

      女儿:长的帅不帅?

      母亲:挺帅的。

      女儿:收入高不?

      母亲:不算很高,中等情况。

      女儿:是公务员不?

      母亲:是,在税务局上班呢。

      女儿:那好,我去见见。

这个女孩的决策过程就是典型的分类树决策。

实质:通过年龄、长相、收入和是否公务员对将男人分为两个类别:见和不见

假设这个女孩对男人的要求是:30岁以下、长相中等以上并且是高收入者或中等以上收入的公务员,那么这个可以用下图表示女孩的决策逻辑

机器学习--决策树分类算法及应用_信息熵

上图完整表达了这个女孩决定是否见一个约会对象的策略,其中:

绿色节点表示判断条件

橙色节点表示决策结果

箭头表示在一个判断条件在不同情况下的决策路径

图中红色箭头表示了上面例子中女孩的决策过程。

这幅图基本可以算是一颗决策树,说它“基本可以算”是因为图中的判定条件没有量化,如收入高中低等等,还不能算是严格意义上的决策树,如果将所有条件量化,则就变成真正的决策树了。

决策树分类算法的关键就是根据“先验数据”构造一棵最佳的决策树,用以预测未知数据的类别

决策树:是一个树结构(可以是二叉树或非二叉树)。其每个非叶节点表示一个特征属性上的测试,每个分支代表这个特征属性在某个值域上的输出,而每个叶节点存放一个类别。使用决策树进行决策的过程就是从根节点开始,测试待分类项中相应的特征属性,并按照其值选择输出分支,直到到达叶子节点,将叶子节点存放的类别作为决策结果。

1.3 决策树构造

1.3.1 决策树构造样例

假如有以下判断苹果好坏的数据样本:

样本    红     大      好苹果

0       1      1         1

1       1      0         1

2       0      1         0

3       0      0         0

样本中有2个属性,A0表示是否红苹果。A1表示是否大苹果。假如要根据这个数据样本构建一棵自动判断苹果好坏的决策树。

由于本例中的数据只有2个属性,因此,我们可以穷举所有可能构造出来的决策树,就2棵,如下图所示:

机器学习--决策树分类算法及应用_数据_02

显然左边先使用A0(红色)做划分依据的决策树要优于右边用A1(大小)做划分依据的决策树。

当然这是直觉的认知。而直觉显然不适合转化成程序的实现,所以需要有一种定量的考察来评价这两棵树的性能好坏。

决策树的评价所用的定量考察方法为计算每种划分情况的信息熵增益:

如果经过某个选定的属性进行数据划分后的信息熵下降最多,则这个划分属性是最优选择

1.3.2 属性划分选择(即构造决策树)的依据

熵:信息论的奠基人香农定义的用来信息量的单位。简单来说,熵就是“无序,混乱”的程度。

通过计算来理解:

1、原始样本数据的熵:

样例总数:4

好苹果:2

坏苹果:2

熵: -(1/2 * log(1/2) + 1/2 * log(1/2)) = 1

信息熵为1表示当前处于最混乱,最无序的状态。

2、两颗决策树的划分结果熵增益计算

l 树1先选A0作划分,各子节点信息熵计算如下:

0,1叶子节点有2个正例,0个负例。信息熵为:e1 = -(2/2 * log(2/2) + 0/2 * log(0/2)) = 0。

2,3叶子节点有0个正例,2个负例。信息熵为:e2 = -(0/2 * log(0/2) + 2/2 * log(2/2)) = 0。

因此选择A0划分后的信息熵为每个子节点的信息熵所 zhan bi  zhong 的加权和:

机器学习--决策树分类算法及应用_决策树_03

选择A0做划分的信息熵增益G(S, A0)=S - E = 1 - 0 = 1.

事实上,决策树叶子节点表示已经都属于相同类别,因此信息熵一定为0。

l 树2先选A1作划分,各子节点信息熵计算如下:

0,2子节点有1个正例,1个负例。信息熵为:e1 = -(1/2 * log(1/2) + 1/2 * log(1/2)) = 1。

1,3子节点有1个正例,1个负例。信息熵为:e2 = -(1/2 * log(1/2) + 1/2 * log(1/2)) = 1。

因此选择A1划分后的信息熵为每个子节点的信息熵所zhan bi  zhong的加权和

机器学习--决策树分类算法及应用_决策树_04

也就是说分了跟没分一样!

选择A1做划分的信息熵增益G(S, A1)=S - E = 1 - 1 = 0.

因此,每次划分之前,我们只需要计算出信息熵增益最大的那种划分即可。


1.4 算法要点

1.4.1、指导思想

经过决策属性的划分后,数据的无序度越来越低,也就是信息熵越来越小

1.4.2 算法实现

梳理出数据中的属性

比较按照某特定属性划分后的数据的信息熵增益,选择信息熵增益最大的那个属性作为第一划分依据,然后继续选择第二属性,以此类推

2. 决策树分类算法Python实战

2.1 案例需求

我们的任务就是训练一个决策树分类器,输入身高和体重,分类器能给出这个人是胖子还是瘦子。

所用的训练数据如下,这个数据一共有10个样本,每个样本有2个属性,分别为身高和体重,第三列为类别标签,表示“胖”或“瘦”。该数据保存在1.txt中。

1.5 50 thin

1.5 60 fat

1.6 40 thin

1.6 60 fat

1.7 60 thin

1.7 80 fat

1.8 60 thin

1.8 90 fat

1.9 70 thin

1.9 80 fat

2.2 模型分析

决策树对于“是非”的二值逻辑的分枝相当自然。而在本数据集中,身高与体重是连续值怎么办呢?

虽然麻烦一点,不过这也不是问题,只需要找到将这些连续值划分为不同区间的中间点,就转换成了二值逻辑问题。

本例决策树的任务是找到身高、体重中的一些临界值,按照大于或者小于这些临界值的逻辑将其样本两两分类,自顶向下构建决策树。

2.3 python实现

使用python的机器学习库,实现起来相当简单和优雅

​# -*- coding: utf-8 -*-

import numpy as np

import scipy as sp

from sklearn import tree

from sklearn.metrics import precision_recall_curve

from sklearn.metrics import classification_report

from sklearn.cross_validation import train_test_split



''' 数据读入 '''

data   = []

labels = []

with open("d:\\python\\ml\\data\\1.txt") as ifile:

    for line in ifile:

        tokens = line.strip().split(' ')

        data.append([float(tk) for tk in tokens[:-1]])

        labels.append(tokens[-1])

x = np.array(data)

labels = np.array(labels)

y = np.zeros(labels.shape)



''' 标签转换为0/1 '''

y[labels=='fat']=1


''' 拆分训练数据与测试数据 '''

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2)


''' 使用信息熵作为划分标准,对决策树进行训练 '''

clf = tree.DecisionTreeClassifier(criterion='entropy')

print(clf)

clf.fit(x_train, y_train)


''' 把决策树结构写入文件 '''

with open("tree.dot", 'w') as f:

      f = tree.export_graphviz(clf, out_file=f)


''' 系数反映每个特征的影响力。越大表示该特征在分类中起到的作用越大 '''

print(clf.feature_importances_)


'''测试结果的打印'''

answer = clf.predict(x_train)

print(x_train)

print(answer)

print(y_train)

print(np.mean( answer == y_train))


'''准确率与召回率'''

precision, recall, thresholds = precision_recall_curve(y_train, clf.predict(x_train))

answer = clf.predict_proba(x)[:,1]

print(classification_report(y, answer, target_names = ['thin', 'fat']))​

这时候会输出

[ 0.2488562  0.7511438]

array([[  1.6,  60. ],

       [  1.7,  60. ],

       [  1.9,  80. ],

       [  1.5,  50. ],

       [  1.6,  40. ],

       [  1.7,  80. ],

       [  1.8,  90. ],

       [  1.5,  60. ]])

array([ 1.,  0.,  1.​,  0.,  0.,  1.,  1.,  1.])

array([ 1.,  0.,  1.,  0.,  0.,  1.,  1.,  1.])

1.0


             precision    recall  f1-score   support

       thin       0.83      1.00      0.91         5

        fat        1.00     0.80      0.89         5

avg / total       1.00      1.00      1.00         8


array([ 0.,  1.,  0.,  1.,  0.,  1.,  0.,  1., 0.,  0.])

array([ 0.,  1.,  0.,  1.,  0.,  1.,  0.,  1., 0.,  1.])


可以看到,对训练过的数据做测试,准确率是100%。但是最后将所有数据进行测试,会出现1个测试样本分类错误。


说明本例的决策树对训练集的规则吸收的很好,但是预测性稍微差点。​

2.4 决策树的保存

一棵决策树的学习训练是非常耗费运算时间的,因此,决策树训练出来后,可进行保存,以便在预测新数据时只需要直接加载训练好的决策树即可

本案例的代码中已经决策树的结构写入了tree.dot中。打开该文件,很容易画出决策树,还可以看到决策树的更多分类信息。

本例的tree.dot如下所示:

​digraph Tree {

0 [label="X[1]<= 55.0000\nentropy = 0.954434002925\nsamples = 8", shape="box"] ;

1 [label="entropy = 0.0000\nsamples = 2\nvalue = [ 2.  0.]", shape="box"] ;

0 -> 1 ;

2 [label="X[1]<= 70.0000\nentropy = 0.650022421648\nsamples = 6", shape="box"] ;

0 -> 2 ;

3 [label="X[0]<= 1.6500\nentropy = 0.918295834054\nsamples = 3", shape="box"] ;

2 -> 3 ;

4 [label="entropy = 0.0000\nsamples = 2\nvalue = [ 0.  2.]", shape="box"] ;

3 -> 4 ;

5 [label="entropy = 0.0000\nsamples = 1\nvalue = [ 1.  0.]", shape="box"] ;

3 -> 5 ;

6 [label="entropy = 0.0000\nsamples = 3\nvalue = [ 0.  3.]", shape="box"] ;

2 -> 6 ;

}​

根据这个信息,决策树应该长的如下这个样子:

机器学习--决策树分类算法及应用_数据_05


原文链接

扫描二维码推送至手机访问。

版权声明:本文来源于网络,仅供学习,如侵权请联系站长删除。

本文链接:https://news.layui.org.cn/post/1106.html

分享给朋友:

“机器学习--决策树分类算法及应用” 的相关文章

你看好云原生吗?

我理解的云原生是一种思想。目前为止,再稍具体一点就是一种构建和运行应用程序的方法 ,是一套技术体系和方法论。 目前来看,互联网技术领域没有那么粗放了,可以看成从”一堆砖头“变成了码的整齐的砖头,各种人物资源、空间利用率更高了。 云原生还在不断的发展,一年前我看中了云原生的发展方向并展开了一系列的学习,目前工作中也只是稍有涉及,并不是主要工作,我还是非常期望可以从事云原生工作的,下面罗列一下云原...

[s905l3]性价比神机mgv3000全网首拆,刷armbian实现更多价值!

最近花55淘了一台mgv3000,s905l3,2+16G带蓝牙,真的性价比没得说 S905L3 工艺28nm差于s905l3a 主频1.9Ghz,超频可以达到2Ghz,GPU是Mail450,当服务器跑ha,nas什么都是很不错的。 而且还自带蓝牙,总体性价比比s905l3a系列高多了 按我的方法可以启动,网卡没有问题,但是目前没有显示,没有蓝牙。 等之后我有时间了照着安卓的dtb改一改也许会解...

源码学习之MyBatis的底层查询原理

导读 本文通过MyBatis一个低版本的bug(3.4.5之前的版本)入手,分析MyBatis的一次完整的查询流程,从配置文件的解析到一个查询的完整执行过程详细解读MyBatis的一次查询流程,通过本文可以详细了解MyBatis的一次查询过程。在平时的代码编写中,发现了MyBatis一个低版本的bug(3.4.5之前的版本),由于现在很多工程中的版本都是低于3.4.5的,因此在这里用一个简单的例...

路由基础之中级网络工程师企业网络架构BGP​

路由基础之中级网络工程师企业网络架构BGP​ 原理概述:​ 防火墙(英语:Firewall)技术是通过有机结合各类用于安全管理与筛选的软件和硬件设备,帮助计算机网络于其内、外网之间构建一道相对隔绝的保护屏障,以保护用户资料与信息安全性的一种技术。​ 防火墙技术的功能主要在于及时发现并处理计算机网络运行时可能存在的安全风险、数据传输等问题,其中处理措施包括隔离与保护,同时可对计算机网络安全当中的各...

一次服务器被入侵的处理过程分享

下文中的,给文件和目录加锁,是指给文件和目录增加了一些属性,只读等。 chattr +ia 目录 一、服务器入侵现象 二、服务器排查和处理 2.1、服务器被入侵的可能原因 2.2、排查和处理步骤 三、本次入侵需要带来启示的点 四、本次服务器被入侵的一些启示 一、服务器入侵现象 近期有一个朋友的服务器(自己做了网站)好像遭遇了入侵,具体现象是: 服务器 CPU 资源长期 1...

基于.NetCore开发博客项目 StarBlog - (18) 实现本地Typora文章打包上传

前言 九月太忙,只更新了三篇文章,本来这个功能是从九月初就开始做的,结果一直拖到现在国庆假期才有时间完善并且写文章~ 之前我更新了几篇关于 Python 的文章,有朋友留言问是不是不更新 .Net 了,那肯定不能啊,我只能说「我 全 都 要」,所以我反手就更新了一篇Asp-Net-Core开发笔记。 然后顺便立个Flag:今年底前完成StarBlog系列文章的主体部分(即API开发+后台前端开发,...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。