目录
1 什么是随机森林?
2 随机森林的特点
3 随机森林的相关基础知识
4 随机森林的生成
5 随机森林的随机性体现:
6 袋外错误率(oob error)
7 随机森林的Python实现
随机森林就是通过集成学习的思想将多棵树集成的一种算法,它的基本单元是决策树,而它的本质属于机器学习的一大分支——集成学习(Ensemble Learning)方法。随机森林的名称中有两个关键词,一个是“随机”,一个就是“森林”。“森林”我们很好理解,一棵叫做树,那么成百上千棵就可以叫做森林了,这样的比喻还是很贴切的,其实这也是随机森林的主要思想--集成思想的体现。“随机”的含义我们会在下边部分讲到。
其实从直观角度来解释,每棵决策树都是一个分类器(假设现在针对的是分类问题),那么对于一个输入样本,N棵树会有N个分类结果。而随机森林集成了所有的分类投票结果,将投票次数最多的类别指定为最终的输出,这就是一种最简单的 Bagging 思想。
我们前边提到,随机森林是一种很灵活实用的方法,它有如下几个特点:
实际上,随机森林的特点不只有这六点,它就相当于机器学习领域的Leatherman(多面手),你几乎可以把任何东西扔进去,它基本上都是可供使用的。在估计推断映射方面特别好用,以致都不需要像SVM那样做很多参数的调试。
随机森林看起来是很好理解,但是要完全搞明白它的工作原理,需要很多机器学习方面相关的基础知识。
1)信息、熵以及信息增益的概念
这三个基本概念是决策树的根本,是决策树利用特征来分类时,确定特征选取顺序的依据。理解了它们,决策树你也就了解了大概。
对于机器学习中的决策树而言,如果带分类的事物集合可以划分为多个类别当中,则某个类(xi)的信息可以定义如下:
I(x)用来表示随机变量的信息,p(xi)指是当xi发生时的概率。
熵是用来度量不确定性的,当熵越大,X=xi的不确定性越大,反之越小。对于机器学习中的分类问题而言,熵越大即这个类别的不确定性更大,反之越小。
信息增益在决策树算法中是用来选择特征的指标,信息增益越大,则这个特征的选择性越好。
2)决策树
决策树是一种树形结构,其中每个内部节点表示一个属性上的测试,每个分支代表一个测试输出,每个叶节点代表一种类别。常见的决策树算法有C4.5、ID3和CART。
3)集成学习
集成学习通过建立几个模型组合的来解决单一预测问题。它的工作原理是生成多个分类器/模型,各自独立地学习和作出预测。这些预测最后结合成单预测,因此优于任何一个单分类的做出预测。
随机森林是集成学习的一个子类,它依靠于决策树的投票选择来决定最后的分类结果。你可以在这找到用python实现集成学习的文档:Scikit 学习文档。
有了树我们就可以分类了,但是森林中的每棵树是怎么生成的呢?
每棵树的按照如下规则生成:
1)如果训练集大小为N,对于每棵树而言,随机且有放回地从训练集中的抽取N个训练样本(这种采样方式称为bootstrap sample方法),作为该树的训练集;
从这里我们可以知道:每棵树的训练集都是不同的,而且里面包含重复的训练样本(理解这点很重要)。
2)如果每个样本的特征维度为M,指定一个常数m< 3)每棵树都尽最大程度的生长,并且没有剪枝过程。 一开始我们提到的随机森林中的“随机”就是指的这里的两个随机性。两个随机性的引入对随机森林的分类性能至关重要。由于它们的引入,使得随机森林不容易陷入过拟合,并且具有很好得抗噪能力(比如:对缺省值不敏感)。 为什么要随机抽样训练集?(add @2016.05.28) 为什么要有放回地抽样?(add @2016.05.28) 随机森林分类效果(错误率)与两个因素有关: 减小特征选择个数m,树的相关性和分类能力也会相应的降低;增大m,两者也会随之增大。所以关键问题是如何选择最优的m(或者是范围),这也是随机森林唯一的一个参数。 随机森林是采用自助法(bootstrap)重采样技术,从原始训练集样本集N有放回的重复抽取k个样本形成新的训练集样本集合,然后根据自助样本集生成k个决策树组成的随机森林。新数据的分类结果按决策树投票多少形成的分数的决定。 特征选择采用随机的方法去分裂每个节点,然后比较不同情况下产生的误差,能够监测到内在估计误差、分类能力和相关性来选择特征的数目。单棵决策树的分类能力很小,但在随机产生大量的决策树后,一个测试样本可以通过每一棵树的分类结果经统计后选择最可能的分类。 上面我们提到,构建随机森林的关键问题就是如何选择最优的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折交叉验证。 利用Python的两个模块,分别为pandas和scikit-learn来实现随机森林。 分类结果: 这里随机生成了三个样本集,分割面近似为月形、圆形和线形的。我们可以重点对比一下决策树和随机森林对样本空间的分割: 1)从准确率上可以看出,随机森林在这三个测试集上都要优于单棵决策树,90%>85%,82%>80%,95%=95%; 2)从特征空间上直观地可以看出,随机森林比决策树拥有更强的分割能力(非线性拟合能力)。
5 随机森林的随机性体现:
6 袋外错误率(oob error)
7 随机森林的Python实现
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
import pandas as pd
import numpy as np
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df[‘is_train’] = np.random.uniform(0, 1, len(df)) <= .75
df[‘species’] = pd.Factor(iris.target, iris.target_names)
df.head()
train, test = df[df[‘is_train’]True], df[df[‘is_train’]False]
features = df.columns[:4]
clf = RandomForestClassifier(n_jobs=2)
y, _ = pd.factorize(train[‘species’])
clf.fit(train[features], y)
preds = iris.target_names[clf.predict(test[features])]
pd.crosstab(test[‘species’], preds, rownames=[‘actual’], colnames=[‘preds’])