机器学习-集成学习(ensemble learning)

集成学习ensemble learning:本身不是一个单独的机器学习算法,而是通过构建并结合多个机器学习器来完成学习任务。
可以用两句话形容:
1、“三个臭皮匠顶个诸葛亮”:一堆弱分类器的组合可以成为一个强分类器;
2、“知错能改,善莫大焉”:不断在错误中学习,迭代来降低放错概率。

投票分类器VotingClassifier:结合多个不同的机器学习分类器,使用多数票(hard)或者平均预测概率(soft)来预测数据标签,可以平衡各个模型的弱点。

一、集成学习概述

1、训练若干个个体学习器(弱学习器)
弱学习器可以是同质或异质的:
同质:boosting系列算法(一系列个体学习器存在强依赖关系,需要串行生成)
例如Ada(adaptive) Boosting算法 以及 提升树Boosting系列算法,Gradient Boosting。
在这里插入图片描述

异质:bagging和随机森林(Random Forest)(个体学习器间不存在强依赖关系,一系列个体学习器可以并行生成)。
在这里插入图片描述

区别bagging和boosting
在bagging方法中,特点在于随机化抽样,通过反复的抽样训练新的模型,最终在这些模型的基础上取平均。
boosting的核心思想在于,对多个模型的预测结果做加权平均则是将多个弱学习模型提升为强学习模型,在此过程中权重在不断更新。

2、一定的结合策略
在对个体学习器进行训练后,需要一种结合策略,将其形成一个强学习器。
1)平均法:对若干个弱学习器的输出进行平均(算术平均和加权平均等)得到最终的预测输出,常用于数值类的回归预测问题。
2)投票法:相对多数投票法(少数服从多数)、绝对多数投票法(过半数票)以及加权投票法,常用于分类问题预测。
3)学习法:
为了解决上述两种方法学习误差较大的问题,采用学习法,代表方法时stacking。
当使用stacking的结合策略时,会再加上一层学习器,此时弱学习器为初级学习器,将用于结合的学习器称为次级学习器。对于测试集,我们首先用初级学习器预测一次,得到次级学习器的输入样本,再用次级学习器预测一次,得到最终的预测结果。

3、形成强学习器

二、AdaBoosting以及GBDT(Gradient Boosting Decision Tree)

这两种算法是基于Boosting思想的著名算法,Boosting算法中,初始化时对每个训练样本赋予相等的权重,如1/n,然后利用该学习算法对训练集训练G轮,每次训练后,对训练失败的训练样本进行学习,从而得到一个预测函数序列,预测效果好的预测函数权重较大。
而Adaboosting和GradientBoosting在面对已存在弱分类器组合的shortcomings时表征不同,Adaboosting依据权值高的样本点,而GrandientBoosting依据梯度

1)Adaboosting算法(记住两点:两个权重
涉及两个权重的计算:
样本的权值:
在没有先验知识的情况下,初始的分布应为等概分布,样本数目为n,权值为1/n;
每次迭代更新权值,提高分错样本的权重。
弱分类器的权值:
最后的强学习器是多个弱学习器通过权值组合得到的;
通过权值体现不同弱学习器的影响,正确率高的弱学习器权重高(实际上是分类误差的一个函数)。

2)GradientBoosting算法(记住一点:梯度下降
GradientBoosting算法是一种利用树的集成模型,引入损失函数描述模型的“靠谱”程度,假设模型未过拟合,损失函数越大,则模型错误率越高。
在求解损失函数时,可以通过梯度下降法来一步步迭代求解,得到最小化的损失函数和模型参数值(梯度即导数or偏导)。
GradientBoostingRegressor的函数参数如下(sklearn包中提供):

class sklearn.ensemble.GradientBoostingRegressor(
loss='ls', learning_rate=0.1, n_estimators=100, subsample=1.0, 
min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_depth=3,
init=None, random_state=None, max_features=None, alpha=0.9, 
verbose=0, max_leaf_nodes=None, warm_start=False, presort='auto')[source]

参数含义:
loss:选择损失函数,默认值ls (least squres)
learning_rate:学习率,默认是0.1
n_estimators:弱学习器数目,默认是100
max_depth:每个学习器最大深度,限制回归树的节点数目,默认是3
min_sample_split:可划分内部节点的最小样本数,默认是2
min_samples_leaf:叶节点所需的最小样本数,默认是1.

篇外:理解梯度下降法(四步)
求梯度;相反方向移动x(引入步长概念);循环前一步,知道x变化使得f(x)在两次迭代间差值足够小;输出x。
在这里插入图片描述

三、RandomForest以及ExtraTrees
随机森林是ensemble方法中的bagging方法,用原始数据进行训练至完全分裂最后得到多个决策树,对新的数据的预测就是对所有的决策树取平均值进行预测。ExtraTrees是bagging方法的一个修正版,使用训练样本直接构建随机树,由于RF和ExtraTrees区别较小,调参方法基本相同,接下来只介绍sklearn中RF的参数。
RandomForest关键概念

  • 采样:样本数量为N,采样数量也为N,但是采取的是有放回的采样bootstrap。
  • 训练:决策树完全分裂至所有的叶子节点,不做各种形式的剪枝,不需担心overfiting问题。
  • 组合算法:训练结束后,对新数据进行预测,会利用得到的M个决策树对新数据进行预测,并对结果进行平均或者进行投票。sklearn算法是对各个树进行平均取结果。
  • 分类和回归:随机森林既可作分类,也可做回归,但主要是分类。

RandomForestClassifier的函数参数如下(sklearn包中提供):

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,bootstrap=True, oob_score=False, n_jobs=1,
random_state=None, verbose=0, warm_start=False, class_weight=None)[source]

