机器学习决策树:提炼出分类器算法

时间:2022-05-06
本文章向大家介绍机器学习决策树:提炼出分类器算法,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

前面三天推送了决策树的基本原理和选择最佳分裂特征的几种公式,用到决策树一般都会出现过拟合问题,因此需要对决策树进行剪枝,阐述了常用的几种剪枝的方法(这些方法都出现在了sklearn的决策树构造函数的参数中),后面总结了sklearn调包分析用决策树做分类和回归的几个例子,下面通过一个简单的例子,提炼出构建一棵分类决策树的算法思想,进一步体会下决策树的分类原理。

1 数据集介绍

有一堆苹果,现在要分析下哪些苹果是好的,哪些是坏的,主要根据三个特征:大小,颜色,和形状进行区分。其中大小这个特征的取值:大和小;颜色特征的取值为:红色和青色;形状的取值有:圆形和非规则。现在拿到一批已检验的数据:

编号 大小 颜色 形状 好果

1 大 红色 圆形 是

2 大 红色 非规则 是

3 大 红色 圆形 是

4 大 青色 圆形 否

5 大 青色 非规则 否

6 小 红色 圆形 是

7 大 青色 非规则 否

8 小 红色 非规则 否

9 小 青色 圆形 否

10 小 青色 非规则 否

2 sklearn分类结果

调用sklearn的API直接对上述结果分类,编写代码如下:

import numpy as np
from sklearn import tree
import graphviz 
#大为1,红为1,圆形为1, 好果为1
data = np.array([[1,1,1,1],
        [1,1,0,1],
        [1,1,1,1],
        [1,0,1,0],
        [1,0,1,0],
        [0,1,1,1],
        [1,0,0,0],
        [0,1,0,0],
        [0,0,1,0],
        [0,0,0,0]])
clf = tree.DecisionTreeClassifier()
clf.fit(data[:,0:3],data[:,3])
dot_data = tree.export_graphviz(clf, out_file=None, 
                         feature_names=["magnitude","color","shape"],  
                         class_names=["bad","good"],  
                         filled=True, rounded=True,  
                         special_characters=True)  
graph = graphviz.Source(dot_data) 
graph

得的的决策树如下所示,根节点选择的特征为颜色,并且判断条件为小于0.5,可以看出它是取值[0,1]的中间值作为不等式的判断条件,基尼系数为0.48,也就是说鱼龙混杂度还是挺大的,可以看到此时value有6个坏果>4个好果,所以这个根节点的类别被标记为坏果。

接下来根据属性的取值,分裂根节点,如果颜色是青色的,则得到一个叶节点,此时的基尼系数为0,说明得到的这类别是纯的,都为坏果,样本个数为5个。如果颜色是红色的,得到一个非叶节点,此时的基尼系数变小了一点,说明获得了一些信息增益。

第二步,我们去掉一个颜色特征,从大小和形状中选择一个最佳的特征进行分裂,结果选择形状作为第二个分裂特征,这个节点对应的样本中:1个坏果,4个好果,所以此节点标记为好果,然后根据其取值:如果形状为圆形,则获得一个叶节点,其所有3个果子都是好果,如果形状不规则,则

第三步,又得到一个非叶节点,它的基尼系数变为0.5,但是数量只有2个,则此时拿掉上一个用过的形状特征后,目前只剩下一个特征:大小,小的为坏果,对应的样本数为1的左叶节点,右叶节点为大的果子,则为好果。

至此,决策树根据基尼系数判断最佳特征的构建过程结束。

3 提炼算法

设数据集为T,属性集为 A,则生成决策树的过程可以标记为 treeBuilder(T,A):

  1. 生成节点node
  2. 如果T中样本属于同一类别,则将node标记为叶节点,递归返回。
  3. 如果A为空,将其标记为叶节点,并且此叶节点的类型为T中类型做多的样本(这种情况:应该只有一种类型了吧,如第2节的最深一层的两个叶节点,此时的属性都已用完,各自都只剩下自己那一类了),递归返回。
  4. 从属性集A中选择最优化分属性A*,sklearn选择最优的划分属性所用的算法是优化的CART算法。
  5. 对A*的最优划分属性的几个取值依次遍历: 如果 A*j(第j个取值)对应的在T中的子集合T_Sub个数大于0,则: A = A-A* 递归调用 treeBuilder(T_Sub, A)

如果 T_Sub个数等于0,我们还需要添加一个节点吗?需要的,虽然在当前数据集上这个属性的样本点为空,并不代表在未来的测试集上这个属性对应的样本点还为空,这也是提高决策树的泛化能力的一个方法。

将这个节点为叶节点,并且这个叶节点的类型标记为T中样本点最多的那个类型,递归返回。

调用上述算法后,最终得到一个以node为根节点的决策树。

算法说明:

1. 递归返回的条件有3个:

  • T中样本属于同一类别;
  • 可用属性为0
  • 某个特征的第 j 个取值在T上的样本点个数为0

2. 需要理解递归返回的第3个条件,为什么训练集上出现个数为0时,还要构造一个叶节点,这是为了提高其泛化能力,并且此叶节点的类型标记为父节点的类型,这是把父节点的样本分布作为当前叶节点的先验分布。

让我们看一下远边优美的风景,放松一下吧!

4 总结

好了以上就是决策树的用于分类的总结,关于决策树做回归的问题,等以后对其更深刻地认识后再专门总结这块吧。

您知道先验概率和后验概率到底是怎么回事吗? 贝叶斯公式是怎么得来的? 它为什么能做分类呢?

明天通过2个易懂的来自于生活的小例子来阐述以上问题,欢迎您的关注!