目录
一、集成学习
1.Bagging
2.Boosting
二、随机森林
1.基本概念
2.注意点
3.API
4.python实例
随机森林(Random Forest)是集成算法Bagging的代表算法,在学习随机森林之前先了解一下什么是集成学习(Ensemble Learning )。
一、集成学习
集成算法是构建多个学习器,通过一定策略结合来完成学习任务。如以决策树为个体学习器的集成构造出随机森林。集成学习的思想是将这些弱学习器的偏置或方差结合起来,从而创建一个强学习机,获得更好的性能按照个体学习器之间的关系。
多个模型集成成为的模型叫做集成评估器(ensemble estimator),组成集成评估器的每个模型都叫做基评估器(base estimator)
通常来说,有三类集成算法:装袋法(Bagging),提升法(Boosting)和stacking。
- 装袋法的核心思想是构建多个相互独立的评估器,然后对其预测进行平均或多数表决原则来决定集成评估器的结果。装袋法的代表模型就是随机森林。
- 提升法中,基评估器是相关的,是按顺序一一构建的。其核心思想是结合弱评估器的力量一次次对难以评估的样本进行预测,从而构成一个强评估器。提升法的代表模型有Adaboost和梯度提升树。
1.Bagging
Bagging算法(Bootstrap Aggregation)主要对样本训练集合进行随机化抽样,通过反复的抽样训练新的模型,最终在这些模型的基础上取平均。(平均,并联)
它的公式是:
1.首先对训练数据集进行多次采样,保证每次得到的采样数据都是不同的
2.分别训练多个模型,例如树模型(理论上树越多效果越好 实际超过一定数量呈现上下浮动)
3.预测时需得到所有模型结果再进行集成
2.Boosting
属于迭代算法,它通过不断地使用一个弱学习器弥补前一个弱学习器的“不足”的过程,来串行地构造一个较强的学习器,这个强学习器能够使目标函数值足够小。基本思想是先赋予每个训练样本相同的概率,然后进行T次迭代,每次迭代后,对分类错误的样本加大权重(重采样),使得在下一次的迭代中更加关注这些样本。(加权,串联)(提升)
它的公式是:
Bagging 和 Boosting 算法异同
Bagging | Boosting | |
样本选择 | 训练集是在原始集中有放回选取的 从原始集中选出的各轮训练集之间是独立的 | 每一轮的训练集不变,只是训练集中每个样例在分类器中的权重发生变化 而权值是根据上一轮的分类结果进行调整 |
样例权重 | 均匀取样 每个样例的权重相等 | 根据错误率不断调整样例的权值 错误率越大则权重越大 |
预测函数 | 所有预测函数的权重相等 | 每个弱分类器都有相应的权重 对于分类误差小的分类器会有更大的权重 |
并行计算 | 各个预测函数可以并行生成 | 各个预测函数只能顺序生成,因为后一个模型参数需要前一轮模型的结果 |
sklearn 中的集成算法模块 ensemble
类 | 类的功能 |
ensemble.AdaBoostClassififier | AdaBoost分类 |
ensemble.AdaBoostRegressor | Adaboost回归 |
ensemble.BaggingClassififier | 装袋分类器 |
ensemble.BaggingRegressor | 装袋回归器 |
ensemble.ExtraTreesClassififier | Extra-trees分类(超树,极端随机树) |
ensemble.ExtraTreesRegressor | Extra-trees回归 |
ensemble.GradientBoostingClassififier | 梯度提升分类 |
ensemble.GradientBoostingRegressor | 梯度提升回归 |
ensemble.IsolationForest | 隔离森林 |
ensemble.RandomForestClassifier | 随机森林分类 |
ensemble.RandomForestRegressor | 随机森林回归 |
ensemble.RandomTreesEmbedding | 完全随机树的集成 |
ensemble.VotingClassififier | 用于不合适估算器的软投票/多数规则分类器 |
二、随机森林
1.基本概念
随机森林由LeoBreiman(2001)提出,从原始训练样本集N中有放回地重复随机抽取k个样本生成新的训练样本集合,然后根据自助样本集生成k个分类树组成随机森林,新数据的分类结果按分类树投票多少形成的分数而定。(Bagging + 决策树)
随机:数据采样随机,特征选择随机(保证泛化能力)
森林:多个决策树并行放在一起
2.注意点
① 在构建决策树的过程中是不需要剪枝的。
② 整个森林的树的数量和每棵树的特征需要人为进行设定。
③ 构建决策树的时候分裂节点的选择是依据最小基尼系数的。
3.API
在集成算法模块ensemble中,随机森林(RF)的分类器是RandomForestClassifier和回归器RandomForestRegressor。RF的参数也包括两部分,第一部分是Bagging框架的参数,第二部分是一棵CART决策树的参数。具体的参数参考随机森林分类器的函数原型:
class sklearn.ensemble.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_scor e= False
, n_jobs = None
, random_state = None
, verbose = 0
, warm_start = False
, class_weight = None )
重要参数
参数 | 解释 |
n_estimators | 森林中树木的数量,默认值是100 |
criterion | 不纯度的衡量指标,有基尼系数(gini)和信息熵两种选择 |
oob_score | 是否采用袋外样本来评估模型的好坏。袋外分数可以反应一个模型拟合后的泛化能力。 |
max_depth | 树的最大深度,超过最大深度的树枝都会被剪掉 |
min_samples_leaf | 一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分枝就不会发生 |
min_samples_split | 一个节点必须要包含至少min_samples_split个训练样本,这个节点才允许被分枝,否则分枝就不会发生 |
max_features | max_features限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃,默认值为总特征个数开平方取整 |
min_impurity_decrease | 限制信息增益的大小,信息增益小于设定数值的分枝不会发生 |
袋外样本oob
对训练数据进行Boostrap(有放回的随机抽样)抽样时,若抽取数为 n,那么每次抽取数据时每个数据被选取的概率为 1/n ,当我们的对数据进行 n 采样时,该数据没有被抽到的概率为
当,那么有
故而有 1/e ≈ 0.368 的数据没有被选择,这大约36.8%的数据就被称为袋外数据,有了袋外数据的存在,使得我们在训练决策树时无须将数据分为训练数据和测试数据,而是直接将袋外数据(out of bag)作为“测试数据集”。也就是说没有必要对其进行交叉验证或者用一个独立的测试集来获得误差的一个无偏估计,它可以在其内部进行评估,也就是说在生成的过程中就可以对误差建立一个无偏估计。在构建每棵树时,我们对训练集使用看不同的bootstrap sample。所以对于每棵树而言,大约有1/3的训练实例没有参与第k棵树的生成,它们称为第k的oob样本。那么基于每棵决策树的oob样本,就能计算出袋外错误率(Out-of-bag error)。
重要属性
属性 | 解释 |
.estimators_ | 返回建立森林的列表 |
.oob_score_ | 使用袋外估计获得的训练数据集的得分 |
.feature_importances_ | 返回各个特征重要性 |
接口
接口 | 解释 |
fit | 训练 |
predict | 返回每个测试样本对应的被分到每一类标签的概率,标签有几个分类就返回几个概率 |
score | 返回精确度 |
以上参数中n_estimators、criterion、oob_score属于Bagging框架的参数,Bagging框架的参数中最重要的包括最大特征数max_features, 最大深度max_depth, 内部节点再划分所需最小样本数min_samples_split和叶子节点最少样本数min_samples_leaf。其余参数、属性和接口等不再赘述,详细可参考scikit-learn中文社区中关于随机森林分类器的解释sklearn.ensemble.RandomForestClassifier-scikit-learn中文社区
sklearn的基本建模流程
from sklearn.tree import RandomForestClassifier #导入随机森林模块
rfc = RandomForestClassifier() #实例化
rfc = rfc.fit(X_train,y_train) #用训练集数据训练模型
result = rfc.score(X_test,y_test) #导入测试集,从接口中调用需要的信息
4.python实例
使用红酒数据集对比决策树和随机森林建模效果
# 导入需要的包
%matplotlib inline
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_wine
#导入需要的数据集
wine = load_wine()
wine.target#0 1 2三分类
from sklearn.model_selection import train_test_split
Xtrain, Xtest, Ytrain, Ytest = train_test_split(wine.data,wine.target,test_size=0.3)#划分训练集测试集
clf = DecisionTreeClassifier(random_state=0)#决策树建模
rfc = RandomForestClassifier(random_state=0)#随机森林建模
clf = clf.fit(Xtrain,Ytrain)
rfc = rfc.fit(Xtrain,Ytrain)
score_c = clf.score(Xtest,Ytest)
score_r = rfc.score(Xtest,Ytest)
print("Single Tree:{}".format(score_c),"Random Forest:{}".format(score_r))#随机森林的得分比单颗决策树高 from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
#画出随机森林和决策树在十组交叉验证下的效果对比
#交叉验证:是数据集划分为n分,依次取每一份做测试集,每n-1份做训练集,多次训练模型以观测模型稳定性的方法
rfc_l = []
clf_l = []
for i in range(10):
rfc = RandomForestClassifier(n_estimators=25) rfc_s = cross_val_score(rfc,wine.data,wine.target,cv=10).mean() rfc_l.append(rfc_s) clf = DecisionTreeClassifier() clf_s = cross_val_score(clf,wine.data,wine.target,cv=10).mean() clf_l.append(clf_s)
plt.plot(range(1,11),rfc_l,label = "Random Forest")
plt.plot(range(1,11),clf_l,label = "Decision Tree")
plt.legend()
plt.show()
由图像看出单个决策树的波动轨迹和随机森林一致。且单个决策树的准确率越高,随机森林的准确率也会越高。
接下来绘制 n_estimators 的学习曲线,观察 n_estimators 取何值时模型拟合效果最好:
superpa = []
for i in range(200): rfc = RandomForestClassifier(n_estimators=i+1,n_jobs=-1) rfc_s = cross_val_score(rfc,wine.data,wine.target,cv=10).mean() superpa.append(rfc_s)
print(max(superpa),superpa.index(max(superpa)))
plt.figure(figsize=[20,5])
plt.plot(range(1,201),superpa)
plt.show()
以乳腺癌数据再举一例:
#导入需要的库
from sklearn.datasets import load_breast_cancer #导入乳腺癌数据
from sklearn.ensemble import RandomForestClassifier #导入随机森林分类器
from sklearn.model_selection import cross_val_score#模型选择中的交叉验证
import pandas as pd
import numpy as np data = load_breast_cancer() #导入数据集,探索数据
data.data.shape #乳腺癌数据集有569条记录,30个特征,单看维度虽然不算太高,但是样本量非常少。过拟合的情况可能存在。
data.target #查看数据标签0 1二分类 #进行一次简单的建模,看看模型本身在数据集上的效果
rfc = RandomForestClassifier(n_estimators=100,random_state=90)#100棵树的随机森林
score_pre = cross_val_score(rfc,data.data,data.target,cv=10).mean()#交叉验证十次
score_pre
#0.9648809523809524
从结果可以看到,随机森林在乳腺癌数据上的表现本就还不错,在现实数据集上,基本上不可能什么都不调就看到95%以上的准确率