任务描述
本关任务:根据已学习的知识编写实现集成学习算法模型。
相关知识
为了完成本关任务,你需要掌握:1.Bagging、随机森林算法模型实现,2.Boosting算法模型实现。
Bagging、随机森林算法模型实现
上节已对Bagging算法进行了较为详尽的说明,本节将进一步通过代码来实例化所学模型。 以下将在UCI的Breast cancer数据集上构建决策树、随机森林、Bagging模型,并比较模型效果。 其中,Bagging的策略如下:
- 从样本集中重采样(有重复的)选出n个样本
- 在所有属性上,对这n个样本建立分类器(ID3、C4.5、CART、SVM、Logistic回归等)
- 重复1、2…… m 次,即获得了 m 个分类器
- 将数据放在这m个分类器上,最后根据这 m 个分类器的投票结果,决定数据属于哪一类
随机森林的策略如下:
- 从样本集中用Bootstrap采样选出n个样本
- 从所有属性中随机选择k个属性,选择最佳分割属性作为节点建立CART决策树
- 重复1、2两个步骤,即建立了m棵CART决策树
- m个CART形成随机森林,通过投票表决结果,决定数据属于哪一类
需要导入的包,如下:
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import GradientBoostingClassifier
import xgboost
读取UCI的Breast cancer数据集,并划分数据集,按照7:3来划分:
data=load_breast_cancer() # 导入数据类
x=pd.DataFrame(data.data) # 获取数据
y=data.target # 获取标签
X_train,X_test,y_train,y_test=train_test_split(x,y,random_state=0,test_size=0.3)
构建决策树模型,并在已划分的数据集上训练:
tree = DecisionTreeClassifier(criterion='entropy', max_depth=None)
tree = tree.fit(X_train, y_train) # 训练
y_train_pred = tree.predict(X_train)
y_test_pred = tree.predict(X_test)
tree_train = accuracy_score(y_train, y_train_pred)
tree_test = accuracy_score(y_test, y_test_pred)
构建Bagging模型,子模型拥有500个决策树,具体参数设置见代码:
bag = BaggingClassifier(base_estimator=tree, n_estimators=500, max_samples=1.0, max_features=1.0, bootstrap=True, bootstrap_features=False, n_jobs=1, random_state=1)
# -----------------------------------------------------
# 参数说明
‘’‘
base_estimator : 对象或无,可选(默认=无)
基本估计量适合数据集的随机子集。如果为None,则基本估计量为决策树。
n_estimators : int,可选(默认值为10)
集合中的基本估计量。
max_samples : int或float,可选(默认值= 1.0)
从X抽取以训练每个基本估计量的样本数。
如果为int,则抽取样本 max_samples。
如果float,则抽取本 max_samples * X.shape[0]
max_features : int或float,可选(默认值= 1.0)
从X绘制以训练每个基本估计量的要素数量。
如果为int,则绘制特征 max_features。
如果是浮动的,则绘制特征 max_features * X.shape[1]
bootstrap : 布尔值,可选(默认= True)
是否抽取样本进行替换。如果为False,则执行不替换的采样。
oob_score : 布尔变量,可选(默认为False)
是否使用现成的样本来估计泛化误差。
warm_start : 布尔变量,可选(默认= False)
设置为True时,请重用上一个调用的解决方案以适合并为集合添加更多估计量,否则,仅适合一个全新的集合。
n_jobs : int或None(可选)(默认为None)
fit和 并行运行的作业数predict。None除非joblib.parallel_backend上下文中,否则表示1 。-1表示使用所有处理器。
random_state : 整型,RandomState实例或无,可选(默认值:无)
如果为int,则random_state是随机数生成器使用的种子;否则为false。
’‘’
# -----------------------------------------------------
bag = bag.fit(X_train, y_train) # 训练
y_train_pred = bag.predict(X_train)
y_test_pred = bag.predict(X_test)
bag_train = accuracy_score(y_train, y_train_pred)
bag_test = accuracy_score(y_test, y_test_pred)
构建Bagging模型:
rf = RandomForestClassifier(n_estimators=1000, max_features='sqrt', max_depth=None, min_samples_split=2, bootstrap=True, n_jobs=1, random_state=1)
# 度量随机森林的准确性
rf = rf.fit(X_train, y_train)
y_train_pred = rf.predict(X_train)
y_test_pred = rf.predict(X_test)
tree_train = accuracy_score(y_train, y_train_pred)
tree_test = accuracy_score(y_test, y_test_pred)
Boosting算法模型实现
Boosting在直接构造强学习器非常困难的情况下,为学习算法的设计提供了一种有效的新思路和新方法。其中最为成功应用的是,Yoav Freund和Robert Schapire在1995年提出的AdaBoost算法。
Adaboost算法可以简述为以下三个步骤:
- 初始化训练数据的权值分布D1。假设有N个训练样本数据,则每一个训练样本最开始时,都被赋予相同的权值:w1=1/N。
- 训练弱分类器hi。具体训练过程中是:如果某个训练样本点,被弱分类器hi准确地分类,那么在构造下一个训练集中,它对应的权值要减小;相反,如果某个训练样本点被错误分类,那么它的权值就应该增大。权值更新过的样本集被用于训练下一个分类器,整个训练过程如此迭代地进行下去。
- 将各个训练得到的弱分类器组合成一个强分类器。各个弱分类器的训练过程结束后,加大分类误差率小的弱分类器的权重,使其在最终的分类函数中起着较大的决定作用,而降低分类误差率大的弱分类器的权重,使其在最终的分类函数中起着较小的决定作用。
GBDT也是集成学习Boosting家族的成员,但是却和传统的Adaboost有很大的不同。在Adaboost中,我们是利用前一轮迭代弱学习器的误差率来更新训练集的权重,这样一轮轮的迭代下去。GBDT也是迭代,使用了前向分布算法,但是弱学习器限定了只能使用CART回归树模型,同时迭代思路和Adaboost也有所不同。为了更好的理解算法思路,我们将通过举个简单的例子来说明:假如有个人30岁,我们首先用20岁去拟合,发现损失有10岁,这时我们用6岁去拟合剩下的损失,发现差距还有4岁,第三轮我们用3岁拟合剩下的差距,差距就只有一岁了。如果我们的迭代轮数还没有完,可以继续迭代下面,每一轮迭代,拟合的岁数误差都会减小。
相对于传统的GBDT,XGBoost使用了二阶信息,在同一数据集上拥有更快的收敛速度。在kaggle挑战赛中,表现优异由于“随机森林族”本身具备过拟合的优势,因此XGBoost仍然一定程度的具有该特性。XGBoost的实现中使用了并行/多核计算,因此训练速度快;同时他的原生语言为C/C++,这是它速度快的原因。
以下将在UCI的Breast cancer数据集上构建AdaBoost、GBDT和XGBoost模型,并比较模型效果。 构建Boosting分类器:
# 具体参数说明翻阅sklearn官方文档
ada = AdaBoostClassifier(n_estimators=1000, learning_rate=0.1, random_state=0))
构建GBDT分类器:
# 具体参数说明翻阅sklearn官方文档
gbdt =GradientBoostingClassifier(n_estimators=1000, learning_rate=0.1, random_state=0)
构建XGBoost分类器:
# 具体参数说明翻阅sklearn官方文档
xgb =xgboost.XGBClassifier(n_estimators=1000, learning_rate=0.1)
代码介绍
利用sklearn中的BaggingClassifier()、AdaBoostClassifier()、GradientBoostingClassifier()函数来构建Bagging、AdaBoost、GBDT集成分类器。 其中BaggingClassifier()函数有十一个参数,本次任务使用到的参数如下:
- base_estimator:object, default=None,适合于数据集的随机子集的基估计量,如果 None,则基估计量是决策树。
- n_estimators:int, default=10 训练基学习器(基本估计器)的个数。本次任务设置为500.
- max_samples:int or float, default=1.0,从X抽取的样本数,用于训练每个基本估计器。本次任务设置为1.
- max_features:int or float, default=1.0,从X中提取的用于训练每个基本估计器的特征数。本次任务设置为1.
- bootstrap:bool, default=True是否为放回取样。本次任务设置为true。
- bootstrap_features:bool, default=False,是否针对特征随机取样。本次任务设置为False。
- n_jobs:int, default=None,使用几个处理起来运行,-1表示使用所有处理器。本次任务设置为1.
- random_state:int or RandomState, default=None,控制原始数据集的随机重采样(采样和特征)。本次任务设置为1.
AdaBoostClassifier()与GradientBoostingClassifier()函数参数,如下:
- base_estimator: 可选参数,默认为DecisionTreeClassifier。
- algorithm: 可选参数,默认为SAMME.R。
- n_estimators: 整数型,可选参数,默认为50。弱学习器的最大迭代次数。本次任务设置为1000.
- learning_rate: 浮点型,可选参数,默认为1.0。每个弱学习器的权重缩减系数,取值范围为0到1。本次任务设置为0.1.
- random_state: 整数型,可选参数,默认为None。本次任务设置为0.
之后使用fit()函数对创建的集成分类器进行训练。该函数设置两个参数,第一个参数为训练数据集,第二个参数为训练数据集标签。
编程要求
根据提示,在右侧编辑器补充代码,深刻理解以上内容,打印出以上所构模型在UCI的Breast cancer数据集上的精度。 本次编程任务需要实现:
- Bagging集成分类器
- AdaBoost集成分类器
- GBDT集成分类器
测试说明
平台会对你编写的代码进行测试:
测试输入:无; 预期输出: Decision tree train/test accuracies 1.000/0.971
Bagging train/test accuracies 1.000/0.959
Random Forest train/test accuracies 1.000/0.971
AdaBoost train/test accuracies 1.000/0.977
GBDT train/test accuracies 1.000/0.982
开始你的任务吧,祝你成功!
答案
import pandas as pd
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import BaggingClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import accuracy_score
data=load_breast_cancer()# 读入乳腺癌数据集,并按照训练集7:测试集3的比例划分数据集
x=pd.DataFrame(data.data)
y=data.target
X_train,X_test,y_train,y_test=train_test_split(x,y,random_state=0,test_size=0.3)
tree = DecisionTreeClassifier(criterion='entropy', max_depth=None)# 构建决策树模型
tree = tree.fit(X_train, y_train)
y_train_pred = tree.predict(X_train)# 度量单个决策树的准确性
y_test_pred = tree.predict(X_test)
tree_train = accuracy_score(y_train, y_train_pred)
tree_test = accuracy_score(y_test, y_test_pred)
######begin######
# 任务1. 构建Bagging模型,生成500个决策树,并训练
bag = BaggingClassifier(base_estimator=tree, n_estimators=500, max_samples=1.0, max_features=1.0, bootstrap=True, n_jobs=1, random_state=1)
bag = bag.fit(X_train, y_train)
######end######
y_train_pred = bag.predict(X_train)
y_test_pred = bag.predict(X_test)
bag_train = accuracy_score(y_train, y_train_pred)
bag_test = accuracy_score(y_test, y_test_pred)
rf = RandomForestClassifier(n_estimators=1000, max_features='sqrt', max_depth=None, min_samples_split=2, bootstrap=True, n_jobs=1, random_state=1)# 构建随机森林模型
rf = rf.fit(X_train, y_train)
y_train_pred = rf.predict(X_train)
y_test_pred = rf.predict(X_test)
rf_train = accuracy_score(y_train, y_train_pred)# 度量随机森林的准确性
rf_test = accuracy_score(y_test, y_test_pred)
######begin######
# 任务2. 构建Boosting模型,并训练
ada = AdaBoostClassifier(n_estimators=1000, learning_rate=0.1, random_state=0)
ada = ada.fit(X_train, y_train)
######end######
y_train_pred = ada.predict(X_train)
y_test_pred = ada.predict(X_test)
ada_train = accuracy_score(y_train, y_train_pred)
ada_test = accuracy_score(y_test, y_test_pred)
######begin######
# 任务3. 构建GBDT模型,并训练
gbdt = GradientBoostingClassifier(n_estimators=1000, learning_rate=0.1, random_state=0)
gbdt = gbdt.fit(X_train, y_train)
######end######
y_train_pred = gbdt.predict(X_train)
y_test_pred = gbdt.predict(X_test)
gbdt_train = accuracy_score(y_train, y_train_pred)
gbdt_test = accuracy_score(y_test, y_test_pred)
# 打印出以上模型的精度
print('Decision tree train/test accuracies %.3f/0.971' % (tree_train))
print('Bagging train/test accuracies %.3f/%.3f' % (bag_train, bag_test))
print('Random Forest train/test accuracies %.3f/%.3f' % (rf_train, rf_test))
print('AdaBoost train/test accuracies %.3f/%.3f' % (ada_train, ada_test))
print('GBDT train/test accuracies %.3f/%.3f' % (gbdt_train, gbdt_test))