集成学习分类器

一、实验目的

(1) 掌握Bagging算法的原理;
(2) 掌握Adaboosting算法的原理;
(3) 掌握Sklearn建模的流程;
(4) 掌握调参的基本思想。

二、实验内容

(1)Bagging算法
在Bagging方法中,利用bootstrap方法从整体数据集中采取有放回抽样得到N个数据集,在每个数据集上学习出一个模型,最后的预测结果利用N个模型的输出得到,具体地:分类问题采用N个模型预测投票的方式,回归问题采用N个模型预测平均的方式。
例如随机森林(Random Forest)就属于Bagging。随机森林简单地来说就是用随机的方式建立一个森林,森林由很多的决策树组成,随机森林的每一棵决策树之间是没有关联的。
预测的时候,随机森林中的每一棵树的都对输入进行预测,最后进行投票,哪个类别多,输入样本就属于哪个类别。这就相当于前面说的,每一个分类器(每一棵树)都比较弱,但组合到一起(投票)就比较强了。
(2)Boosting算法
提升方法(Boosting)是一种可以用来减小监督学习中偏差的机器学习算法。主要也是学习一系列弱分类器,并将其组合为一个强分类器。Boosting中有代表性的是AdaBoost(Adaptive boosting)算法:刚开始训练时对每一个训练例赋相等的权重,然后用该算法对训练集训练t轮,每次训练后,对训练失败的训练例赋以较大的权重,也就是让学习算法在每次学习以后更注意学错的样本,从而得到多个预测函数。
(1)导入需要的库;
(2)导入数据集,完成数据清洗(填补缺失值或者删除、将字符串特征数值化、删除对分类无帮助的特征);
(3)进行一次简单的建模,看模型本身在数据集上的效果;
(4)采用网格搜索方法,寻找最优的的参数(n_estimators、criterion、min_samples_split、min_samples_leaf、,max_depth、,max_features);
(5)使用随机森林、Adaboosting算法,与决策树方法进行比较,对比结果;
(6)总结调参的经验(重点!)

三、实验代码

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import sklearn
from sklearn import datasets
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import GridSearchCV
from sklearn.tree import DecisionTreeClassifier
from sklearn.feature_extraction import DictVectorizer
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import AdaBoostClassifier


import warnings
warnings.filterwarnings("ignore")

train_data = pd.read_csv('D:\\Desktop\\大二下\\模式识别\\集成学习分类器\\titanic_train.csv')
print('训练集:')
print(train_data)
train_data.info()


#数据清洗
train_data['Age'].fillna(train_data['Age'].mean(),inplace = True)#在缺失的Age值中填入Age平均值
print('登陆口岸的情况:')
print(train_data['Embarked'].value_counts())#打印登陆口岸的情况
train_data['Embarked'].fillna('S',inplace = True)#用占比最多的登陆口岸'S'对缺失数据进行填充
#train_data.pop("PassengerId")
train_data.pop("Name")
train_data.pop("SibSp")
train_data.pop("Parch")
train_data.pop("Ticket")
train_data.pop("Cabin")
#train_data.pop("Fare")
#train_data.pop("Pclass")
train_data=train_data.dropna()#去掉含有NA的行

#特征选择
features = ['PassengerId','Pclass','Sex','Age','Fare','Embarked']
train_features = train_data
train_labels = train_data.pop('Survived')

#处理符号化的对象,将符号转化为数字
dv = DictVectorizer(sparse = False)
train_features = dv.fit_transform(train_features.to_dict(orient= 'record'))
print(dv.feature_names_)
def sex(x):
    if x=="male":
        return 0
    else:
        return 1
train_data["Sex"]=train_data["Sex"].apply(lambda x:sex(x))
print('train_data["Sex"]',train_data["Sex"])
def Embarked(x):
    if x=="S":
        return 0
    if x=="C":
        return 1
    if x=="Q":
        return 2

train_data["Embarked"]=train_data["Embarked"].apply(lambda x:Embarked(x))
print('train_data["Embarked"]',train_data["Embarked"])


#随机森林
print('随机森林')
#进行一次简单建模,看看模型本身在数据集上的效果
rfc = RandomForestClassifier(n_estimators=100,random_state=90)
score_pre = cross_val_score(rfc,train_data,train_labels,cv=10).mean()
print('简单建模得分:',score_pre)

