机器学习之集成学习和随机森林

一、集成学习

集成学习就是合并多个分类器的预测。一般会在一个项目快结束的时候使用集成算法,一旦建立了一些好的分类器,就可以使用集成把它们合并成一个更好的分类器。
著名的集成方法:投票分类、bogging、pasting、boosting、stacking、和一些其它算法。

1.1 投票分类(少数服从多数)

令人惊奇的是这种投票分类器得出的结果经常会比集成中最好的一个分类器结果更好。
事实上,即使每一个分类器都是一个弱学习器(意味着它们也就比瞎猜好点),集成后仍然是一个强学习器(高准确率),只要有足够数量的弱学习者,他们就足够多样化。

如果每一个分类器都在同一个数据集上训练,会导致犯同一种类型的错误。相比较而言,每个分类器在不同的数据集上训练,集成后的结果会更好。
下面使用moons数据集,训练三个分类器,使用集成算法。

from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split

moons = make_moons(noise=0.3, random_state=0)
X, y = moons
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.4, random_state=42)
# print(X_train[10], y_train[0])
[-0.65805008 -0.12944211] 0
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import VotingClassifier #软投票/多数规则分类器
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC

log_clf = LogisticRegression()
rnd_clf = RandomForestClassifier()
svm_clf = SVC()

voting_clf = VotingClassifier(estimators=[("lr", log_clf), ("rf", rnd_clf), ("svc", svm_clf)], voting="hard")
#voting:"soft"/"hard"
#硬投票,默认"hrad"。"hard",使用预测的类标签进行多数规则投票。
#软投票,"soft",基于预测概率之和的argmax来预测类别标签,这推荐用于经过良好校准的分类器的集合。

# voting_clf.fit(X_train, y_train)

测一下准确率:

from sklearn.metrics import accuracy_score #分类准确度得分

for clf in (log_clf, rnd_clf, svm_clf, voting_clf):
  clf.fit(X_train, y_train)
  y_pred = clf.predict(X_test)
  print(clf.__class__.__name__, accuracy_score(y_test, y_pred))
LogisticRegression 0.875
RandomForestClassifier 0.925
SVC 0.95
VotingClassifier 0.95

1.2 Bagging和Pasting

对每一个分类器都使用相同的训练算法,但是在不同的训练集上去训练它们。有放回采样被称为装袋(Bagging,是 bootstrap aggregating 的缩写)。无放回采样称为粘贴(pasting)

聚合函数通常对分类是统计模式(例如硬投票分类器),对回归是平均

