sklearn adaboost_机器学习sklearn之随机森林

v2-eebb289cc0c267fe132bb6f53a147de9_1440w.jpg?source=172ae18b

大家好我是飘哥,这是飘哥整理的sklearn系列文章的学习笔记第二篇,我的开发环境时pycharm 2017.2,文中需要库如下:

python 3.7.1

scikit-learn 0.20.3

numpy 1.15.4

pandas 0.23.4

Matplotlib 3.0.2

Scipy 1.1.0

集成算法介绍

俗话说,三个臭皮匠顶个诸葛亮。类似的,如果集成一系列分类器的预测结果,也将会得到由于单个预测期的预测结果。一组预测期称为一个集合(ensemble),因此这一技术被称为集成学习(Ensemble Learning)。集成学习算法称作集成方法(Ensemble method)。

集成学习算法可以说是现在最火爆的机器学习算法。集成算法本身不是一个单独的机器学习算法,而是通过在数据上构建多个模型,集成所有模型的建模结果。

集成算法可以分为同质集成和异质集成,同质集成是集成算法中的采用同一类型的学习器,比如都是决策树;异质集成是集成算法中的采用由不同类型的学习器组成的。(目前比较流行的集成算法都是同质算法,而且基本都是基于决策树或者神经网络的)

他拥有广泛的应用前景,从市场营销到医疗保健保险,既可以用来市场模拟建模,统计客户来源,保留,流失,也可以用来预测疾病的风险和病患者的易感性。在现在的各种算法比赛中,随机森林,梯度提升树(gbdt),xgboost等集成算法的身影随处可及。在一些领域xgboost已经比梯度提升树更加好用了。

集成算法的目标是考虑多个评估器的建模结果,汇总后得到一个综合的结果,以此来获取比单个模型更好的回归或分类表现。

多个模型集成成为的模型叫做集成评估器(ensemble estimator)【业内也有叫集成模型】,组成集成评估器的每个模型都叫做基评估器(base estimator)【也有叫做子评估器】.通常来说,有三类集成算法:装袋法(bagging,减小方差),提升法(boosting,偏差)和stacking(改进预测)。

说明随机森林是一种bagging的方法, random forests 我们称为随机森林,其实随机森林是对装袋法的一种改进

v2-8cea61d6ffbd950510c2244ff81175bf_b.jpg

封袋法的核心思想是构建多个相互独立的评估器,然后对其预测进行平均或者多数表决原则来决定集成评估器的结果,封袋法模型的代表就是随机森林。

提升法中基评估器是相关的,是按照顺序一一构建,核心思想是结合弱评估器的力量一次次对难以评估的样本进行预测,从而构成一个强评估器,提升的代表模型有adaboost和梯度提升树。

v2-225c85cbe048b12072b5030e813d9a8e_b.jpg

上图就是装袋法模型,从图可以看出,每次取样建模,每次取样建模,每个模型相互独立,模型相互平行,封袋法是对这些模型预测的结果进行平均或者多数表决原则来决定集成评估器的结果。

v2-91b366f66cb7ae1adcdeda231d5f87a1_b.jpg

提升法中的评估模型都是相关的,要按照一定顺序,从上面箭头剋元看出,每次按照取样,建模,预测的流程完成,然后会告诉下一个取样步骤,我那些预测结果是错误的,在下一次采样的过程中那些预测错误的样本会有更高的权重,新的模型会基于那些错误的样本,有更强的学习技能。

Sklearn的集成算法

Sklearn的所有集成算法都在一个库中,叫做ensemble

ensemble.AdaBoostClassifier([…])AdaBoost分类ensemble.AdaBoostRegressor([base_estimator, …])AdaBoost回归ensemble.BaggingClassifier([base_estimator, …])封装分类器ensemble.BaggingRegressor([base_estimator, …])装袋回归器ensemble.ExtraTreesClassifier([…])extra-tree分类(超树,极端随机树)ensemble.ExtraTreesRegressor([n_estimators, …])extra-tree回归ensemble.GradientBoostingClassifier([loss, …])梯度提升分类ensemble.GradientBoostingRegressor([loss, …])梯度提升回归ensemble.IsolationForest([n_estimators, …])隔离森林ensemble.RandomForestClassifier([…])随机森林分类ensemble.RandomForestRegressor([…])随机森林回归ensemble.RandomTreesEmbedding([…])完全随机树的集成ensemble.VotingClassifier(estimators[, …])用于不合适评估器的软投票/多数规则分类器

