机器学习

1 集成学习

1.1 介绍

集成学习,Ensemble Learning,可以理解为由许多算法按照某种策略集成在一起的算法框架。

集成学习的作用

  1. 单一的模型很可能不够强大
    集成学习会考虑多个评估器的建模结果,汇总后得到一个综合结果,以此来获取比单个模型更好的回归或分类表现。
  2. 模型选择问题
    构建模型的目标是训练出一个稳定的且在各个方面表现都很好的模型,但实际情况往往不这么理想。有时只能获得许多个有偏好的模型(弱监督模型),这些模型仅仅在某些方面的表现比较好。集成学习就是通过将多个弱监督模型组合在一起,得到一个更加全面的强监督模型系统。

集成学习的核心问题是如何将各个模型集成在一起,即研究集成策略。
这里不同的模型包括:

  1. 不同的机器学习算法
  2. 不同的训练过程
    即相同的机器学习算法,不同的训练样本,或不同的算法参数等。

例如,存在三种不同的分类器,分别对样本数据进行分类,利用集成学习可以获得比单个分类器更好的表现,这里的集成策略是将这些分类器的分类结果汇总起来取平均。
在这里插入图片描述

1.2 机器学习体系一览

需要明确集成学习在整个机器学习体系中的位置。
在这里插入图片描述

1.3 集成学习分类

实现集成学习的方法主要可以分为两大类:
并行集成方法和序列集成方法。

  1. 并行集成方法(装袋法Bagging)
    并行集成方法中参与训练的基础学习器并行生成(例如Random Forest)。
    并行方法的原理是利用基础学习器之间的独立性,通过平均或者投票等方式来显著地降低错误和误差。
  2. 序列集成方法(提升法Boosting)
    序列集成方法中参与训练的基础学习器按照顺序生成(例如 AdaBoost)。
    序列方法的原理是利用基础学习器之间的依赖关系,通过对之前训练中错误标记的样本赋值较高的权重,可以提高整体的预测效果。
    在这里插入图片描述
1.4 实现集成学习的方法

实现集成学习的方法包括Bagging、Boosting、Stacking等,这些方法的重点都是使用何种策略能够将各个模型的输出结果汇总起来,从而得到最佳结果。

1.4.1 Bagging套袋法

Bagging套袋法,全称为bootstrap aggregating,是一种有放回的抽样方法。

算法过程:

  1. 从原始样本集中抽取训练集。
    每轮从原始样本集中使用有放回的方法抽取n个训练样本。在训练集中,有些样本可能被多次抽取到,而有些样本可能一次都没有被抽中。
    共进行k轮抽取,得到k个训练集,而且k个训练集之间相互独立。
  2. 每次使用一个训练集得到一个模型,则k个训练集共可以得到k个模型。
    注:这里并没有具体的分类算法或回归方法,我们可以根据具体问题采用不同的分类或回归方法。
  3. 分类问题,将测试样本分布输入到k个模型中,获得k个分类结果。对于k个模型输出的分类结果,采用投票的方式(可以带权重)决定测试样本的最终分类结果;
  4. 回归问题,将k个模型输出结果的均值作为最终结果,前提是所有模型的重要程度相同。

在这里插入图片描述

1.4.2 Boosting

Boosting的主要思想是将弱学习器组装成一个强学习器。
通过提高那些在前一轮被弱分类器分错样例的权值,减小前一轮分对样例的权值(使得弱分类器可以对分错样例更敏感),来使得分类器对误分的数据有较好的效果。也就是说算法刚开始训练时对每一个训练样本赋相等的权重,然后用该算法对训练集训练t轮,每次训练后,对训练失败的训练例赋以较大的权重,也就是让学习算法在每次学习以后更注意学错的样本。
在这里插入图片描述

1.4.3 Stacking

Stacking方法是指训练一个模型用于组合其他各个模型。首先我们先训练多个不同的模型,然后把之前训练的各个模型的输出为输入来训练一个模型,以得到一个最终的输出。
如下图,先在整个训练数据集上通过有放回抽样得到各个训练集合,得到一系列分类模型,然后将输出用于训练第二层分类器。
在这里插入图片描述