API:对分类是BaggingClassifier
对于回归是`BaggingRegressor

接下来的代码训练了一个 500 个决策树分类器的集成,每一个都是在数据集上有放回采样 100 个训练实例下进行训练(这是 Bagging 的例子,如果你想尝试 Pasting,就设置bootstrap=False)

n_jobs参数告诉 sklearn 用于训练和预测所需要 CPU 核的数量。(-1 代表着 sklearn 会使用所有空闲核)

总体而言,Bagging 通常会导致更好的模型

from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier

bag_clf = BaggingClassifier(DecisionTreeClassifier(), n_estimators=500, max_samples=50, oob_score=True, bootstrap=True, n_jobs=-1)

bag_clf.fit(X_train, y_train)
BaggingClassifier(base_estimator=DecisionTreeClassifier(class_weight=None,
                                                        criterion=‘gini‘,
                                                        max_depth=None,
                                                        max_features=None,
                                                        max_leaf_nodes=None,
                                                        min_impurity_decrease=0.0,
                                                        min_impurity_split=None,
                                                        min_samples_leaf=1,
                                                        min_samples_split=2,
                                                        min_weight_fraction_leaf=0.0,
                                                        presort=False,
                                                        random_state=None,
                                                        splitter=‘best‘),
                  bootstrap=True, bootstrap_features=False, max_features=1.0,
                  max_samples=50, n_estimators=500, n_jobs=-1, oob_score=True,
                  random_state=None, verbose=0, warm_start=False)
  1. 在 sklearn 中,你可以在训练后需要创建一个BaggingClassifier来自动评估时设置oob_score=True来自动评估。而不需要使用交叉验证或者使用单独的验证集
bag_clf.oob_score_
0.8833333333333333
# 比较一下
y_pred = bag_clf.predict(X_test)
accuracy_score(y_test, y_pred)

0.95

1.3 随机贴片和随机子空间

BaggingClassifier也支持采样特征。它被两个超参数max_features和bootstrap_features控制。他们的工作方式和max_samples和bootstrap一样,但这是对于特征采样而不是实例采样。因此,每一个分类器都会被在随机的输入特征内进行训练。

当你在处理高维度输入下(例如图片)此方法尤其有效。对训练实例和特征的采样被叫做随机贴片。保留了所有的训练实例(例如bootstrap=False和max_samples=1.0),但是对特征采样(bootstrap_features=True并且/或者max_features小于 1.0)叫做随机子空间。

采样特征导致更多的预测多样性,用高偏差换低方差。

1.4 boosting(提升)

提升(Boosting,最初称为假设增强)指的是可以将几个弱学习者组合成强学习者的集成方法。
对于大多数的提升方法的思想就是按顺序去训练分类器,每一个都要尝试修正前面的分类。
现如今已经有很多的提升方法了,但最著名的就是 Adaboost(适应性提升,是 Adaptive Boosting 的简称) 和 Gradient Boosting(梯度提升)。让我们先从 Adaboost 说起。

1.4.1 Adaboost

使一个新的分类器去修正之前分类结果的方法就是对之前分类结果不对的训练实例多加关注。这导致新的预测因子越来越多地聚焦于这种情况。这是 Adaboost 使用的技术。
举个例子,去构建一个 Adaboost 分类器,第一个基分类器(例如一个决策树)被训练然后在训练集上做预测,在误分类训练实例上的权重就增加了。第二个分类机使用更新过的权重然后再一次训练,权重更新,以此类推

sklearn 通常使用 Adaboost 的多分类版本 SAMME(这就代表了 分段加建模使用多类指数损失函数)。如果只有两类别,那么 SAMME 是与 Adaboost 相同的。如果分类器可以预测类别概率(例如如果它们有predict_proba()),如果 sklearn 可以使用 SAMME 叫做SAMME.R的变量(R 代表“REAL”),这种依赖于类别概率的通常比依赖于分类器的更好。

from sklearn.ensemble import AdaBoostClassifier

ada_clf = AdaBoostClassifier(DecisionTreeClassifier(max_depth=1), n_estimators=200,algorithm="SAMME.R", learning_rate=0.5)
ada_clf.fit(X_train, y_train)
AdaBoostClassifier(algorithm=‘SAMME.R‘,
                   base_estimator=DecisionTreeClassifier(class_weight=None,
                                                         criterion=‘gini‘,
                                                         max_depth=1,
                                                         max_features=None,
                                                         max_leaf_nodes=None,
                                                         min_impurity_decrease=0.0,
                                                         min_impurity_split=None,
                                                         min_samples_leaf=1,
                                                         min_samples_split=2,
                                                         min_weight_fraction_leaf=0.0,
                                                         presort=False,
                                                         random_state=None,
                                                         splitter=‘best‘),
                   learning_rate=0.5, n_estimators=200, random_state=None)

1.4.2 梯度提升(Gradient Boosting)
另一个非常著名的提升算法是梯度提升。与 Adaboost 一样,梯度提升也是通过向集成中逐步增加分类器运行的,每一个分类器都修正之前的分类结果。然而,它并不像 Adaboost 那样每一次迭代都更改实例的权重,这个方法是去使用新的分类器去拟合前面分类器预测的残差 。

(1)以决策树回归详解

from sklearn.tree import DecisionTreeRegressor

# 第一个分类器
tree_reg1 = DecisionTreeRegressor(max_depth=2)
tree_reg1.fit(X, y)

# 在第一个分类器的残差上运行第二个分类器
y2 = y - tree_reg1.predict(X)
tree_reg2 = DecisionTreeRegressor(max_depth=2)
tree_reg2.fit(X, y2)

# 在第二个分类器的残差上运行第三个分类器
y3 = y2 - tree_reg1.predict(X)
tree_reg3 = DecisionTreeRegressor(max_depth=2)
ree_reg3.fit(X, y3)

# 它可以通过集成所有树的预测来在一个新的实例上进行预测。
y_pred = sum(tree.predict(X_new) for tree in (tree_reg1, tree_reg2, tree_reg3))

(2)使用sklearn自带分类器实现

    • 超参数learning_rate 确立了每个树的贡献。如果你把它设置为一个很小的树,例
      如 0.1,在集成中就需要更多的树去拟合训练集,但预测通常会更好。这个正则化技术叫做 shrinkage
from sklearn.ensemble import GradientBoostingRegressor

gbrt = GradientBoostingRegressor(max_depth=2, n_estimators=3, learning_rate=1.0)
gbrt.fit(X, y)

(3)更好的梯度提升

为了找到树的最优数量,最简单使用这个技术的方法就是使用staged_predict():它在训练的每个阶段(用一棵树,两棵树等)返回一个迭代器。接下来的代码用 120 个树训练了一个 GBRT 集成,然后在训练的每个阶段验证错误以找到树的最佳数量,最后使用 GBRT 树的最优数量训练另一个集成:

import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.ensemble import GradientBoostingRegressor

X_train, X_val, y_train, y_val = train_test_split(X, y)
gbrt = GradientBoostingRegressor(max_depth=2, n_estimators=120)
gbrt.fit(X_train, y_train)
errors = [mean_squared_error(y_val, y_pred) for y_pred in gbrt.staged_predict(X_val)]

bst_n_estimators = np.argmin(errors) ## np.argmin表示最小值在数组中所在的位置
gbrt_best = GradientBoostingRegressor(max_depth=2,n_estimators=bst_n_estimators)
gbrt_best.fit(X_train, y_train)
GradientBoostingRegressor(alpha=0.9, criterion=‘friedman_mse‘, init=None,
                          learning_rate=0.1, loss=‘ls‘, max_depth=2,
                          max_features=None, max_leaf_nodes=None,
                          min_impurity_decrease=0.0, min_impurity_split=None,
                          min_samples_leaf=1, min_samples_split=2,
                          min_weight_fraction_leaf=0.0, n_estimators=119,
                          n_iter_no_change=None, presort=‘auto‘,
                          random_state=None, subsample=1.0, tol=0.0001,
                          validation_fraction=0.1, verbose=0, warm_start=False)

(4)第二种更好的梯度提升
你也可以早早的停止训练来实现早停(与先在一大堆树中训练,然后再回头去找最优数目相反)。你可以通过设置warm_start=True来实现 ,这使得当fit()方法被调用时 sklearn 保留现有树,并允许增量训练。接下来的代码在当一行中的五次迭代验证错误没有改善时会停止训练:

gbrt = GradientBoostingRegressor(max_depth=2, warm_start=True)
min_val_error = float("inf")
error_going_up = 0
for n_estimators in range(1, 120):
  gbrt.n_estimators = n_estimators
  gbrt.fit(X_train, y_train)
  y_pred = gbrt.predict(X_val)
  val_error = mean_squared_error(y_val, y_pred)
  if val_error < min_val_error:
    min_val_error = val_error
    error_going_up = 0
  else:
    error_going_up += 1
    if error_going_up == 5:

1.5 Stacking

另外一个集成方法叫做 Stacking(stacked generalization 的缩写)。
这个算法基于一个简单的想法:不使用琐碎的函数(如硬投票)来聚合集合中所有分类器的预测,而是自己训练一个模型来执行这个聚合。

sklearn 并不直接支持 stacking ,但是你自己组建是很容易的(看接下来的练习)。或者你也可以使用开源的项目例如 brew (网址为 <https: brew="" github.com="" viisar="">)</https:>

二、 随机森林

2.1 实现随机森林

随机森林是决策树的一种集成,**通常是通过 bagging 方法(有时是 pasting 方法)**进行训练,通常用max_samples设置为训练集的大小与建立一个BaggingClassifier然后把它放入 DecisionTreeClassifier 相反,你可以使用更方便的也是对决策树优化够的RandomForestClassifier(对于回归是RandomForestRegressor)。接下来的代码训练了带有 50个树(每个被限制为 16 叶子结点)的决策森林,使用所有空闲的 CPU 核:

from sklearn.ensemble import RandomForestClassifier

rnd_clf = RandomForestClassifier(n_estimators=50, max_leaf_nodes=16, n_jobs=-1)
rnd_clf.fit(X_train, y_train)
y_pred_rf = rnd_clf.predict(X_test)

2.2 极端随机树

当你在随机森林上生长树时,在每个结点分裂时只考虑随机特征集上的特征(正如之前讨论过的一样)。相比于找到更好的特征我们可以通过使用对特征使用随机阈值使树更加随机(像规则决策树一样)。

这种极端随机的树被简称为 Extremely Randomized Trees(极端随机树),或者更简单的称为 Extra-Tree。再一次用高偏差换低方差。它还使得 Extra-Tree 比规则的随机森林更快地训练,因为在每个节点上找到每个特征的最佳阈值是生长树最耗时的任务之一。

你可以使用 sklearn 的ExtraTreesClassifier来创建一个 Extra-Tree 分类器。他的 API 跟RandomForestClassifier是相同的,相似的, ExtraTreesRegressor 跟RandomForestRegressor也是相同的 API。

我们很难去分辨ExtraTreesClassifier和RandomForestClassifier到底哪个更好。通常情况下是通过交叉验证来比较它们(使用网格搜索调整超参数)。

2.3 特征重要度

如果你观察一个单一决策树,重要的特征会出现在更靠近根部的位置,而不重要的特征会经常出现在靠近叶子的位置。因此我们可以通过计算一个特征在森林的全部树中出现的平均深度来预测特征的重要性。sklearn 在训练后会自动计算每个特征的重要度。你可以通过feature_importances_变量来查看结果。下面以鸢尾花数据为例,得出最重要的特征是花瓣长度(44%)和宽度(42%)。而萼片长度和宽度相对比较是不重要的(分别为 11% 和 2%)

from sklearn.datasets import load_iris

iris = load_iris()
rnd_clf = RandomForestClassifier(n_estimators=500, n_jobs=-1)
rnd_clf.fit(iris["data"], iris["target"])
for name, score in zip(iris["feature_names"], rnd_clf.feature_importances_):
  print(name, score)
sepal length (cm) 0.10318363296580253
sepal width (cm) 0.024861953583854814
petal length (cm) 0.43069959942052854
petal width (cm) 0.4412548140298142

原文地址:https://www.cnblogs.com/qiuyuyu/p/11358382.html

时间: 2024-10-04 11:18:07

机器学习之集成学习和随机森林的相关文章

机器学习(十三) 集成学习和随机森林(下)

五.随机森林和 Extra-Trees 六.Ada Boosting 和 Gradient Boosting 七.Stacking 八.学习scikit-learn文档, 官方学习文档: http://scikit-learn.org http://scikit-learn.org/stable/user_guide.html 今年,Kaggle刚刚上线了Kaggle Learn模块,使用Kaggle的数据,来一点点进行机器学习实战.可以参考:https://www.kaggle.com/lea

机器学习(十三) 集成学习和随机森林(上)

一.什么是集成学习 二.Soft Voting Classifier 更合理的投票,应该有的权值 三.Bagging 和 Pasting 四.oob (Out-of-Bag) 和关于Bagging的更多讨论 原文地址:https://www.cnblogs.com/zhangtaotqy/p/9581237.html

大白话5分钟带你走进人工智能-第二十八节集成学习之随机森林概念介绍(1)

                                                      第二十八节集成学习之随机森林概念介绍(1) 从本系列开始,我们讲解一个新的算法系列集成学习.集成学习其实是怎么样去应用决策树解决一些问题. 在机器学习领域集成学习是一种非常简单直接的提升分类器回归器预测效果的一种思路.决策树有一个困境,当层数太深的时候会有过拟合问题,当我不想过拟合,就通过预剪枝给它砍掉一部分深度,此时损失又容易太大了,导致在训练集上预测的又不怎么准.所以对于决策树很难去找

10.集成学习与随机森林

1.什么是集成学习 什么是集成学习,以前我们都是使用一个算法来进行预测,难免会有"独断专行"的感觉.集成学习是将多个算法集成在一块,然后多个算法对同一个问题进行预测,然后少数服从多数,这便是集成学习. 我们生活中有很多集成学习的例子,比如买东西的时候看推荐,如果10个人推荐你买A产品,但是只有1个人推荐你买B产品,我们会更将倾向于买B产品. 我们看看sklearn是如何为我们提供集成学习的接口的. from sklearn.datasets import make_moons from

集成学习 - 决策树-随机森林

认识 我觉得决策树+ 随机森林 应该是 ML 中最为重要的算法之一了吧, 反正我是很喜欢用的. 算法难度低, 可解释性很强, 能可视化 能处理非线性, 可扩展为随机森林(集成学习) 建立决策树的判别依据有很多, 比较主流的有经典的 ID3 算法(熵), C4.5 , 基尼系数等. 我是这种基于熵的理解了, 上学时学过熵的概念, 在<> 和 <> 有讲到. 其余的也没仔细看, 暂时能深入理解一个就可以了. 信息熵 衡量信息的不确定性 或 混乱程度的指标 不确定性越大, 则熵值越大 直

R语言︱机器学习模型评估方案(以随机森林算法为例)

R语言︱机器学习模型评估方案(以随机森林算法为例) 笔者寄语:本文中大多内容来自<数据挖掘之道>,本文为读书笔记.在刚刚接触机器学习的时候,觉得在监督学习之后,做一个混淆矩阵就已经足够,但是完整的机器学习解决方案并不会如此草率.需要完整的评价模型的方式. 常见的应用在监督学习算法中的是计算平均绝对误差(MAE).平均平方差(MSE).标准平均方差(NMSE)和均值等,这些指标计算简单.容易理解:而稍微复杂的情况下,更多地考虑的是一些高大上的指标,信息熵.复杂度和基尼值等等. 本篇可以用于情感挖

机器学习实战之 第七章 集成方法(随机森林和 AdaBoost)

第7章 集成方法 ensemble method 集成方法: ensemble method(元算法: meta algorithm) 概述 概念:是对其他算法进行组合的一种形式. 通俗来说: 当做重要决定时,大家可能都会考虑吸取多个专家而不只是一个人的意见. 机器学习处理问题时又何尝不是如此? 这就是集成方法背后的思想. 集成方法: 投票选举(bagging: 自举汇聚法 bootstrap aggregating): 是基于数据随机重抽样分类器构造的方法 再学习(boosting): 是基于

机器学习算法--集成学习

1. 个体和集成 集成学习通过构建并结合多个"个体学习器"来完成学习任务.个体学习器通常由一个现有的学习算法从训练数据产生,若集成中只包含同种类型的个体学习器,称为同质集成:若包含不同类型的个体学习器,为异质集成.同质集成中的个体学习器也成为"基学习器". 如何产生并结合"好而不同"的个体学习器,恰是集成学习研究的核心. 根据个体学习器的生成方式,目前的集成学习方法大致分为两大类: (1)个体学习器间存在强依赖关系,必须串行生成的序列化方法,代表

机器学习之集成学习(一)

详细参考:https://www.cnblogs.com/pinard/p/6131423.html 首先明确集成学习它本身不是一个单独的机器学习算法,而是通过构建并结合多个机器学习器来完成学习任务. 集成学习有两个主要的问题需要解决,第一是如何得到若干个个体学习器,第二是如何选择一种结合策略,将这些个体学习器集合成一个强学习器.对于个体学习器第一种就是所有的个体学习器都是一个种类的,或者说是同质的.比如都是决策树个体学习器,或者都是神经网络个体学习器.第二种是所有的个体学习器不全是一个种类的,