各种算法-树相关的算法

目录

深度优先搜索的节点

二叉树的后序遍历post order算法

决策树

信息、熵以及信息增益的概念

决策树构造例子

可视化

CART

随机森林


深度优先搜索的节点

dfs:Depth First Search,深度优先搜索

我们在做dfs的时候,当访问到一个节点时,会出现四种情况:
1.此节点未被访问过,则此次的访问关系边(发起点——>接受点)称为树边(tree edge);
2.此节点被访问过但此节点的子孙还没访问完,换句话说,此次的发起点的源头可以追溯到接收点,则此次访问关系边称为后向边(back edge);
3.此节点被访问过且此节点的子孙已经访问完,而且发起点是搜索初始边,则称为前向边(down edge);
4.此节点被访问过且此节点的子孙已经访问完,而且发起点不是搜索初始边,则称为横叉边(cross edge)。
其实这种分类只是相对的,也会随着dfs的改变而改变,比如搜索入口、搜索顺序等。

二叉树的后序遍历post order算法

后序遍历也是深度优先算法,在后顺序遍历中,首先访问左子树,然后访问右子树,最后打印节点或根的值。这就是为什么根值总是在后序遍历中最后打印的原因。与许多树算法一样,实现后序遍历的最简单方法是使用递归。

决策树

与SVM类似,决策树在机器学习算法中是一个功能非常全面的算法,它可以执行分类与回归任务,甚至是多输出任务。决策树的算法非常强大,即使是一些复杂的问题,也可以良好地拟合复杂数据集。决策树同时也是随机森林的基础组件,随机森林在当前是最强大的机器学习算法之一。

信息、熵以及信息增益的概念

  这三个基本概念是决策树的根本,是决策树利用特征来分类时,确定特征选取顺序的依据。理解了它们,决策树你也就了解了大概。

  引用香农的话来说,信息是用来消除随机不确定性的东西。当然这句话虽然经典,但是还是很难去搞明白这种东西到底是个什么样,可能在不同的地方来说,指的东西又不一样。对于机器学习中的决策树而言,如果带分类的事物集合可以划分为多个类别当中,则某个类(xi)的信息可以定义如下:

  I(x)用来表示随机变量的信息,p(xi)指是当xi发生时的概率。

  熵是用来度量不确定性的,当熵越大,X=xi的不确定性越大,反之越小。对于机器学习中的分类问题而言,熵越大即这个类别的不确定性更大,反之越小。

  信息增益在决策树算法中是用来选择特征的指标,信息增益越大,则这个特征的选择性越好。

决策树构造例子

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier

iris = load_iris()
X = iris.data[:, 2:] # petal length and width
y = iris.target

tree_clf = DecisionTreeClassifier(max_depth=2)
tree_clf.fit(X, y)

可视化

根据生成的图,我们看一下决策树如何做决策。假设我们现在有了一条 iris flower数据并希望对它进行分类。我们首先从根节点开始(深度为0,在最顶端):这个节点会判断这支花的petal length 是否小于2.45cm。假设它是,则移动到左子节点(深度1,左)。在这个例子中,这个左子节点是一个叶子节点,所以它不会继续进行判断,仅检查这个节点的类别,然后决策树便会预测这支花是一个Iris setosa类被(class=setosa)。

可以看到,决策树一个很好的特性就是:它们需要的数据准备操作很少。实际上,它们也不需要进行特征缩放或是数据中心化。

每个节点的sample属性统计的是:有多少条训练数据符合此节点。例如,100条训练数据的pental length 大于2.45cm(深度1,右)。

每个节点的value属性可以告诉我们:在每个类别中,有多少条训练数据符合这个节点。例如,在最底层右边的节点中,有0条数据属于Iris setosa,1条数据属于Iris versicolor,以及45条数据属于virginica。