1.4.4 Bagging,Boosting二者之间的区别
  1. 样本选择上
    Bagging:训练集是在原始集中有放回选取的,从原始集中选出的各轮训练集之间是独立的。
    Boosting:每一轮的训练集不变,只是训练集中每个样例在分类器中的权重发生变化。而权值是根据上一轮的分类结果进行调整。
  2. 样例权重
    Bagging:使用均匀取样,每个样例的权重相等
    Boosting:根据错误率不断调整样例的权值,错误率越大则权重越大。

2 随机森林

2.1 介绍

随机森林是一种有监督学习算法,是以决策树为基学习器的集成学习算法。随机森林非常简单,易于实现,计算开销也很小,在分类和回归上表现出非常惊人的性能,因此,随机森林被誉为“代表集成学习技术水平的方法”。

随机森林的随机性体现在哪几个方面

  1. 数据集的随机选择
    从原始数据集中采取"有放回的抽样bagging",构造子数据集。不同子数据集的元素可以重复,同一个子数据集中的元素也可以重复。
  2. 待选特征的随机选取
    随机森林中的子树的每一个分裂过程并未用到所有的待选特征,而是从所有的待选特征中随机选取一定的特征,之后再随机选取的特征中选取最优的特征。

随机森林的重要作用
可以用于分类问题,也可以用于回归问题;
可以解决模型过拟合的问题,对于随机森林来说,如果随机森林中的树足够多,那么分类器就不会出现过拟合;
可以检测出特征的重要性,从而选取好的特征。

2.2 随机森林的构建过程
  1. 从原始训练集中随机有放回采样取出m个样本,生成m个训练集;
  2. 对m个训练集,我们分别训练m个决策树模型;
  3. 对于单个决策树模型,假设训练样本特征的个数为n,那么每次分裂时根据信息增益/信息增益比/基尼指数 选择最好的特征进行分裂;
  4. 将生成的多颗决策树组成随机森林。对于分类问题,按照多棵树分类器投票决定最终分类结果;对于回归问题,由多颗树预测值的均值决定最终预测结果。
2.3 随机森林的优点和缺点
2.3.1 优点

1.由于采用了集成算法,本身精度比大多数单个算法要好,所以准确性高;
2.由于两个随机性的引入,使得随机森林不容易陷入过拟合(样本随机,特征随机);
3.在工业上,由于两个随机性的引入,使得随机森林具有一定的抗噪声能力,对比其他算法具有一定优势;
4.它能够处理很高维度(feature很多)的数据,并且不用做特征选择,对数据集的适应能力强:既能处理离散型数据,也能处理连续型数据;
5.在训练过程中,能够检测到feature间的互相影响,且可以得出feature的重要性,具有一定参考意义。

2.3.2 缺点

当随机森林中的决策树个数很多时,训练时需要的空间和时间会比较大。

2.4 代码实现

sklearn.ensemble库中提供了Random Forest分类和回归的实现:
RandomForestClassifier
RandomForestRegression

from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200825205902971.png?x-oss-process=image/watermark, type_ZmFuZ3poZW5naGVpdGk, shadow_10, text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2NTY1NTA5, size_16, color_FFFFFF, t_70#pic_center)

2.4.1 n_estimators
n_estimators
这是森林中树木的数量,即基评估器的数量。这个参数对随机森林模型的精确性影响是单调的,n_estimators越大,模型的效果往往越好。但是相应的,任何模型都有决策边界,n_estimators达到一定的程度之后,随机森林的 精确性往往不在上升或开始波动,并且,n_estimators越大,需要的计算量和内存也越大,训练的时间也会越来越 长。对于这个参数,我们是渴望在训练难度和模型效果之间取得平衡。
n_estimators的默认值在现有版本的sklearn中是10,但是在即将更新的0.22版本中,这个默认值会被修正为 100。这个修正显示出了使用者的调参倾向:要更大的n_estimators。