集成算法中,有一半以上都是决策树的集成模型,可以想见决策树集成中必定是有很好的效果,我们将以随机森林为例,慢慢为大家揭开集成算法的面纱。

复习:机器学习sklearn系列之决策树:https://zhuanlan.zhihu.com/p/58868995

RandomForestClassifier

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_score=False, n_jobs=1, random_state=None, verbose=0, warm_start=False, class_weight=None)

这是一个类,sklearn.ensemble是类,RandomForestClassifier也是类。

随机森林是具有代表性的bagging集成算法,他的所有基评估器都有决策树,分类树组成的森林叫做随机森林分类器,回归树所集成的森林就叫做随机森林回归器,RandomForestClassifier是随机森林分类器。

基本参数

Ø criterion:

”gini” or “entropy”(default=”gini”)是计算属性的gini(基尼不纯度)还是entropy(信息增益),来选择最合适的节点。

splitter: ”best” or “random”(default=”best”)随机选择属性还是选择不纯度最大的属性,建议用默认。

Ø max_features:

选择最适属性时划分的特征不能超过此值。

当为整数时,即最大特征数;当为小数时,训练集特征数*小数;

if “auto”, then max_features=sqrt(n_features).

If “sqrt”, thenmax_features=sqrt(n_features).

If “log2”, thenmax_features=log2(n_features).

If None, then max_features=n_features.

Max features默认值是总特征个数开平方取整。

Ø max_depth:

(default=None)设置树的最大深度,默认为None,这样建树时,会使每一个叶节点只有一个类别,或是达到min_samples_split。

Ø min_samples_split:

根据属性划分节点时,每个划分最少的样本数。

Ø min_samples_leaf:

叶子节点最少的样本数。

Ø max_leaf_nodes:

(default=None)叶子树的最大样本数。

Ø min_weight_fraction_leaf:

(default=0) 叶子节点所需要的最小权值

Ø verbose:

(default=0) 是否显示任务进程

Ø min_impurity_decrease

限制信息增益的大小,信息增益小雨设定数值的分枝不会发生

(信息增益,前面说过决策树是依赖基尼系数和信息熵的来进行分枝,每分枝一层,不纯度越小,信息熵越小,父节点减去子节点的信息熵之差)

以上参数和决策树的参数一样,大家可以参看我另外一篇文章机器学习sklearn系列之决策树:https://zhuanlan.zhihu.com/p/58868995。

说明:单个决策树的准确率越高,随机森林的准确率越高,因为装袋法依赖于平均值或者少数服从多数原则来决定集成的结果。

独有参数

A. n_estimators=10:

决策树的个数(前面学习决策树的时候,是建立一棵树,现在是建立一个森林,这个参数就是告诉你这个森林里要包含多少棵树),越多越好,但是性能就会越差,至少100左右(0.22版本)可以达到可接受的性能和误差率。

这是森林中的数量,即基基评估器的数量,这个参数对随机森林的准确性影响是单调的,n_estimators越大,模型效果越好(模型效果越好,就是调参的重点)。但是相应的,任何模型都有决策边界,n_estimators达到一定程度后,随机森林的准确性往往不是上升(一开始会看到会飞速的上升,然后就是慢慢持平,或者有小的波动),而是开始波动,并且n_estimators越大建立的树越多,需要的计算量和内存也越大,训练的时间也会越来越长,对于这个参数,在训练难度和模型效果之间取得平衡最好。

bootstrap=True:是否有放回的采样。