最后,每个节点的gini属性衡量的是它的不纯度(impurity):如果节点中所有的训练集数据均属于同一个类别,则这个节点的gini指数为0(gini=0),说明此节点为一个“纯”(pure)节点。例如,在深度1的左边节点中,所有的训练数据都属于Iris setosa类别,所以这个节点是“纯”的,并且gini分数为0。下面是训练算法计算gini分数的公式,Gi 为第 ith 个节点的gini分数:

在这个公式中,pi,k 是:在节点ith中属于类别k的实例数占(这个节点中)训练数据实例数的比例。在深度2的左节点中,gini分数为:1 – (0/54)2 – (49/54)2 – (5/54)2 ≈ 0.168

需要注意的是,sk-learn使用的是CART算法,它仅生成二叉树(也就是节点仅会判断“是/否“问题)。不过其他算法如ID3可以生成多叉树。

下图是决策数的决策边界。竖着的那条实现代表的是根节点(深度0)的决策边界:petal length=2.45cm这条线。由于左边区域是“纯“的(仅有Iris setosa类别),所以它无法再分割。不过右边的区域是”不纯“的,所以深度为1 的右节点可以在petal width=1.75cm处再次分割(由横着的虚线表示)。由于在训练时参数max_depth 设置为2,这个决策树会在此停止。如果设置max_depth=3,则两个深度为2的节点还会增加其他的决策边界(下图中虚线点表示)。

决策树是非常直观的,并且决策边界也非常容易解释,类似这种模型一般称为白盒模型。相反的,也有黑盒模型,例如随机森林以及神经网络。这些模型的预测表现非常好,但是一般很难以一种简洁的方式去解释它们这样做预测的原因。例如,假设有一个神经网络判断到某张图片上有某个人,我们很难知道到底是什么促成了这个预测:是这个模型预测到了这个人的眼睛?耳朵?还是鼻子?亦或是他们坐的那张椅子?与之相反的是,决策树可以提供一个非常好、且简单的分类规则。

决策树也可以用于估计:一个实例属于某个特定类别k的概率。首先它会遍历树,以在叶子节点中找到这个实例,然后返回类别k的训练数据在这个节点中的比例。例如,假设我们有支花,它的petal length = 5cm,petal width=1.5cm。则它对应的叶子节点为:深度为2的左节点。所以此时决策树会输出下面的概率:

  • 此花属于Iris setosa类别(0/54)的概率为0
  • 此花属于Iris versicolor类别(49/54)的概率为90.7%
  • 此花属于Iris virginica类别(5/54)的概率为9.3%

CART

分类与回归树(classification and regression tree, CART)模型是应用广泛的决策树学习方法,同样由特征选择、树的生成和剪枝组成,既可以用于分类也可以用于回归。

CART假设决策树是二叉树,内部结点特征的取值为“是”和“否”,左分支是取值为“是”的分支,右分支是取值为“否”的分支。

CART算法主要由以下两步组成:

  1. 决策树生成:基于训练数据集生成决策树,生成的决策树要尽量大。
  2. 决策树剪枝:用验证数据集对已生成的树进行剪枝并选择最优子树,这时用损失函数最小作为剪枝的标准。

随机森林

随机森林就是通过集成学习的思想将多棵树集成的一种算法,它的基本单元是决策树,而它的本质属于机器学习的一大分支——集成学习(Ensemble Learning)方法。随机森林的名称中有两个关键词,一个是“随机”,一个就是“森林”。“森林”我们很好理解,一棵叫做树,那么成百上千棵就可以叫做森林了,这样的比喻还是很贴切的,其实这也是随机森林的主要思想--集成思想的体现。“随机”的含义我们会在下边部分讲到。其实从直观角度来解释,每棵决策树都是一个分类器(假设现在针对的是分类问题),那么对于一个输入样本,N棵树会有N个分类结果。而随机森林集成了所有的分类投票结果,将投票次数最多的类别指定为最终的输出,这就是一种最简单的 Bagging 思想。

