系列文章目录及链接
上篇:机器学习(五) -- 监督学习(2) -- 朴素贝叶斯
下篇:机器学习(五) -- 监督学习(4) -- 集成学习方法-随机森林
前言
tips:标题前有“***”的内容为补充内容,是给好奇心重的宝宝看的,可自行跳过。文章内容被“
文章内容”删除线标记的,也可以自行跳过。“!!!”一般需要特别注意或者容易出错的地方。
本系列文章是作者边学习边总结的,内容有不对的地方还请多多指正,同时本系列文章会不断完善,每篇文章不定时会有修改。
由于作者时间不算富裕,有些内容的《算法实现》部分暂未完善,以后有时间再来补充。见谅!
文中为方便理解,会将接口在用到的时候才导入,实际中应在文件开始统一导入。
一、决策树通俗理解及定义
1、什么叫决策树(What)
决策树(decision tree)是一种树形结构,其中每个内部节点表示一个属性上的判断,每个分支代表一个判断结果的输出,最后每个叶节点代表一种分类结果。决策树本质是一颗由多个判断节点组成的树。
决策树思想的来源非常朴素,程序设计中的条件分支结构就是if-else结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法。
决策树的决策过程就是从根节点开始,测试待分类项中对应的特征属性,并按照其值选择输出分支,直到叶子节点,将叶子节点的存放的类别作为决策结果。
2、决策树的目的(Why)
决策树学习的目的是为了产生一棵泛化能力强(即处理未见示例能力强)的决策树。
3、怎么做(How)
决策树通常有三个步骤:特征选择、决策树的生成、决策树的修剪。
特征选择:从训练数据的特征中选择一个特征作为当前节点的分裂标准(特征选择的标准不同产生了不同的特征决策树算法)。
决策树生成:根据所选特征评估标准,从上至下递归地生成子节点,直到数据集不可分则停止决策树停止声场。
决策树剪枝:决策树容易过拟合,需要剪枝来缩小树的结构和规模(包括预剪枝和后剪枝)。
决策树:决策和树两步,构建树形结构在前,决策在后。决策树的生成过程中分割方法,即 属性选择的度量 是关键
几个问题:如何进行特征选择?
按照某个特征对数据进行划分时,它能最大程度地将原本混乱的结果尽可能划分为几个有序的大类,则就应该先以这个特征为决策树中的根结点。
二、原理理解及公式
1、决策树原理
1.1、决策树组成
决策树由结点和有向边组成。结点有两种类型:内部结点和叶节点。
内部结点表示一个特征或属性,
叶节点表示一个类别,
有向边则对应其所属内部结点的可选项(属性的取值范围)。
在用决策树进行分类时,首先从根结点出发,对实例在该结点的对应属性进行测试,接着会根据测试结果,将实例分配到其子结点;然后,在子结点继续执行这一流程,如此递归地对实例进行测试并分配,直至到达叶结点;最终,该实例将被分类到叶结点所指示的结果中。
1.2、决策树的构建
决策树的本质是从训练集中归纳出一套分类规则,使其尽量符合以下要求:
- 具有较好的泛化能力;
- 在 1 的基础上尽量不出现过拟合现象。
当目标数据的特征较多时,应该将样本数据的特征按照怎样的顺序添加到一颗决策树的各级结点中?这便是构建决策树所需要关注的问题核心。
也就是前面说的如何特征选择。按照某个特征对数据进行划分时,它能最大程度地将原本混乱的结果尽可能划分为几个有序的大类,则就应该先以这个特征为决策树中的根结点。
基于此,引入信息论中的“熵”。
2、信息论基础
2.1、熵
2.1.1、概念
熵(Entropy)是表示随机变量不确定性的度量,即物体内部的混乱程度。
比如下图中,从 左到右表示了熵增的过程。
系统越有序,熵值越低;系统越混乱或者分散,熵值越高。
对于决策树希望分类后的结果能使得整个样本集在各自的类别中尽可能有序,即最大程度地降低样本数据的熵。
2.1.2、熵的公式
D为训练数据集所有样本,K为所划分的类别数量,pk是k类样本的概率密度:(H(X)是另一种表达形式。)
当pk=0或pk=1时,H(X)=0,随机变量完全没有不确定性
当pk=0.5时,H(X)=1,此时随机变量的不确定性最大
eg:显然A集合的熵值要低,A中只有两种类别,而B中类别太多了,熵值就会大很多。
常用的最优属性选取方法有三种:
- 信息增益:在 ID3 决策树中使用
- 信息增益率:在 C4.5 决策树中使用
- 基尼系数:在 CART 决策树中使用
2.2、信息增益(决策树的划分依据一)-- ID3
2.2.1、概念
以某特征划分数据集前后的熵的差值。
熵可以表示样本集合的不确定性,熵越大,样本的不确定性就越大。因此可以使用划分前后集合熵的差值来衡量使用当前特征对于样本集合D划分效果的好坏。
信息增益 = ent(前) - ent(后)
2.2.2、公式
特征A对训练数据集D的信息增益g(D,A),定义为集合D的信息熵H(D)与特征A给定条件下D的信息条件熵H(D|A)之差,即公式为:
信息熵:
条件熵:(D为训练数据集所有样本,A为某一特征,n为特征A的特征值种类,|Di|为第i类数量,
K为所划分的类别数量,|Dik|第i类划分为第k类的数量)
其实就是父节点的信息熵与其下所有子节点总信息熵之差。
2.2.3、栗子
用一个栗子(银行贷款数据)来理解:eg:
“年龄”信息增益:
“有工作”信息增益:
“有房子”信息增益:
“信贷情况”信息增益:
对4种特征的Gain进行比较,Gain(D,有房子)≈0.420最大,所以应该选择“有房子”作为决策树的根节点。
选择根节点后,在划分后的基础上,在对其他特征递归计算,得到下一个Gain最大的特征,以此类推构建一颗决策树。
2.3、信息增益率(决策树的划分依据二)--C4.5
2.3.1、概念
增益率是用前面的增益度量Gain(D,A)和特征A的“固有值”(intrinsic value)的比值来共同定义的。
信息增益率⽤ “信息增益 / 内在信息”‘,会导致属性的重要性随着内在信息的增⼤⽽减⼩(也就是说,如果这个属性本身不确定性就很⼤,那我就越不倾向于选取它),这样算是对单纯⽤信息增益有所补偿。
(信息增益倾向于特征值较多的,信息增益率倾向于特征值较少的)
2.3.2、公式
2.3.3、栗子
还是用上面的例子继续计算:
“年龄”信息增益率:
“有工作”信息增益率:
“有房子”信息增益率:
“信贷情况”信息增益率:
对4种特征的Gain_ratio进行比较,Gain_ratio(D,有房子)≈0.433最大,所以应该选择“有房子”作为决策树的根节点。
选择根节点后,在划分后的基础上,在对其他特征递归计算,得到下一个Gain_ratio最大的特征,以此类推构建一颗决策树。
2.4、基尼值和基尼指数(决策树的划分依据三)--CART
CART (Classification and Regression Tree)
2.4.1、基尼值
Gini(D):从数据集D中随机抽取两个样本,其类别标记不⼀致的概率。Gini(D)值
越⼩,数据集D的纯度越⾼。 数据集 D 的纯度可⽤基尼值来度量
2.4.2、基尼指数
Gini_index(D,A):⼀般,选择使划分后基尼系数最⼩的属性作为最优化分属性。
2.4.3、栗子
还是用上面的例子继续计算:
“年龄”基尼指数:
“有工作”基尼指数:
“有房子”基尼指数:
“信贷情况”基尼指数:
对4种特征的Gini_index进行比较,Gini_index(D,有房子)≈0.264最低,所以应该选择“有房子”作为决策树的根节点。
选择根节点后,在划分后的基础上,在对其他特征递归计算,得到下一个Gini_index最小的特征,以此类推构建一颗决策树。
2.4.4、栗子
针对连续值进行划分
咱们直接考虑年收入的Gini:
会将每两个连续年收入取中值进行划分,并求出其Gini系数增益,从表中可知,将年收入从95,和100处分成两部分Gini增益最高。
3、cart剪枝
实线显示的是决策树在训练集上的精度,虚线显示的则是在一个独立的测试集上测量出来的精度。
随着树的增长,在训练样集上的精度是单调上升的, 然而在独立的测试样例上测出的精度先上升后下降。
出现这种情况的原因:
1、噪声、样本冲突,即错误的样本数据。
2、特征即属性不能完全作为分类标准。
3、巧合的规律性,数据量不够大。
2.1、预剪枝
1、每一个结点所包含的最小样本数目,例如10,则该结点总样本数小于10时,则不再分;
2、指定树的高度或者深度,例如树的最大深度为4;
3、指定结点的熵小于某个值,不再划分。随着树的增长, 在训练样集上的精度是单调上升的, 然而在独立的测试样例上测出的精度先上升后下降。
2.2、后剪枝
后剪枝,在已生成过拟合决策树上进行剪枝,可以得到简化版的剪枝决策树。
4、优缺点
4.1、ID3
信息增益的缺点是倾向于选择取值较多的属性,在有些情况下这类属性可能不会提供太多有价值的信息.
ID3算法只能对描述属性为离散型属性的数据集构造决策树。
4.2、C4.5
改进:
- 用信息增益率来选择属性
- 可以处理连续数值型属性
- 采用了一种后剪枝方法
- 对于缺失值的处理
优点:
产生的分类规则易于理解,准确率较高。
缺点:
在构造树的过程中,需要对数据集进行多次的顺序扫描和排序,因而导致算法的低效。
C4.5只适合于能够驻留于内存的数据集,当训练集大得无法在内存容纳时程序无法运行。
4.3、cart
CART算法相比C4.5算法的分类方法,采用了简化的二叉树模型,同时特征选择采用了近似的基尼系数来简化计算。
C4.5不一定是二叉树,但CART一定是二叉树。
三、**算法实现
四、接口实现
1、API
sklearn.tree.DecisionTreeClassifier
导入:
from sklearn.tree import DecisionTreeClassifier
语法:
DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)
criterion:划分标准;{"gini","entropy"},default="gini"
max_depth:树的深度大小;int,default="None"
min_samples_split:某节点的样本数少于min_samples_split,不会继续再尝试选择最优特征来进行划分;int,default=2
min_samples_leaf:限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝;int,default="None"
max_leaf_nodes:限制最大叶子节点数,可以防止过拟合;int,default="None"
random_state:随机数种子
max_features:限制最大特征数;{None,log2,sqrt},default="None"
2、流程
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
2.1、获取数据
# 加载数据
iris = load_iris()
2.2、数据预处理
# 划分数据集
x_train,x_test,y_train,y_test = train_test_split(iris.data, iris.target, test_size=0.2, random_state=1473)
2.3、特征工程
2.4、决策树模型训练
# 实例化预估器
dtc = DecisionTreeClassifier() # 确定决策树参数
# 模型训练
dtc.fit(x_train, y_train)
2.5、模型评估
# 预测测试集结果
y_pred = dtc.predict(x_test)
print('前20条记录的预测值为:\n', y_pred[:20])
print('前20条记录的实际值为:\n', y_test[:20])
# 求出预测准确率和混淆矩阵
from sklearn.metrics import accuracy_score, confusion_matrix
print("预测结果准确率为:", accuracy_score(y_test, y_pred))
print("预测结果混淆矩阵为:\n", confusion_matrix(y_test, y_pred))
2.6、结果预测
经过模型评估后通过的模型可以代入真实值进行预测。
2.7、决策树可视化
2.7.1、导出dot文件
# 决策树可视化
from sklearn.tree import export_graphviz
export_graphviz(
# 传入构建好的决策树模型
dtc,
# 设置输出文件(需要设置为 .dot 文件,之后再转换为 jpg 或 png 文件)
out_file="./data/iris_tree.dot",
# 设置特征的名称
feature_names=iris.feature_names,
# 设置不同分类的名称(标签)
class_names=iris.target_names
)
2.7.2、下载Graphviz插件
官网:Graphviz官网
!!!注意:这里一定要把加入系统路径(环境变量)勾上哦。
等待安装完成即可
2.7.3、生成可视化图片
找到导出的dot文件位置
打开cmd(输入cmd,回车)
输入命令
dot -Tpng iris_tree.dot -o iris_tree.png
或
dot -Tjpg iris_tree.dot -o iris_tree.jpg
分析:非叶节点的第一行如petal length(cm)<=2.35,为划分属性即条件,如将petal length属性按照不高于2.35和高于2.35分成两部分。
gini=0.666,表示该节点的gini值。
samples=120,为总样本数量。
value=[43,38,39],为各类别样本数量。
class=setosa,为该节点被划分的类别(样本类别数量最多的类别),叶节点才具有参考价值。
旧梦可以重温,且看:机器学习(五) -- 监督学习(2) -- 朴素贝叶斯
欲知后事如何,且看: 机器学习(五) -- 监督学习(4) -- 集成学习方法-随机森林