利用sklearn 建立随机森林与adaboost模型,并用于银行营销数据集预测

关于数据集:

 具体的要求为:

import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier # 导入随机森林模型
from sklearn.model_selection import train_test_split  # 导入数据集划分模块
import matplotlib.pyplot as plt
from sklearn.metrics import roc_auc_score
from sklearn.metrics import classification_report
import warnings
warnings.filterwarnings("ignore") 

# 数据的读入与处理
tags=['年龄', '工作类别','婚姻状况','教育','违约情况','住房贷款','个人贷款','接触方式','最后一个联系月份','最后一周的联系日','最后的接触持续时间','执行人数量','联系过去之后的天数','联系人数','前一次营销结果','定期存款']
data_path ='bank.csv'
df = pd.read_csv(data_path,sep=';',names=tags)


##数据探索性分析
for s in tags:
	if str(df[s].dtype)=='object':
		print('标签{}为字符串类型,因此不进行数值分析\n'.format(s))
	else:
		print('标签{}的取值范围为:{}--{}\t50%分位数:{}\t标准值:{}\t均值:{}\n'.format(s,
	                                                                            min(df.loc[ : ,s]),
	                                                                            max(df.loc[ : ,s]),
	                                                                            df.describe()[s]['50%'],
	                                                                            df.describe()[s]['std'],
	                                                                            df.describe()[s]['mean'],
	))

# 画出相关性热力图(但是得在编码之后才可以进行)
import seaborn as sns
sns.set_style('whitegrid',{'font.sans-serif':['simhei','Arial']}) 	#解决中文乱码
plt.rcParams['axes.unicode_minus']=False 		#显示负数
ax=sns.heatmap(pd.get_dummies(df).corr(),cmap="Blues", fmt='.2g')
ax.set_title('相关性热力图')  # 图标题
ax.set_xlabel('真实情况')
ax.set_ylabel('预测情况')
plt.show()



######Begin ######
# 任务1. 去除'day','month','poutcome'特征属性
df.drop(['最后一个联系月份','最后一周的联系日','前一次营销结果'], axis=1, inplace=True)
###### End ######


######Begin ######
# 任务2. 替换部分样本值
df['工作类别'].replace(['unknown'],df['工作类别'].mode(),inplace=True)
df['工作类别'].isin(['unknown']).sum()
df['教育'].replace(['unknown'],df['教育'].mode(),inplace=True)
df['教育'].isin(['unknown']).sum()
###### End ######


######Begin ######
# 任务3. 将特征采用哑变量进行编码,字符型特征经过转化可以进行训练
features=pd.get_dummies(df.iloc[:,:-1])
###### End ######
df['定期存款'] = df['定期存款'].replace(to_replace=['no', 'yes'], value=[0, 1])
labels=df.loc[:,'定期存款']

##划分测试训练集,用来下面两个模型建模
x_train, x_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=1)# 按4:1的比例划分训练和测试集


######Begin ######
#画折线图以及随机森林的模型建立
y_sroce=[]
for num_tree in range(20,201,20):	##以20为决策树数量的步长
	RFC=RandomForestClassifier(n_estimators=num_tree,random_state=90,oob_score = True)
	RFC.fit(x_train,y_train)
	y_sroce.append(RFC.oob_score_)


plt.rc("font",family="SimHei",size="15")  #解决中文乱码问题
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']

x_axis=[(i+1)*20 for i in range(len(y_sroce))]
plt.plot(x_axis,y_sroce)
plt.plot(x_axis, y_sroce,'o', linewidth=3) 
plt.ylabel('袋外样本得分')
plt.xlabel('基模型数量')
plt.title('随机森林模型在不同基模型数量下的袋外样本得分')
plt.show()

RFC_pre_test=RFC.predict(x_test)# 对于测试集x_test进行预测

###### End ######


##adaboost模型建立
from sklearn.ensemble import AdaBoostClassifier
y_sroce=[]
for num_base in range(20,201,20):	##以20为决策树数量的步长
	AdaBoost_model = AdaBoostClassifier(random_state=45,n_estimators=num_base)
	AdaBoost_model.fit(x_train,y_train)
	y_sroce.append(AdaBoost_model.score(x_train,y_train))

x_axis=[(i+1)*20 for i in range(len(y_sroce))]
plt.plot(x_axis,y_sroce)
plt.plot(x_axis, y_sroce,'o', linewidth=3) 
plt.ylabel('训练集精确率')
plt.xlabel('基分类器数量')
plt.title('adaboost模型在不同基分类器数量下的训练集精确率')
plt.show()



Ada_pre_test=AdaBoost_model.predict(x_test)
print('特征重要性为:{}\n各分类器权重为:{}\n各分类器错误率为:{}\n'.format(AdaBoost_model.feature_importances_,AdaBoost_model.estimator_weights_,AdaBoost_model.estimator_errors_))
print(len(AdaBoost_model.estimator_weights_))
print(len(AdaBoost_model.feature_importances_))

##各模型文本指标以及AUC值
print('adaboost文本指标:{}\n'.format(classification_report(y_test, Ada_pre_test)))
print('随机森林文本指标:{}\n'.format(classification_report(y_test, RFC_pre_test)))
print("adaboost模型AUC值:{}\n".format(roc_auc_score(y_test, Ada_pre_test)))
print("随机森林模型AUC值:{}\n".format(roc_auc_score(y_test, RFC_pre_test)))



出现的报错:

sklearn.exceptions.NotFittedError: This AdaBoostClassifier instance is not fitted yet. Call 'fit' with appropriate arguments before using this estimator.

解决方法为:

你需要对模型先进行拟合才可以进行后续操作,如:

from sklearn.ensemble import AdaBoostClassifier
y_sroce=[]


for num_base in range(20,201,20):	##以20为决策树数量的步长

##错误示范
	AdaBoost_model = AdaBoostClassifier(random_state=45,n_estimators=num_base)
	y_sroce.append(AdaBoost_model.score(x_train,y_train))

##正确示范
	AdaBoost_model = AdaBoostClassifier(random_state=45,n_estimators=num_base)
	AdaBoost_model.fit(x_train,y_train)        #需要对模型先拟合
	y_sroce.append(AdaBoost_model.score(x_train,y_train))

而且关于基分类器权重全为1的情况

这个是因为你用的是默认的adaboost中的SAMME.R方法,adaboost的algorithm参数有两种方式SAMME, 和SAMME.R两种,默认是SAMME.R,两者的区别主要是弱学习器权重的度量,前者是对样本集预测错误的概率进行划分的,后者是对样本集的预测错误的比例,即错分率进行划分的,默认是用的SAMME.R。所以你只需要略微调一下参数即可

猜你喜欢

转载自blog.csdn.net/kuyecsl/article/details/131232881