参数含义:
n_estimators:森林中树的个数,默认是10
criterion:衡量分类的质量,默认“gini”,即基尼不纯度(Gini impurity),度量一个集合中每种类型的比例。支持规则有gini和entropy(信息增益)
max_features : int, float, string or None, optional (default=”auto”):需要考虑特征的数目,If “auto”, then max_features=sqrt(n_features)
max_depth : integer or None, optional (default=None):树最大深度
min_samples_split : integer, optional (default=2):分裂一个内部结点所需最少样本数
min_samples_leaf : integer, optional (default=1):新创建输液中最少样本数
bootstrap=True:是否有放回的采样。
oob_score : bool :oob(out of band,带外)数据,即:在某次决策树训练中没有被bootstrap选中的数据。多单个模型的参数训练,我们知道可以用cross validation(cv)来进行,但是特别消耗时间,而且对于随机森林这种情况也没有大的必要,所以就用这个数据对决策树模型进行验证,算是一个简单的交叉验证。性能消耗小,但是效果不错。
n_jobs=1:并行job个数。这个在ensemble算法中非常重要,尤其是bagging(而非boosting,因为boosting的每次迭代之间有影响,所以很难进行并行化),因为可以并行从而提高性能。1=不并行;n:n个并行;-1:CPU有多少core,就启动多少job。
warm_start=False:热启动,决定是否使用上次调用该类的结果然后增加新的。
class_weight=None:各个label的权重。

四、投票分类器VotingClassifier
hard标准:相对多数投票

>>> from sklearn import datasets
>>> from sklearn.model_selection import cross_val_score
>>> from sklearn.linear_model import LogisticRegression
>>> from sklearn.naive_bayes import GaussianNB
>>> from sklearn.ensemble import RandomForestClassifier
>>> from sklearn.ensemble import VotingClassifier
>>> iris = datasets.load_iris()
>>> X, y = iris.data[:, 1:3], iris.target
>>> clf1 = LogisticRegression(random_state=1)
>>> clf2 = RandomForestClassifier(random_state=1)
>>> clf3 = GaussianNB()
>>> eclf = VotingClassifier(estimators=[('lr', clf1), ('rf', clf2), ('gnb', clf3)], voting='hard')
>>> for clf, label in zip([clf1, clf2, clf3, eclf], ['Logistic Regression', 'Random Forest', 'naive Bayes', 'Ensemble']):
...     scores = cross_val_score(clf, X, y, cv=5, scoring='accuracy')
...     print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), label))
Accuracy: 0.90 (+/- 0.05) [Logistic Regression]
Accuracy: 0.93 (+/- 0.05) [Random Forest]
Accuracy: 0.91 (+/- 0.04) [naive Bayes]
Accuracy: 0.95 (+/- 0.05) [Ensemble]

soft标准:返回预测概率值总和最大的标签,可通过参数weights指定每个分类器的权重(此时将按照加权平均计算,标签为概率最高的)
例如:有3个分类器对一个结果进行预测,每个分类器权重为w1=1,w2=1,w3=1。如下表中标签2为最终结果:
在这里插入图片描述

>>> from sklearn import datasets
>>> from sklearn.tree import DecisionTreeClassifier
>>> from sklearn.neighbors import KNeighborsClassifier
>>> from sklearn.svm import SVC
>>> from itertools import product
>>> from sklearn.ensemble import VotingClassifier
 
>>> # Loading some example data
>>> iris = datasets.load_iris()
>>> X = iris.data[:, [0,2]]
>>> y = iris.target
 
>>> # Training classifiers
>>> clf1 = DecisionTreeClassifier(max_depth=4)
>>> clf2 = KNeighborsClassifier(n_neighbors=7)
>>> clf3 = SVC(kernel='rbf', probability=True)
>>> eclf = VotingClassifier(estimators=[('dt', clf1), ('knn', clf2), ('svc', clf3)], voting='soft', weights=[2,1,2])
 
>>> clf1 = clf1.fit(X,y)
>>> clf2 = clf2.fit(X,y)
>>> clf3 = clf3.fit(X,y)
>>> eclf = eclf.fit(X,y)

VotingClassifier参考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章