1 随机森林步骤
随机森林(Rand Forest)以决策树为基本单元,通过集成大量的决策树,减小过拟合的风险(减小模型方差),能做二分类、多分类和回归任务。
1)步骤
- 用有抽样放回的方法(bagging)从样本集中选取n个样本作为一个训练集
- 用抽样得到的样本集生成一棵决策树。在生成树的每一个结点:
- 随机不重复地选择d个特征
- 利用这d个特征分别对样本集进行划分,找到最佳的划分特征(可用基尼系数(CART数)、增益率(C4.5)或者信息增益(ID3)判别)
- 重复步骤1到步骤2共k次,k即为随机森林中决策树的个数。
- 用训练得到的随机森林对测试样本进行预测,并用票选法决定预测的结果。
2)随机含义
- 样本随机:训练每一个决策树使用的都是bootstrapping(拔靴法)产生的数据集
- 特征随机:在每一个树结点上进行结点划分时,考虑特征子空间
- 简单做法:从原始特征中随机不重复地抽取一些特征;
- 延伸做法:从原始特征中随机不重复地抽取一些特征,然后将某些特征线性合并,产生一系列组合特征。
3)随机森林结合策略
- 分类:投票,少数服从多数。每个树的预测结果就是给某个类别投一票,最终随机森林的输出值就是得票最多的类别
- 回归:平均法,每一个树都会输出一个实数,随机森林的输出值就是所有决策树输出值的均值
2 树的生成规则
- 1)如果训练集大小为N,对于每棵树而言,随机且有放回地从训练集中的抽取N个训练样本(这种采样方式称为bootstrap sample方法),作为该树的训练集;
每棵树的训练集都是不同的,而且里面包含重复的训练样本。
为什么要随机抽样训练集:如果不进行随机抽样,每棵树的训练集都一样,那么最终训练出的树分类结果也是完全一样的,这样的话完全没有bagging的必要;
为什么要有放回地抽样:如果不是有放回的抽样,那么每棵树的训练样本都是不同的,都是没有交集的,这样每棵树都是"有偏的",都是绝对"片面的",也就是说每棵树训练出来都是有很大的差异的;而随机森林最后分类取决于多棵树(弱分类器)的投票表决,这种表决应该是"求同",所以说使用完全不同的训练集来训练每棵树这样对最终分类结果是没有帮助的,这样无异于是"盲人摸象"。
- 2)如果每个样本的特征维度为M,指定一个常数m<<M,随机地从M个特征中选取m个特征子集,每次树进行分裂时,从这m个特征中选择最优的;
- 3)每棵树都尽最大程度的生长,并且没有剪枝过程。
随机森林分类效果(错误率)与两个因素有关:
- 森林中任意两棵树的相关性:相关性越大,则错误率越大;
- 森林中每棵树的分类能力:每棵树的分类能力越强,则整个森林的错误率就越低。
则随机森林有着:减小特征选择个数m,树的相关性和分类能力也会相应的降低;增大m,两者也会随之增大。所以关键是如何选择最优的m(或者是范围),这也是随机森林唯一的一个参数。
3 优缺点
优点:
- 每棵树都选择部分样本及部分特征,一定程度避免过拟合;
- 每棵树随机选择样本并随机选择特征,使得具有很好的抗噪能力,性能稳定;
- 能处理很高维度的数据,并且不用做特征选择(不需要降维处理);
- 适合并行计算;
- 实现比较简单。
缺点:
- 参数较复杂;
- 模型训练和预测都比较慢。
- 在某些噪音比较大的样本集上,RF模型容易陷入过拟合。
- 取值划分比较多的特征容易对RF的决策产生更大的影响,从而影响拟合的模型的效果。
4 sklearn中的随机森林模型
在sklearn机器模型中,Radom Forest函数为:
from sklearn.ensemble import RandomForestClassifier,RandomForestRegressor
RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None,
min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0,
max_features=’auto’, max_leaf_nodes=None, min_impurity_decrease=0.0,
min_impurity_split=None, bootstrap=True, oob_score=False, n_jobs=1,
random_state=None,verbose=0, warm_start=False, class_weight=None)
RandomForestRegressor(n_estimators=100, *, criterion='mse', max_depth=None,
min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0,
max_features='auto', max_leaf_nodes=None, min_impurity_decrease=0.0,
min_impurity_split=None, bootstrap=True, oob_score=False, n_jobs=None,
random_state=None, verbose=0, warm_start=False, ccp_alpha=0.0, max_samples=None)
参数作用:
n_estimators:数值型取值
含义:森林中决策树的个数,默认是10
criterion:字符型取值
含义:采用何种方法度量分裂质量,信息熵或者基尼指数,默认是基尼指数
max_features:取值为int型, float型, string类型, or None(),默认"auto"
含义:寻求最佳分割时的考虑的特征数量,即特征数达到多大时进行分割。
int:max_features等于这个int值
float:max_features是一个百分比,每(max_features * n_features)特征在每个分割出被考虑。
"auto":max_features等于sqrt(n_features)
"sqrt":同等于"auto"时
"log2":max_features=log2(n_features)
None:max_features = n_features
max_depth:int型取值或者None,默认为None
含义:树的最大深度
min_samples_split:int型取值,float型取值,默认为2
含义:分割内部节点所需的最少样本数量
int:如果是int值,则就是这个int值
float:如果是float值,则为min_samples_split * n_samples
min_samples_leaf:int取值,float取值,默认为1
含义:叶子节点上包含的样本最小值
int:就是这个int值
float:min_samples_leaf * n_samples
min_weight_fraction_leaf : float,default=0.
含义:能成为叶子节点的条件是:该节点对应的实例数和总样本数的比值,至少大于这个min_weight_fraction_leaf值
max_leaf_nodes:int类型,或者None(默认None)
含义:最大叶子节点数,以最好的优先方式生成树,最好的节点被定义为杂质相对较少,即纯度较高的叶子节点
min_impurity_split:float取值
含义:树增长停止的阀值。一个节点将会分裂,如果他的杂质度比这个阀值;如果比这个值低,就会成为一个叶子节点。
min_impurity_decrease:float取值,默认0.
含义:一个节点将会被分裂,如果分裂之后,杂质度的减少效果高于这个值。
bootstrap:boolean类型取值,默认True
含义:是否采用有放回式的抽样方式
oob_score:boolean类型取值,默认False
含义:是否使用袋外样本来估计该模型大概的准确率
n_jobs:int类型取值,默认1
含义:拟合和预测过程中并行运用的作业数量。如果为-1,则作业数设置为处理器的core数。
class_weight:dict, list or dicts, "balanced"
含义:如果没有给定这个值,那么所有类别都应该是权重1
对于多分类问题,可以按照分类结果y的可能取值的顺序给出一个list或者dict值,用来指明各类的权重.
"balanced"模式,使用y值自动调整权重,该模式类别权重与输入数据中的类别频率成反比,即n_samples / (n_classes * np.bincount(y)),分布为第n个类别对应的实例数。
"balanced_subsample"模式和"balanced"模式类似,只是它计算使用的是有放回式的取样中取得样本数,而不是总样本数
如下图信息,给定数据,使用这个数据集,利用随机森林思想,完成随机森林的创建及使用
并行地训练多颗回归树,对样本进行预测时,所有回归树同时预测,取均值作为输出
并行地训练多颗分类树,对样本进行预测时,所有分类树同时预测,按照投票方式输出
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
df = pd.DataFrame([[0,1],[1,1],[2,1],[3,-1],[4,-1],
[5,-1],[6,1],[7,1],[8,1],[9,-1]])
X = df.iloc[:,[0]]
Y = df.iloc[:,-1]
model = RandomForestClassifier(n_estimators=50).fit(X,Y)
model.predict(X)