建立森林
树模型的优点是简单易懂,可视化之后的树人人都能够看懂,可惜随机森林是无法被可视化的。所以为了更加直观地让大家体会随机森林的效果,我们来进行一个随机森林和单个决策树效益的对比。我们依然使用红酒数据集。

from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import f1_score

X = load_wine().data
y = load_wine().target
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=2020)

l = LogisticRegression(solver='liblinear').fit(x_train, y_train)
f1_score(y_test, l.predict(x_test), average='micro')  # 1.0

d = DecisionTreeClassifier().fit(x_train, y_train)
f1_score(y_test, d.predict(x_test), average='micro')  # 0.9166666666666666

r = RandomForestClassifier().fit(x_train, y_train)
f1_score(y_test, r.predict(x_test), average='micro')  # 1.0

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

%matplotlib inline
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt

rfc = RandomForestClassifier(n_estimators=25)
rfc_s = cross_val_score(rfc, wine.data, wine.target, cv=10)
clf = DecisionTreeClassifier()
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()

在这里插入图片描述
画出随机森林和决策树在十组交叉验证下的效果对比。

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

在这里插入图片描述

2.4.2 random_state

随机森林中的random_state控制的是生成森林的模式,类似决策树中的random_state,用来固定森林中树的随机性。当random_state固定时,随机森林中生成是一组固定的树。

2.4.3 bootstrap & oob_score
  1. bootstrap
    装袋法是通过有放回的随机抽样技术来形成不同的训练数据,bootstrap就是用来控制抽样技术的参数。我们进行样本的随机采样,每次采样一个样本,并在抽取下一个样本之前将该样本 放回原始训练集,也就是说下次采样时这个样本依然可能被采集到。bootstrap参数默认True,代表采用这种有放回的随机抽样技术。通常,这个参数不会被我们设置为False。
  2. oob_score
    然而有放回抽样也会有自己的问题。由于是有放回,一些样本可能会被采集多次,而其他一些样本却可能被忽略,一次都未被采集到。那么这些被忽略或者一次都没被采集到的样本叫做oob袋外数据。
    也就是说,在使用随机森林时,我们可以不划分测试集和训练集,只需要用袋外数据来测试我们的模型即可。
    如果希望用袋外数据来测试,则需要在实例化时就将oob_score这个参数调整为True,训练完毕之后,我们可以用随机森林的另一个重要属性:oob_score_来查看我们的在袋外数据上测试的结果。
# 无需划分训练集和测试集
rfc = RandomForestClassifier(n_estimators=25, oob_score=True)
rfc = rfc.fit(wine.data, wine.target)
#重要属性oob_score_ 
rfc.oob_score_  # 0.9606741573033708
2.5 回归随机森林RandomForestRegressor

回归随机森林所有的参数,属性与接口,全部和随机森林分类器一致。仅有的不同就是回归树与分类树的不同,不纯度的指标, 参数Criterion不一致。
Criterion参数:
回归树衡量分枝质量的指标,支持的标准有三种:
输入"mse"使用均方误差mean squared error(MSE),父节点和叶子节点之间的均方误差的差额将被用来作为特征选择的标准,这种方法通过使用叶子节点的均值来最小化L2损失
输入“friedman_mse”使用费尔德曼均方误差,这种指标使用弗里德曼针对潜在分枝中的问题改进后的均方误差
输入"mae"使用绝对平均误差MAE(mean absolute error),这种指标使用叶节点的中值来最小化L1损失。

from sklearn.tree import DecisionTreeRegressor
from sklearn.datasets import load_boston

X = load_boston().data
y = load_boston().target
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=2020)

d = DecisionTreeRegressor().fit(x_train, y_train)
d.score(x_test, y_test)  # 0.5118157773300465

r = RandomForestRegressor().fit(x_train, y_train)
r.score(x_test, y_test)  # 0.7721598501396133

进行又放回的随机抽样时,每一个弱评估器使用的训练数据和原始样本的训练数据量级一致。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