随机森林通俗介绍

随机森林是用随机的方式建立一个森林,森林里面有很多的决策树组成,随机森林的每一棵决策树之间是没有关联的。在得到森林之后,当有一个新的输入样本进入的时候,就让森林中的每一棵决策树分别进行一下判断,看看这个样本应该属于哪一类(对于分类算法),然后看看哪一类被选择最多,就预测这个样本为那一类。随机森林可以既可以处理属性为离散值的量,比如ID3算法,也可以处理属性为连续值的量,比如C4.5算法。另外,随机森林还可以用来进行无监督学习聚类和异常点检测。

一、随机森林构造过程

下面是随机森林的构造过程:

  1. 假如有N个样本,则有放回的随机选择N个样本(每次随机选择一个样本,然后返回继续选择)。这选择好了的N个样本用来训练一个决策树,作为决策树根节点处的样本。

  2. 当每个样本有M个属性时,在决策树的每个节点需要分裂时,随机从这M个属性中选取出m个属性,满足条件m << M。然后从这m个属性中采用某种策略(比如说信息增益)来选择1个属性作为该节点的分裂属性。

  3. 决策树形成过程中每个节点都要按照步骤2来分裂(很容易理解,如果下一次该节点选出来的那一个属性是刚刚其父节点分裂时用过的属性,则该节点已经达到了叶子节点,无须继续分裂了)。一直到不能够再分裂为止。注意整个决策树形成过程中没有进行剪枝。

  4. 按照步骤1~3建立大量的决策树,这样就构成了随机森林了。

二、随机森林的注意点

在建立每一棵决策树的过程中,有两点需要注意:采样完全分裂

1、随机采样

首先是两个随机采样的过程,随机森林对输入的数据要进行行、列的采样。

  • 对于行采样,采用有放回的方式,也就是在采样得到的样本集合中,可能有重复的样本。假设输入样本为N个,那么采样的样本也为N个。这样使得在训练的时候,每一棵树的输入样本都不是全部的样本,使得相对不容易出现过拟合
  • 对于列采样,从M个属性中,选择m个(m << M)。

2、完全分裂

然后对采样之后的数据使用完全分裂的方式建立出决策树,这样决策树的某一个叶子节点要么是无法继续分裂的,要么里面所有样本都是指向的同一个分类

一般很多的决策树算法都一个重要的步骤——剪枝,但是这里不这样干,由于之前的两个随机采样的过程保证了随机性,所以就算不剪枝,也不会出现过拟合

三、随机森林的优缺点

1、随机森林的优点

  1. 两个随机性的引入,使得随机森林不容易陷入过拟合
  2. 两个随机性的引入,使得随机森林具有很好的抗噪声能力
  3. 它能够处理很高维度(特征很多)的数据,并且不用做特征选择,对数据集的适应能力强,既能处理离散型数据,也能处理连续型数据,数据集无需规范化
  4. 可生成一个Proximities=(pij)矩阵,用于度量样本之间的相似性,pij=aij/N, aij表示样本i和j出现在随机森林中同一个叶子结点的次数,N随机森林中树的颗数
  5. 在创建随机森林的时候,对泛化误差使用的是无偏估计
  6. 训练速度快,可以得到变量重要性排序(两种:基于OOB误分率的增加量和基于分裂时的GINI下降量)
  7. 在训练过程中,能够检测到特征间的互相影响
  8. 训练时树与树之间是相互独立的,容易做成并行化方法
  9. 实现比较简单

2、随机森林的缺点:

  1. 随机森林在解决回归问题时,并没有像它在分类中表现的那么好,这是因为它并不能给出一个连续的输出。当进行回归时,随机森林不能够做出超越训练集数据范围的预测,这可能导致在某些特定噪声的数据进行建模时出现过度拟合。(PS:随机森林已经被证明在某些噪音较大的分类或者回归问题上回过拟合)。
  2. 对于许多统计建模者来说,随机森林给人的感觉就像一个黑盒子,你无法控制模型内部的运行。只能在不同的参数和随机种子之间进行尝试。
  3. 可能有很多相似的决策树,掩盖了真实的结果。
  4. 对于小数据或者低维数据(特征较少的数据),可能不能产生很好的分类。(处理高维数据,处理特征遗失数据,处理不平衡数据是随机森林的长处)。
  5. 执行数据虽然比boosting等快(随机森林属于bagging),但比单只决策树慢多了。

四、sklearn实现随机森林

1、一个简单例子

这里我使用scikit-learn中的鸢尾花数据集作为例子来学习随机森林算法。

{cmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
import pandas as pd
import numpy as np

# 加载数据集
iris = load_iris()

# 数据特征:150行, 4列
features = iris['data']

# 对应的鸢尾花种类: 150个,三种鸢尾花分别用 0,1,2 表示
target = iris['target']

# 自定义4个特征的名称
feature_names = iris.feature_names
feature_names = ['花萼长度', '花萼宽度', '花瓣长度', '花瓣宽度']

# 自定义三种鸢尾花的名称
class_names = iris.target_names
class_names = ['山鸢尾花', '变色鸢尾花', '维吉尼亚鸢尾花']

# 把样本分成训练集和测试集两部分, 两者比例为: 7:3
X_train, X_test, y_train, y_test = train_test_split(features, target, test_size=0.3, random_state=42)

# 定义决策树的个数为100
clf = RandomForestClassifier(n_estimators=100)
model = clf.fit(X_train, y_train)

# 预测
output = model.predict(X_test)
# 计算准确率
acc = np.mean(output == y_test)*100
print("The accuracy of the pure RandomForest classifier is: \t", acc, "%")
1
The accuracy of the pure RandomForest classifier is: 	 100.0 %

下面计算一下特征重要性:

{cmd
1
df_feature = pd.DataFrame({'feature': feature_names,'importance': model.feature_importances_})
1
2
3
4
5
  feature  importance
0 花萼长度 0.119307
1 花萼宽度 0.040993
2 花瓣长度 0.458942
3 花瓣宽度 0.380758

2、调参说明

  • n_estimators:表示森林里树的个数。一般来说n_estimators太小,容易欠拟合,n_estimators太大,计算量会太大,并且n_estimators到一定的数量后,再增大n_estimators获得的模型提升会很小,所以一般选择一个适中的数值。默认是100。

  • max_features:最大特征数。一般我们用默认的”auto”就可以了,如果特征数非常多,我们可以灵活使用下面描述的其他取值来控制划分时考虑的最大特征数,以控制决策树的生成时间。

    • 默认是”auto”,意味着划分时最多考虑$\sqrt{N}$个特征
    • 如果是”log2”,意味着划分时最多考虑$log_2N$个特征
    • 如果是”sqrt”,意味着划分时最多考虑$\sqrt{N}$个特征
    • 如果是整数,代表考虑的特征绝对数
    • 如果是浮点数,代表考虑特征百分比,即考虑(百分比xN)取整后的特征数,其中N为样本总特征数
  • max_depth: 决策树最大深度。默认可以不输入,如果不输入的话,决策树在建立子树的时候不会限制子树的深度。一般来说,数据少或者特征少的时候可以不管这个值。如果模型样本量多,特征也多的情况下,推荐限制这个最大深度,具体的取值取决于数据的分布。常用的可以取值10-100之间。

  • min_samples_split: 内部节点再划分所需最小样本数。这个值限制了子树继续划分的条件,如果某节点的样本数少于min_samples_split,则不会继续再尝试选择最优特征来进行划分。默认是2。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。

  • min_samples_leaf: 叶子节点最少样本数。这个值限制了叶子节点最少的样本数,如果某叶子节点数目小于样本数,则会和兄弟节点一起被剪枝。 默认是1,可以输入最少的样本数的整数,或者最少样本数占样本总数的百分比。如果样本量不大,不需要管这个值。如果样本量数量级非常大,则推荐增大这个值。

  • min_weight_fraction_leaf:叶子节点最小的样本权重和。这个值限制了叶子节点所有样本权重和的最小值,如果小于这个值,则会和兄弟节点一起被剪枝。 默认是0,就是不考虑权重问题。一般来说,如果我们有较多样本有缺失值,或者分类树样本的分布类别偏差很大,就会引入样本权重,这时我们就要注意这个值了。

  • max_leaf_nodes: 最大叶子节点数。通过限制最大叶子节点数,可以防止过拟合,默认是”None”,即不限制最大的叶子节点数。如果加了限制,算法会建立在最大叶子节点数内最优的决策树。如果特征不多,可以不考虑这个值,但是如果特征分成多的话,可以加以限制,具体的值可以通过交叉验证得到。

  • min_impurity_split: 节点划分最小不纯度。这个值限制了决策树的增长,如果某节点的不纯度(基于基尼系数,均方差)小于这个阈值,则该节点不再生成子节点。即为叶子节点。一般不推荐改动默认值1e-7。

上面决策树参数中最重要的包括最大特征数max_features, 最大深度max_depth, 内部节点再划分所需最小样本数min_samples_split和叶子节点最少样本数min_samples_leaf

五、参考

赞赏一杯咖啡
0%