oob_score=False:oob(out of band,带外)数据,即:在某次决策树训练中没有被bootstrap选中的数据。多单个模型的参数训练,我们知道可以用cross validation(cv)来进行,但是特别消耗时间,而且对于随机森林这种情况也没有大的必要,所以就用这个数据对决策树模型进行验证,算是一个简单的交叉验证。性能消耗小,但是效果不错。

(一)开始行动,建立森林

树模型有点简单易懂,可视化之后的树人人都能看懂,但是随机森林却无法可视化,所以为乐让大家更好的体会随机森林的效果,我们进行一个随机森林和单个决策树的效益比对,例子中我们依然使用红酒数据集。

#导入库需要的包

#导入决策树

from sklearn.tree import DecisionTreeClassifier

#导入随机森林

from sklearn.ensemble import RandomForestClassifier

#从sklearn中家载红酒库,sklearn中集成了多个数据集

from sklearn.datasets import load_wine

#导入需要的数据集

from sklearn.datasets import load_wine

wine = load_wine()

#打印红酒集中的特征值

print(wine.data)

#打印红酒集中的标签

print(wine.target)

输出结果:

[[1.423e+01 1.710e+00 2.430e+00 ... 1.040e+00 3.920e+00 1.065e+03]

[1.320e+01 1.780e+00 2.140e+00 ... 1.050e+00 3.400e+00 1.050e+03]

[1.316e+01 2.360e+00 2.670e+00 ... 1.030e+00 3.170e+00 1.185e+03]

...

[1.327e+01 4.280e+00 2.260e+00 ... 5.900e-01 1.560e+00 8.350e+02]

[1.317e+01 2.590e+00 2.370e+00 ... 6.000e-01 1.620e+00 8.400e+02]

[1.413e+01 4.100e+00 2.740e+00 ... 6.100e-01 1.600e+00 5.600e+02]]

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]

(可以看出标签是三分类的,0,1,2,如果有两个标签值就是2分类)

#复习sklearn建模基本流程

from sklearn.model_selection import train_test_split

# train_test_split的作用是 把数据集分解成训练数据集,测试数据集

# test_size=3是分解比例,分别是训练集70%和测试集30%,

xtrain,xtest,ytrain,ytest=train_test_split(wine.data,wine.target,test_size=3)

#random_state=0 ,决策树由于前面数据集的分解是随机的,

#导致由于每次生成的树都是不一样的,所以用这个参数保证每次产生的树一致

clf=DecisionTreeClassifier(random_state=0)

#在随机森林中random_state的作用是告诉代码帮我生成一个固定的森林吧

# 但是里面的每一课树长的都是不一样的。

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 froest:{}".format(score_r))

输出结果:

/anaconda3/lib/python3.7/site-packages/sklearn/ensemble/forest.py:246: FutureWarning: The default value of n_estimators will change from 10 in version 0.20 to 100 in 0.22.

single tree:1.0 random froest:1.0

(注意不用担心,第一行不是错误,他说在2.2版本后随机森林的参数n_estimators将会变成100了。

结果中的数据得到的是一样,是因为我们给了相同的训练集,需要说明的是随机森林的数值应该比决策树的值要好一些。为了理解我们用10组数据进行效果对比)

#画出随机森林和决策树在一组交叉验证下的效果对比

from sklearn.model_selection import cross_val_score

import matplotlib.pyplot as plt

#通过cross_val_score交叉验证

rfc=RandomForestClassifier(n_estimators=25)

rfc_s=cross_val_score(rfc,wine.data,wine.target,cv=10)

clf=DecisionTreeClassifier()

#通过cross_val_score交叉验证

clf_s=cross_val_score(clf,wine.data,wine.target,cv=10)

plt.plot(range(1,11),rfc_s,label="RandomForest")

plt.plot(range(1,11),clf_s,label="Decision Tree")

plt.legend()

plt.show()

输出结果:

v2-dd406367c4da00c3d93d0dfced275ac6_b.jpg

说明:通过10次交叉验证得到的曲线,橙色线是决策树,蓝色线是随机森林。可以看到随机森林的10次表现都是在决策树之上的。虽然偶尔决策树接近随机森林的效果,但是基本上随机森林的效果碾压决策树。