#学习曲线
scorel = []
C = range(95,130,5)
for i in C:
    rfc = RandomForestClassifier(n_estimators=i,
                                 n_jobs=-1,
                                 random_state=90)
    score = cross_val_score(rfc,train_data,train_labels, cv=10).mean()
    scorel.append(score)
print('学习曲线最高分数:',max(scorel),'它的下标:',(95+scorel.index(max(scorel))*5))
plt.figure(figsize=[20,5])
plt.plot(C,scorel)
plt.show()

#网格搜索
print('随机森林网格搜索')
#调整n_estimators(基分类器提升次数)
param_grid={'n_estimators':np.arange(75, 120, 5)}
 
rfc = RandomForestClassifier(random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)
#调整最大深度
param_grid={'max_depth':np.arange(1, 10, 1)}
 
rfc = RandomForestClassifier(n_estimators=39
                             ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)
#调整Criterion
param_grid={'criterion':['gini','entropy']}
 
rfc = RandomForestClassifier(n_estimators=39
                             ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)
#调整min_samples_split
param_grid={'min_samples_split':np.arange(2, 10, 2)}
 
rfc = RandomForestClassifier(n_estimators=39
                             ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)
#调整min_samples_leaf
param_grid={'min_samples_leaf':np.arange(1, 10, 1)}
 
rfc = RandomForestClassifier(n_estimators=39
                             ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)
#调整max_features
param_grid={'max_features':np.arange(5, 15, 1)}
 
rfc = RandomForestClassifier(n_estimators=39
                             ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)

#Adaboosting
print('Adaboosting算法')
#进行一次简单建模,看看模型本身在数据集上的效果
rfc = AdaBoostClassifier(n_estimators=100,random_state=90)
score_pre = cross_val_score(rfc,train_data,train_labels,cv=10).mean()
print('简单建模得分:',score_pre)

#网格搜索
print('AdaBoosting网格搜索')
#调整n_estimators
param_grid={'n_estimators':np.arange(75, 120, 5)}
 
rfc = AdaBoostClassifier(base_estimator=None
                         ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)

#调整learning_rate
param_grid={'learning_rate':np.arange(0.5, 1.5, 0.1)}
 
rfc = AdaBoostClassifier(base_estimator=None
                         ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)

#调整algorithm(两者的区别主要是弱学习器权重的度量,前者是对样本集预测错误的概率进行划分的,后者是对样本集的预测错误的比例)
param_grid={'algorithm':['SAMME','SAMME.R']}
 
rfc = AdaBoostClassifier(base_estimator=None
                         ,random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)

#决策树
print('决策树')
#进行一次简单建模,看看模型本身在数据集上的效果
rfc = DecisionTreeClassifier(random_state=90)
score_pre = cross_val_score(rfc,train_data,train_labels,cv=10).mean()
print('简单建模得分:',score_pre)


#网格搜索
print('决策树网格搜索')
#调整最大深度
param_grid={'max_depth':np.arange(1, 20, 1)}
 
rfc = DecisionTreeClassifier(random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)
#调整Criterion
param_grid={'criterion':['gini','entropy']}
 
rfc = DecisionTreeClassifier(random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)
#调整min_samples_split
param_grid={'min_samples_split':np.arange(2, 10, 2)}
 
rfc = DecisionTreeClassifier(random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)
#调整min_samples_leaf
param_grid={'min_samples_leaf':np.arange(1, 10, 1)}
 
rfc = DecisionTreeClassifier(random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)
#调整max_features
param_grid={'max_features':np.arange(5, 15, 1)}
 
rfc = DecisionTreeClassifier(random_state=90
                            )
GS = GridSearchCV(rfc,param_grid,cv=10)
GS.fit(train_data,train_labels)

print(GS.best_params_)
print(GS.best_score_)

