(十二)集成学习与随机森林

一,什么是集成学习

什么是集成学习

把不同的算法都运用起来对同一个东西进行决策,再用这个算法对其他算法进行投票,少数服从多数,票数多的胜。

比如生活中购买东西,我们一般不会只找一个人推荐,而是找多个人的评价再做出决定,这就是集成学习。

即集成不同人的意见进行决策。

其实,样本整体相当于一个病人,样本里的数据就是病人的特征,算法可以看作是治病方案并决定怎么才算是生病,判断是否病人有病,当患者有重大疾病,通常需要听取很多医生的建议才可以下定论。

因此设计程序只需要使用不同的算法对同一数据进行分析。

sklearn包中包含算法:Voting Classifier

数据生成:

import numpy as np

import matplotlib.pyplot as plt

from sklearn import datasets

X, y = datasets.make_moons(n_samples=500, noise=0.3, random_state=42)

plt.scatter(X[y==0,0], X[y==0,1])

plt.scatter(X[y==1,0], X[y==1,1])

plt.show()

手动分类决策:

使用逻辑回归

from sklearn.model_selection import train_test_split

from sklearn.linear_model import LogisticRegression

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)

log_clf = LogisticRegression()

log_clf.fit(X_train, y_train)

log_clf.score(X_test, y_test)

使用SVM

from sklearn.svm import SVC

svm_clf = SVC()

svm_clf.fit(X_train, y_train)

svm_clf.score(X_test, y_test)

使用决策树

from sklearn.tree import DecisionTreeClassifier

dt_clf = DecisionTreeClassifier(random_state=666)

dt_clf.fit(X_train, y_train)

dt_clf.score(X_test, y_test)

投票

y_predict1 = log_clf.predict(X_test)

y_predict2 = svm_clf.predict(X_test)

y_predict3 = dt_clf.predict(X_test)

y_predict = np.array((y_predict1 + y_predict2 + y_predict3) >= 2, dtype='int')

检查投票结果:

from sklearn.metrics import accuracy_score

accuracy_score(y_test, y_predict)

提高了数据准确度

sklearn随机森林决策:

from sklearn.ensemble import VotingClassifier

#类似pipline

voting_clf = VotingClassifier(estimators=[  #估计器

    ('log_clf', LogisticRegression()),

    ('svm_clf', SVC()),

    ('dt_clf', DecisionTreeClassifier(random_state=666))],

                             voting='hard')

voting_clf.fit(X_train, y_train)

voting_clf.score(X_test, y_test)

二,Soft Voting Classifier

投票要考虑到投票的权重问题,比如唱歌比赛中,观众投票占的比重肯定是低于专业评委的比重的,也就是专业评委投的票更具有权威性,因此他们的权重会高一些,这就是软投票。硬投票就是把所有的投票人不论专业不专业,无论他们决策水平怎么样都一视同仁。

在soft中,还要考虑算法有多大的概率确认是某类,这个模型越确定投给某一类,我们就更相信它。

这样,我们就要求集合的每一个模型都可以估计概率->逻辑回归,使用predict_prob函数进行概率预测。可以回顾哪些算法支持概率预测:

  • 逻辑回归本身就是基于概率模型的
  • KNN也可以支持概率预测,并且可以根据距离加入权重
  • 决策树算法类似KNN,可以用占比例最大的数据点数量/叶子中所有数据点的数量表示概率
  • SVM也可以计算概率,SVC中有自带的probility进行预测,但会牺牲一定的计算时间

程序实现:

数据同上

voting_clf2 = VotingClassifier(estimators=[

    ('log_clf', LogisticRegression()),

    ('svm_clf', SVC(probability=True)),

    ('dt_clf', DecisionTreeClassifier(random_state=666))],

                             voting='soft')

voting_clf2.fit(X_train, y_train)

voting_clf2.score(X_test, y_test)

三,Bagging和Pasting

虽然有很多机器学习方法,但是从投票的角度看,仍然不够

要创建更多的子模型,集成更多的子模型的意见,并且子模型之间不能一致,要有差异性!

如何创建差异性?

每个模型只看样本数据的一部分。

比如,有500个样本数据,5个子模型,每个子模型只看100个样本数据。

如果我们只有一个子模型,整体准确率是51%

如果有3个子模型,整体准确率是0.51^3+C(3,2)*0.51^2*0.49=51.5%

如果有500个子模型,整体准确率是65.6%

随着子模型的增加,整体的准确率会提高

而如果每个子模型的准确率是60%

500个子模型的准确率是99.999%(理论上)

因此使用集成学习的频率很高

取样:放回取样(Bagging)(更常用),不放回取样(Pasting)

统计学中的放回取样叫做:bootstrap

程序实现:

数据同上,产生训练与测试数据集

使用Bagging:

from sklearn.tree import DecisionTreeClassifier

from sklearn.ensemble import BaggingClassifier

#在这里集成的模型都是决策树模型,因为决策树非参数模型更容易产生差异比较大的子模型

bagging_clf = BaggingClassifier(DecisionTreeClassifier(),

                           n_estimators=500, max_samples=100,

                           bootstrap=True)

#n_estimators表示集成多少决策树模型,max_samples表示每个子模型要看多少样本,bootstrap表示放回或者不放回取样,有很多决策树,因此叫做随机森林

bagging_clf.fit(X_train, y_train)

bagging_clf.score(X_test, y_test)

四,oob(Out-of-Bag)和更多关于Bagging的讨论

对于放回取样会导致有一些样本很可能没有取到,平均有37%的样本取不到,就是oob

不使用测试数据集,而是使用这部分没有被取样的样本oob作为测试/验证数据集

使用sklearn中的oob_score_属性

数据样本依旧如上,但是没有train_test_split这一步

