概述
机器学习之决策树
今天是分类算法的第二课时,我们今天要介绍的是一个应用非常广泛的模型——决策树。首先我依然会从一个例子出发,看看女神是怎样决策要不要约会的;然后分析它的算法原理、思路形成的过程;由于决策树非常有价值,还衍生出了很多高级版本,在扩展内容里我也进行了简要的介绍。希望通过本课时的学习,你可以掌握决策树的思路以及使用方法,并能够尝试用它来解决遇到的问题
一共例子
我们都知道女神身后有很多的追求者,她肯定不会和每个人都约会,因为时间不够,必须要好好管理自己的时间才行。于是女神给每个想要约会的人发信息说:“把你的简历发过来吧。”
简历收上来后,第一眼先看照片,颜值打几分?然后再看年收入,长得帅的就可以少挣点,毕竟 “帅也可以当饭吃啊”。不帅的呢?那收入必须要求高一点,“颜值不够,薪资来凑”。薪资还差点的,再看看学历是不是研究生 / 985/211,看看身高有没有 180…… 所以你就可以对号入座了,发现自己哪条都不符合,好了,去好好“搬砖” 吧。
由此可知,女神的筛选条件有颜值、身高、收入、学历等,每一项都会对最后是否约会的结果产生影响,即女神通过对这几种条件的判断,决定是否要安排约会。
上面这个过程就是决策树的思路,下面我们来看一下决策树的具体原理。
算法原理
在已知的条件中,选取一个条件作为树根,也就是作为第一个决策条件,比如 “颜值” 分为帅和不帅两个结果,然后再看是否还需要其他判断条件。如果需要的话,继续构建一个分支来判断第二个条件,以此类推,直到能够推出一个结果,这个分支就结束了。
同样的,当我们把所有样本数据中出现的情况组合都构建入这棵树的时候,我们的算法也就完成了对样本的学习。最终形成的这棵树上,所有的叶子节点都是要输出的类别信息,所有的非叶子节点都是特征信息。当一个新的数据来了之后,就按照对应的判断条件,从根节点走到叶子节点,从而获得这个数据的分类结果。
比如,我帮女神收集了几份简历,然后按照条件整理出如下结果 :
编号 | 颜值 | 年收入 | 身高 | 学历 |
---|---|---|---|---|
1 | 帅 | 28 w | 178 cm | 本科 |
2 | 不帅 | 100 w | 176 cm | 硕士 |
3 | 不帅 | 40 w | 185 cm | 硕士 |
根据女神已经制定好的决策树,我们去预测一下这三个人能否获得约会资格。第一个人帅,那就从根节点走向左分支;再判断第二个条件:年收入只有 28w,不到 30w 的标准,那就被淘汰了。第二个人不帅,走向右分支,年收入 100w,那就可以继续往下进入左分支,身高 176cm 刚好过合格线,获得左分支的结果,顺利进入约会环节。第三个人不帅,年收入 40w,那就进入右分支,还需要再看学历:是研究生,那还可以继续走向左分支,身高有 185cm,那也成功获得约会资格 :
这就是决策树最初的一个思路。但是这里有一个问题,我想你可能也会想到,那就是该如何选择一个特征作为根节点?下一次决策又该选取哪个特征作为节点?决策树算法使用了一种称作信息增益的方法来衡量一个特征和特征之间的重要性,信息增益越大表明这个特征越重要,那么就优先对这个特征进行决策。至于信息增益和信息熵是在信息论中涉及的内容,如果你有兴趣可以再进行详细学习。
在一种理想的情况下,我们构建的决策树上的每一个叶子节点都是一个纯粹的分类,也就是通过这条路径进入到这个叶子节点的所有数据都是同一种类别,但是这需要反复回溯修改非叶子节点的判定条件,而且要划分更多的分支来进行处理,所以实际上决策树实现的时候都采用了贪心算法,来寻找一个最近的最优解,而不是全局的最优解。
算法的优缺点
几个版本的决策树的比较
决策树最初的版本称为 ID3( Iterative Dichotomiser 3 ),ID3 的缺点是无法处理数据是连续值的情况,也无法处理数据存在缺失的问题,需要在准备数据环节把缺失字段进行补齐或者删除数据。后来有人提出了改进方案称为 C4.5,加入了对连续值属性的处理,同时也可以处理数据缺失的情况。同时,还有一种目前应用最多的 CART( Classification And Regression Tree)分类与回归树,每次分支只使用二叉树划分,同时可以用于解决回归问题。
关于这三种决策树,我列了一个对比的表格,可以看到它们之间的区别。
这里的优缺点是针对 CART 树来讲,因为现在 CART 是主流的决策树算法,而且在 sklearn 工具包中使
用的也是 CART 决策树。那么我们再看一下,决策树算法有什么优缺点。
优点
- 非常直观,可解释极强。 在生成的决策树上,每个节点都有明确的判断分支条件,所以非常容易看到为什么要这样处理,比起神经网络模型的黑盒处理,高解释性的模型非常受金融保险行业的欢迎。在后面的动手环节,我们能看到训练完成的决策树可以直接输出出来,以图形化的方式展示给我们生成的决策树每一个节点的判断条件是什么样子的。
- 预测速度比较快。 由于最终生成的模型是一个树形结构,对于一条新数据的预测,只需要按照条件在每一个节点进行判定就可以。通常来说,树形结构都有助于提升运算速度。
- 既可以处理离散值也可以处理连续值,还可以处理缺失值。
缺点
- 容易过拟合。 试想在极端的情况下,我们根据样本生成了一个最完美的树,那么样本中出现的每一个值都会有一条路径来拟合,所以如果样本中存在一些问题数据,或者样本与测试数据存在一定的差距时,就会看出泛化性能不好,出现了过拟合的现象。
- 需要处理样本不均衡的问题。 如果样本不均衡,某些特征的样本比例过大,最终的模型结果将会更偏向这些特征。
- 样本的变化会引发树结构巨变。
关于剪枝
上面提到的一个问题就是决策树容易过拟合,那么我们需要使用剪枝的方式来使得模型的泛化能力更好,所以剪枝可以理解为简化我们的决策树,去掉不必要的节点路径以提高泛化能力。剪枝的方法主要有预剪枝和后剪枝两种方式。
- 预剪枝: 在决策树构建之初就设定一个阈值,当分裂节点的熵阈值小于设定值的时候就不再进行分裂了;然而这种方法的实际效果并不是很好,因为谁也没办法预料到我们设定的恰好是我们想要的。
- 后剪枝: 后剪枝方法就是在我们的决策树已经构建完成以后,再根据设定的条件来判断是否要合并一些中间节点,使用叶子节点来代替。在实际的情况下,通常都是采用后剪枝的方案。
信息增熵
这里使用官网提供的示例数据进行讲解,数据为14天打球的情况(实际的情况);最后的目标是希望构建决策树实现最后是否打球的预测(yes|no),数据如下
由数据可知共有4种特征,因此在进行决策树构建的时候根节点的选择就有4种情况,如下。那么就回到最初的问题上面了,到底哪个作为根节点呢?是否4种划分方式均可以呢?因此 信息增益 就要正式的出场露面了
由于是要判断决策前后的熵的变化,首先确定一下在历史数据中(14天)有9天打球,5天不打球,所以此时的熵应为(一般log函数的底取2,要求计算的时候统一底数即可):
先从第一个特征下手,计算决策树分类后的熵值的变化,还是使用公式进行计算
注意:直接将计算得到的结果和上面计算出初始的结果相比较吗? (当然不是,outlook取到sunny,overcast,rainy是有不同的概率的,因此最后的计算结果要考虑这个情况)最终的熵值计算就为:
信息增益:系统的熵值就由原始的0.940下降到了0.693,增益为0.247
依次类推,可以分别求出剩下三种特征分类的信息增益
最后我们选择最大的那个就可以啦,相当于是遍历了一遍特征,找出来了根节点(老大),然后在其余的中继续通过信息增益找子节点(老二)…,最终整个决策树就构建完成了!
信息增益率和gini系数
之前使用信息增益进行判断根节点有没有什么问题,或者是这种方法是不是存在bug,有些问题是解决不了的???答案是当然有的,比如还是使用上面的14个人打球的数据,这里添加一个特征为打球的次数ID,分别为1,2,3,…,12,13,14
由此特征进行决策判断后的结果可以发现均为单个的分支,计算熵值的结果也就为0,这样分类的结果信息增益是最大的,说明这个特征是非常有用的,如果还是按照信息增益来进行评判,树模型就势必会按照ID进行根节点的选择,而实际上按照这个方式进行决策判断并不可行,只看每次打球的ID并不能说这一天是不是会打球。
从上面的示例中可以发现信息增益无法解决这种特征分类(类似ID)后结果特别特别多的情况,故就发展了另外的决策树算法叫做 信息增益率 和 gini系数
这里介绍一下构建决策树中使用的算法(至于前面的英文称呼,知道是一种指代关系就可以了,比如说的信息增益也可以使用ID3进行表示):
代码举例
关于几个版本的决策树你已经有了大致的了解,那么下面我们来动手写一写使用决策树算法进行的代码。
在前面的部分我没有写更多的注释,这部分是关于包的引入和导入数据的,在前面的章节已经进行过介绍,这里主要是把引入的算法包进行了调整,其余的部分实际上没有什么修改,如果你忘了可以看一下前面的章节。
from sklearn import datasets
from sklearn.tree import DecisionTreeClassifier
import numpy as np
np.random.seed(0)
iris=datasets.load_iris()
iris_x=iris.data
iris_y=iris.target
indices = np.random.permutation(len(iris_x))
iris_x_train = iris_x[indices[:-10]]
iris_y_train = iris_y[indices[:-10]]
iris_x_test = iris_x[indices[-10:]]
iris_y_test = iris_y[indices[-10:]]
#在模型训练时,我们设置了树的最大深度为 4。
clf = DecisionTreeClassifier(max_depth=4)
clf.fit(iris_x_train, iris_y_train)
#我们尝试把决策树算法生成的模型使用画图的方式展示出来
from IPython.display import Image
from sklearn import tree
import pydotplus
dot_data = tree.export_graphviz(clf, out_file=None,
feature_names=iris.feature_names,
class_names=iris.target_names,
filled=True, rounded=True,
special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data)
Image(graph.create_png())
iris_y_predict = clf.predict(iris_x_test)
score=clf.score(iris_x_test,iris_y_test,sample_weight=None)
print('iris_y_predict = ',iris_y_predict)
print('iris_y_test = ',iris_y_test)
print('Accuracy:',score)
s_x_test,iris_y_test,sample_weight=None)
print('iris_y_predict = ',iris_y_predict)
print('iris_y_test = ',iris_y_test)
print(‘Accuracy:’,score)
``
最后
以上就是腼腆航空为你收集整理的机器学习之决策树机器学习之决策树的全部内容,希望文章能够帮你解决机器学习之决策树机器学习之决策树所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复