'''
#参数集成搜索
#随机森林网格搜索
print('随机森林网格搜索')
#定义参数及取值范围
tree_param_grid={'max_depth':np.arange(5, 7, 1)
                 ,'n_estimators':np.arange(100,120,5)
                 ,'min_samples_split':np.arange(4, 8, 2)
                 ,'criterion':['gini','entropy']
                 ,'min_samples_leaf':np.arange(4, 7, 1)
                 ,'max_features':np.arange(4, 6, 1)}
#构建模型(选择要选择的模型,选择参数集,选择交叉验证的CV)
GS=GridSearchCV(RandomForestClassifier(),param_grid=tree_param_grid,cv=10)
GS.fit(train_features, train_labels)
means = GS.cv_results_['mean_test_score'] #获取每个方案的分数均值
std=GS.cv_results_['std_test_score'] #获得分数的标准差
params = GS.cv_results_['params'] #获取参数组合
#输出参数组合
#for mean,std,param in zip(means,std,params):
#    print("mean: %f std: %f with: %r" % (mean,std,param))
#输出最优的参数以及最优的分数
print(GS.best_params_,GS.best_score_)


#Adaboosting网格搜索
print('adaboosting网格搜索')
#定义参数及取值范围
tree_param_grid={'n_estimators':np.arange(75,120,5)
                 ,'learning_rate':np.arange(0.5, 1.5, 0.1)
                 ,'algorithm':['SAMME','SAMME.R']}
#构建模型(选择要选择的模型,选择参数集,选择交叉验证的CV)
GS=GridSearchCV(AdaBoostClassifier(),param_grid=tree_param_grid,cv=10)
GS.fit(train_features, train_labels)
means = GS.cv_results_['mean_test_score'] #获取每个方案的分数均值
std=GS.cv_results_['std_test_score'] #获得分数的标准差
params = GS.cv_results_['params'] #获取参数组合
#输出参数组合
#for mean,std,param in zip(means,std,params):
#    print("mean: %f std: %f with: %r" % (mean,std,param))
#输出最优的参数以及最优的分数
print(GS.best_params_,GS.best_score_)


#决策树网格搜索
print('决策树网格搜索')
#定义参数及取值范围
tree_param_grid={'max_depth':np.arange(1, 10, 1)
                 ,'min_samples_split':np.arange(2, 10, 2)
                 ,'criterion':['gini','entropy']
                 ,'min_samples_leaf':np.arange(1, 10, 1)
                 ,'max_features':np.arange(5, 15, 1)}
#构建模型(选择要选择的模型,选择参数集,选择交叉验证的CV)
GS=GridSearchCV(DecisionTreeClassifier(),param_grid=tree_param_grid,cv=10)
GS.fit(train_features, train_labels)
means = GS.cv_results_['mean_test_score'] #获取每个方案的分数均值
std=GS.cv_results_['std_test_score'] #获得分数的标准差
params = GS.cv_results_['params'] #获取参数组合
#输出参数组合
#for mean,std,param in zip(means,std,params):
#    print("mean: %f std: %f with: %r" % (mean,std,param))
#输出最优的参数以及最优的分数
print(GS.best_params_,GS.best_score_)
'''

四、实验结果与分析

随机森林简单建模:在这里插入图片描述
通过该信息我们发现,在默认参数的条件下,分数已经较高。经过学习曲线调整n_estimators参数后,我们发现分数相差不大。
学习曲线:
在这里插入图片描述
通过学习曲线可知n_estimators参数不能设置过大或过小,太大会导致过拟合,而过小会导致欠拟合。
用随机森林模型进行分参数网格搜索:
在这里插入图片描述
通过运行结果我们可以发现,max_depth,min_samples_split及min_samples_leaf参数可以有效地提高随机森林模型的正确率。
Adaboosting算法简单建模:
在这里插入图片描述
我们可以很明显的看出Adaboosting算法的正确率要比随机森林低很多。
Adaboosting分参数网格搜索:
在这里插入图片描述

我们发现learning_rate参数对Adaboosting算法正确率的提升有不错的提升,而algorithm参数的选择可以极大的提高Adaboosting算法的正确率。Alogorithm有两个参数(SAMME,SAMME.R)前者是对样本集预测错误的概率进行划分的,后者是对样本集的预测错误的比例。
决策树简单建模:
在这里插入图片描述
我们发现决策树的正确率也是远小于随机森林的,只比Adaboosting高一点。
随机森林分参数网格搜索:
在这里插入图片描述
通过运行结果,进一步验证了我们对max_depth,min_samples_split及min_samples_leaf参数可以明显提高正确率的推测。由此可知,剪枝操作是极其重要的。
集成参数网格搜索:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们可以看出集成参数网格搜索调整的正确率更高,但缺点是运行时间长,我们只能通过缩小参数范围、删减参数个数或提高步长的方式来减少运算时间。在实际应用中,网格搜索法一般会先使用较广的搜索范围和较大的步长,来寻找全局最优值可能的位置;然后会逐渐缩小搜索范围和步长,来寻找更精确的最优值。这种操作方案可以降低所需的时间和计算量,但由于目标函数一般是非凸的,所以很可能会错过全局最优值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值