使用oob

from sklearn.tree import DecisionTreeClassifier

from sklearn.ensemble import BaggingClassifier

bagging_clf = BaggingClassifier(DecisionTreeClassifier(),

                               n_estimators=500, max_samples=100,

                               bootstrap=True, oob_score=True)

bagging_clf.fit(X, y)

bagging_clf.oob_score_

Bagging的思路非常容易进行并行化处理

因此可以用到n_jobs进行并行操作

bagging_clf = BaggingClassifier(DecisionTreeClassifier(),

                               n_estimators=500, max_samples=100,

                               bootstrap=True, oob_score=True,

                               n_jobs=-1) #使用所有的核

bagging_clf.fit(X, y)

Bagging的更多讨论

产生差异化的方式还有:

  • 针对特征进行随机采样(Random Subspaces) 样本特别多的情况下,比如图像
  • 即针对样本又针对特征进行随机采样(Random Patches),表示即在行的方向上随机又在列的方向上随机,因为取样的图像像补丁,因此得名。

在特征空间上进行的采样也叫做(bootsrap_features)

random_subspaces_clf = BaggingClassifier(DecisionTreeClassifier(),

                               n_estimators=500, max_samples=500, #相当于没有对样本数据随机

                               bootstrap=True, oob_score=True,

                               max_features=1, bootstrap_features=True)

#max_features表示每次看几个特征,bootstrap_features=True表示放回采样

random_subspaces_clf.fit(X, y)

random_subspaces_clf.oob_score_

五,随机森林和Extra-Trees

随机的提取样本及其特征,集成了很多的决策树,因此被称为随机森林

使用以上数据集:

from sklearn.ensemble import RandomForestClassifier

rf_clf = RandomForestClassifier(n_estimators=500, oob_score=True, random_state=666,         

n_jobs=-1)

rf_clf.fit(X, y)

rf_clf2 = RandomForestClassifier(n_estimators=500, max_leaf_nodes=16,

oob_score=True, random_state=666, n_jobs=-1)

rf_clf2.fit(X, y)

rf_clf2.oob_score_

Extra-Trees

极其随机的随机森林,决策树在节点划分上,使用随机的特征和随机的阈值,提供额外的随机性,抑制过拟合(随机取数据使得大多数子模型不会被几个数据带偏),但是增大了bias(增大偏差,抑制方差),并且这个方式还会增加训练速度(相较于随机森林)

from sklearn.ensemble import ExtraTreesClassifier

et_clf = ExtraTreesClassifier(n_estimators=500, bootstrap=True, oob_score=True,

random_state=666, n_jobs=-1)

et_clf.fit(X, y)

使用集成学习解决回归问题:

from sklearn.ensemble import BaggingRegressor

from sklearn.ensemble import RandomForestRegressor

from sklearn.ensemble import ExtraTreesRegressor

六,Ada-Boosting和Gradient-Boosting

Boosting:增强推动

也是集成多个子模型,但是这些子模型彼此间不是独立的关系,而是,每个子模型都在尝试增强(Boosting)整体的效果

AdaBoosting是什么?

假设解决的是回归问题,上图中浅色的蓝点表示模型成功预测的点,深蓝色的点表示没有被预测到。之后我们重新学习数据样本时,让浅蓝色样本点所占比列小一点(因为已经可以学到了),让深蓝色样本点的学习权重更大一些,这样慢慢的就会逐渐接近真实模型。

因此在ada-boosting中,他会认为有一些数据点是重要的,另外一些不重要,之后从一个子模型延申出很多的子模型,这些子模型看的是同样的数据样本点,只不过他们对数据点赋予的权重是不同的,这样就形成了差异性,最后再让这些子模型综合投票进行预测。

程序实现:

使用以上数据集

from sklearn.tree import DecisionTreeClassifier

from sklearn.ensemble import AdaBoostClassifier #调用分类器

#随机森林是集成学习的一种方法,所以是ensemble

ada_clf = AdaBoostClassifier(

    DecisionTreeClassifier(max_depth=2), n_estimators=500)

ada_clf.fit(X_train, y_train)

通过调正参数还可以进一步提高

Gradient Boosting是什么?

所有的算法都会出错误

某算法针对所有的数据集进行训练,得到一个模型m1,产生的错误是e1;

现在针对e1训练出第二个模型m2,产生的错误是e2;

再针对e2训练第三个模型m3,产生的错误是e3;

……

最终的预测结果是:m1+m2+m3+…

左侧列从上到下依次是图1-3,右侧列从上到下依次是图4-6

图一是第一次预测的模型,得到的绿色线就是m1,图二是图一模型犯的错误e1,

程序实现:

from sklearn.ensemble import GradientBoostingClassifier

gb_clf = GradientBoostingClassifier(max_depth=2, n_estimators=30)

gb_clf.fit(X_train, y_train)

Boosting解决回归问题:

from sklearn.ensemble import AdaBoostRegressor

from sklearn.ensemble import GradientBoostingRegressor

七,Stacking集成学习

对于voting classifier的思路是使用几个不同的算法,每个算法都进行预测,之后综合这几个算法的结果就可以。分类问题可以少数服从多数,回归问题可以取平均值。

Stacking的思路是:同样使用几个模型进行预测,但是我们不用预测结果进行投票,而是使用预测结果训练一个新的模型,再利用新的模型的预测结果作为最终结果。如下图所示:

回归的模型也可以用来预测,只需要回归算出概率就可以。同样回归问题也可以转换为分类问题,就是求取平均值实现。

Stacking要做的就是把训练数据集分为俩分,其中一份用来训练三个模型(如下图),另外的数据训练上边的模型(stacking)

更复杂的Stacking模型:

太复杂容易过拟合。这个模型已经接近神经网络了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值