机器学习算法(四) 决策树算法

前言

决策树是一种用于对实例进行分类的树形结构。决策树由节点(Node)和有向边(Directed Edge)组成。节点的类型有两种:内部节点和叶子节点。其中,内部节点表示一个特征或属性的测试条件(用于分开具有不同特性的记录),叶子节点表示一个分类。决策树既能够用于分类,也能用于回归。本文主要讲解分类决策树。

决策树模型呈树形结构,在分类问题中,表示基于特征对实例进行分类的过程。正如文章题目所言,我们可以认为决策树算法是 IF-THEN 规则的集合,也可以认为是定义在特征空间与类空间上的条件概率分布。

决策树算法的主要优点是模型具有可读性分类速度快。决策树学习通常分为三个步骤:特征选择决策树生成决策树的剪枝

决策树模型

决策树模型是一种描述对实例进行分类的树形结构。一旦决策树构建完成,那么利用决策树进行分类预测是非常简单的:首先,从根节点开始,对实例的某一特征进行对比测试,根据测试结果将该实例分配到相应的子节点上;这时,每一个子节点对应着该特征的一个取值(或取值范围)。如此递归地对实例进行测试,直至该实例被分配到叶子节点,最后将实例分配到叶子节点所代表的类中。

由上图可知,我们可以将决策树看成是一个 IF-THEN 规则的集合。我们可以这样理解这句话:对于决策树中的非叶子节点,我们可以将其看成是一个规则的条件;叶子节点可以看成是规则的最终结论;而决策树中的边,我们可以将其理解成规则划分的过程。决策树的路径或其对应的 IF-THEN 规则集合具有一个十分重要的性质:互斥且完备。也就是说,每一个样本空间上的实例都可以被一条或一条规则链所覆盖,而且只被一条路径或一条规则链所覆盖。

熵与信息增益

由前言部分我们知道,决策树学习过程的第一步就是“特征选择”。所谓的特征选择其实是分两个步骤的:

  1. 首先,需要选择对训练数据具有最大分类能力的特征进行树的叶子节点的分裂;
  2. 然后,选择该特征合适的分裂点进行分裂。

这里有一点需要解释下,以离散型变量为例,寻找特征分裂点的方法也不是固定的:对于 ID3 和 C4.5 等传统决策树算法使用的是将所有特征值作为分支,生成多叉树结构,这时我们就不需要做任何选择了——例如对于后续的 XGBoost 的单棵树全部采用的是二叉树的结构,此时就必须采用合适的算法进行特征分裂点的选择,将节点上的样本分到不同的两个子节点上。

由以上解释我们知道对于本节重点介绍的 ID3 和 C4.5 算法来说,我们只需要第一步,也就是选择对训练数据具有最大的分类能力的特征。那么如何判断一个特征对训练数据的分类能力大小呢?为此我们引出本小节的目标:熵与信息增益


image.png

image.png

信息增益
image.png

特征选择

image.png

决策树生成

image.png

ID3 算法

有了上述知识的铺垫,ID3 算法的过程就十分简单了。它的核心是递归的构建决策树,递归的过程中在每个节点上应用信息增益准则选择特征,直至满足递归停止条件(所有特征的信息增益都很小或者没有特征可以选择)。
image.png
C4.5 算法

前面我们讲过了,其实 C4.5 算法和 ID3 算法基本上完全一致,只是特征选择时的选择方法从 ID3 依据的信息增益改成了信息增益比了。因此,本节讲述清除信息增益比的概念就可以了,C4.5 算法生成决策树的详细算法过程参见 ID3 算法描述就可以了。

以信息增益作为划分训练数据集 D 的特征,会倾向于选择特征值较多的特征的问题。而使用信息增益比(Information Gain Ratio) 就可以解决这个问题。
image.png

决策树的剪枝策略

我们都知道决策树的生成算法递归得构建决策树,直到不能继续构建为止。因此,这样产生的决策树很容易过分的学习训练样本,使得它对未知的测试数据的分类效果比较差,即这样产生的决策树很容易过拟合。过拟合的原因在于我们构建的决策树过分复杂,导致其过多地学习训练样本的分布,而对未知样本的学习泛化能力较弱。解决这个问题的方法就是简化已生成的决策树,使其变得更简单。

在决策树学习的过程中将已经生成的决策树进行简化的过程称作“剪枝”。也就是说,我们可以将决策树中划分的过细的叶子节点剪去,退回到其父节点成为新的叶子节点,使得新的决策树变得简单,并且能够在未知的测试数据的预测上取得更好的分类结果。

剪枝分为预剪枝和后剪枝:

预剪枝

  1. 每一个结点所包含的最小样本数目,例如10,则该结点总样本数小于10时,则不再分;
  2. 指定树的高度或者深度,例如树的最大深度为4;
  3. 指定结点的熵小于某个值,不再划分。

后剪枝
总体思路为:由完全树 T0 开始,剪枝部分结点得到 T1,再次剪枝部分结点得到 T2……直到剩下树根的树 Tk;在验证数据集上对这 k 个树分别评价,选择损失函数最小的树 Ta。

决策树分类实战

from sklearn import tree
from sklearn import datasets
from sklearn.model_selection import train_test_split

# 加载iris数据集
iris = datasets.load_iris()

X = iris.data
y = iris.target

print('Sample num: ', len(y))

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 模型初始化并训练
clf = tree.DecisionTreeClassifier()
clf.fit(X_train, y_train)

# 预测结果
ans = clf.predict(X_test)
# 计算准确率
cnt = 0
for i in range(len(y_test)):
    if ans[i] - y_test[i] < 1e-1:
        cnt += 1
    # print(ans[i], ' ', y_test[i])
print("Accuracy: ", (cnt * 100.0 / len(y_test)),"%")

运行结果

Sample num:  150
Accuracy:  100.0 %

猜你喜欢

转载自blog.csdn.net/datawhale/article/details/81205024