#画出随机森林和决策树在10组交叉验证下的效果对比

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="RandomForest")

plt.plot(range(1,11),clf_l,label="Decision Tree")

plt.legend()

plt.show()

输出结果:

v2-fa31f33acfa505ae674bda4e24b47e2d_b.jpg

说明:随着交叉验证的次数越来越多,曲线变得越来越平滑,说明效果差别不大,另外随机森林的表现已经远远超越了决策树。

是否注意到,单个决策树的运动轨迹和随机森林一致,再次验证但个决策树准确率越高,随机森林准确率越高,

#n_estimators的学习曲线

#建立200个模型,下面这段代码要运行很长时间3分钟左右,依赖于你的机器配置

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()

输出结果:

v2-5d3623a6dbb8fbaef47b945e82361f67_b.jpg

思考:随机森林用了什么方法,保证集成的效果一定好于单个分类器?

B. Random_state

random_state是一个随机种子,是在任意带有随机性的类或函数里作为参数来控制随机模式。当random_state取某一个值时,也就确定了一种规则。

random_state可以用于很多函数,我比较熟悉的是用于以下三个地方:1、训练集测试集的划分 2、构建决策树 3、构建随机森林

1、划分训练集和测试集的类train_test_split

 随机数种子控制每次划分训练集和测试集的模式,其取值不变时划分得到的结果一模一样,其值改变时,划分得到的结果不同。若不设置此参数,则函数会自动选择一种随机模式,得到的结果也就不同。

2、构建决策树的函数

clf = tree.DecisionTreeClassifier(criterion="entropy",random_state=30,splitter="random")

  其取值不变时,用相同的训练集建树得到的结果一模一样,对测试集的预测结果也是一样的;

  其值改变时,得到的结果不同;

  若不设置此参数,则函数会自动选择一种随机模式,每次得到的结果也就不同。

3、构建随机森林

clf = RandomForestClassifier(random_state=0)

 其取值不变时,用相同的训练集建森林得到的结果一模一样,对测试集的预测结果也是一样的;

  其值改变时,建森林得到的结果不同;

  若不设置此参数,则函数会自动选择一种随机模式,每次得到的结果也就不同。

总结:在需要设置random_state的地方给其赋一个值,当多次运行此段代码能够得到完全一样的结果,别人运行此代码也可以复现你的过程。若不设置此参数则会随机选择一个种子,执行结果也会因此而不同了。虽然可以对random_state进行调参,但是调参后在训练集上表现好的模型未必在陌生训练集上表现好,所以一般会随便选取一个random_state的值作为参数。

重要属性

有三个重要的属性estimators_(返回森林的列表),oob_score_ 以及feature_importances_特征的重要性)。

注意Oob_score指的是袋外估计准确率得分,随机森林为了确保森林中的每一棵树都不尽相同,所以对训练集采用放回抽样的方法,来组成新的训练集给新树进行训练,在这个过程中,因为有放回的随机抽样,所以会有一些数据从来都没有抽到,也就是说这些数据是在我们的训练集中,但是没有被随机森林抽取到拿去给这些树进行训练,就像当是掉在我们这些装的袋子外面,所以叫做outofbag oob数据,这些袋外数据虽然没有被训练到,但是我们也别浪费掉,sklearn可以用这些袋外数据测试模型,测试结果就是用.oob_score来导入。它本身也是导出模型精准度。

随机森林和的接口和决策树一样,依然有四个常用的接口:apply,fit,predict和score,除此之外,还需要注意随机森林的predict_proba接口,这个接口返回每个测试样本对应的被分到每个类标签的概率,标签有几个分类就返回几个概率,如果是二分问题,则predict_proba返回值大于0.5,被分为1,小于0.5被分为0 。传统的随机森林是利用袋装法的规则,平均或少数服从多数决定集成的效果,而sklearn中的随机森林平均每个样本对应的predict_proba返回的概率,得到一个平均概率,从而决定测试样本的分类。

以上属性,大家自行编写代码运行体验。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值