打个形象的比喻:森林中召开会议,讨论某个动物到底是老鼠还是松鼠,每棵树都要独立地发表自己对这个问题的看法,也就是每棵树都要投票。该动物到底是老鼠还是松鼠,要依据投票情况来确定,获得票数最多的类别就是森林的分类结果。森林中的每棵树都是独立的,99.9%不相关的树做出的预测结果涵盖所有的情况,这些预测结果将会彼此抵消。少数优秀的树的预测结果将会超脱于芸芸“噪音”,做出一个好的预测。将若干个弱分类器的分类结果进行投票选择,从而组成一个强分类器,这就是随机森林bagging的思想(关于bagging的一个有必要提及的问题:bagging的代价是不用单棵决策树来做预测,具体哪个变量起到重要作用变得未知,所以bagging改进了预测准确率但损失了解释性。)。

  每棵树的按照如下规则生成:

  1)如果训练集大小为N,对于每棵树而言,随机且有放回地从训练集中的抽取N个训练样本(这种采样方式称为bootstrap sample方法),作为该树的训练集;

  从这里我们可以知道:每棵树的训练集都是不同的,而且里面包含重复的训练样本(理解这点很重要)。

  为什么要随机抽样训练集?

  如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的,这样的话完全没有bagging的必要;

  为什么要有放回地抽样?

  我理解的是这样的:如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是"有偏的",都是绝对"片面的"(当然这样说可能不对),也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决,这种表决应该是"求同",因此使用完全不同的训练集来训练每棵树这样对最终分类结果是没有帮助的,这样无异于是"盲人摸象"。

  2)如果每个样本的特征维度为M,指定一个常数m<<M,随机地从M个特征中选取m个特征子集,每次树进行分裂时,从这m个特征中选择最优的;

  3)每棵树都尽最大程度的生长,并且没有剪枝过程。

  一开始我们提到的随机森林中的“随机”就是指的这里的两个随机性。两个随机性的引入对随机森林的分类性能至关重要。由于它们的引入,使得随机森林不容易陷入过拟合,并且具有很好得抗噪能力(比如:对缺省值不敏感)。

随机森林分类效果(错误率)与两个因素有关:

  • 森林中任意两棵树的相关性:相关性越大,错误率越大;
  • 森林中每棵树的分类能力:每棵树的分类能力越强,整个森林的错误率越低。

  减小特征选择个数m,树的相关性和分类能力也会相应的降低;增大m,两者也会随之增大。所以关键问题是如何选择最优的m(或者是范围),这也是随机森林唯一的一个参数。

上面我们提到,构建随机森林的关键问题就是如何选择最优的m,要解决这个问题主要依据计算袋外错误率oob error(out-of-bag error)。

  随机森林有一个重要的优点就是,没有必要对它进行交叉验证或者用一个独立的测试集来获得误差的一个无偏估计。它可以在内部进行评估,也就是说在生成的过程中就可以对误差建立一个无偏估计。

  我们知道,在构建每棵树时,我们对训练集使用了不同的bootstrap sample(随机且有放回地抽取)。所以对于每棵树而言(假设对于第k棵树),大约有1/3的训练实例没有参与第k棵树的生成,它们称为第k棵树的oob样本。

  而这样的采样特点就允许我们进行oob估计,它的计算方式如下:

  (note:以样本为单位)

  1)对每个样本,计算它作为oob样本的树对它的分类情况(约1/3的树);

  2)然后以简单多数投票作为该样本的分类结果;

  3)最后用误分个数占样本总数的比率作为随机森林的oob误分率。

  (文献原文:Put each case left out in the construction of the kth tree down the kth tree to get a classification. In this way, a test set classification is obtained for each case in about one-third of the trees. At the end of the run, take j to be the class that got most of the votes every time case n was oob. The proportion of times that j is not equal to the true class of n averaged over all cases is the oob error estimate. This has proven to be unbiased in many tests.)

  oob误分率是随机森林泛化误差的一个无偏估计,它的结果近似于需要大量计算的k折交叉验证。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值