R语⾔(把银⾏已认购定期存款的客户原始数据建⽴决策树模型,从⽽预测新⼀
批客户是否会认购定期存款)
原始数据:
输⼊变量:
#银⾏客户资料:
1-年龄(数字)
2-⼯作:⼯作类型(分类:“管理”,“未知”,“失业”,“管理”,“⼥佣”,“企业家”,“学⽣”,“蓝领”、“个体户”、“退休⼈员”、“技术⼈员”、“服务⼈员”)
3-婚姻:婚姻状况(分类:“已婚”、“离婚”、“单⾝”;注:“离婚”指离婚或丧偶)
4-教育(分类:“未知”、“中等”、“初级”、“⾼等”)
5-违约:信⽤违约吗?(⼆进制:“是”,“否”)
6-余额:年平均余额,单位:欧元(数字)
7-住房:有住房贷款吗?(⼆进制:“是”,“否”)
8-贷款:有个⼈贷款吗?(⼆进制:“是”,“否”)
#与当前活动的最后⼀个联系⼈相关:
9-联系⼈:联系⼈通信类型(分类:“未知”、“电话”、“⼿机”)
10天:每⽉的最后⼀个联系⽇(数字)
11个⽉:⼀年中最后⼀个联系⽉(分类为:“⼀⽉”、“⼆⽉”、“三⽉”、“⼗⼀⽉”、“⼗⼆⽉”)
12-持续时间:上次联系持续时间,以秒为单位(数字)
#其他属性:
13-活动:在此活动期间为此客户执⾏的联系⼈数(数字,包括最后⼀个联系⼈)
14-pdays:上次从上⼀个活动联系客户后经过的天数(数字,-1表⽰以前没有联系过客户)
15-上⼀页:在此活动之前为此客户执⾏的联系⼈数(数字)
16-poutcome:上⼀次营销活动的结果(分类:“未知”、“其他”、“失败”、“成功”)
输出变量(所需⽬标):
17-y-客户是否已认购定期存款?(⼆进制:“是”,“否”)
#设置⼯作空间,导⼊数据
twd('D:/bankfull')
bankfull <- read.csv2("bank-full.csv",stringsAsFactors =F)# 数据读取
#查看变量
names(bankfull)
#数据探索
summary(bankfull)
#处理噪声数据
library(outliers)
outlier(as.numeric(bankfull$balance))# opposite = FALSE, logical = FALSE
#检测NA值,并输出其位
which(is.na(bankfull))
#删除含有缺失值的⾏
it(bankfull)
#删掉所有列上都重复的
bankfull<-bankfull[!duplicated(bankfull),]
#将处理后的数据保存
write.csv(bankfull,'bankfull.csv')
#提取数据的第⼀列(年龄),第五列(是否信⽤违约);将数据按照年龄升序排序
newbankdata <- bankfull[,c(1,5)]
newbankdata=newbankdata[order(newbankdata$age),]#默认升序
write.csv(newbankdata,'newbankdata.csv')
#统计违约⼈数
weiyuenum<-data.frame(table(newbankdata[,2]))
write.csv(weiyuenum,'weiyuenum.csv')
#将其中违约的提取出来
weiyue <-subt(newbankdata,newbankdata$default=="yes")
write.csv(weiyue,'weiyue.csv')
#age<=12的为⼩孩;12<age<=30的为青年;30<age<=60的为中年;age>60的为⽼年
a<-cut(weiyue$age,breaks=c(-Inf,12,30,60,Inf),
labels =c("⼩孩","青年","中年","⽼年"))
weiyue<-cbind(weiyue,a)
write.csv(weiyue,'weiyue.csv')
write.csv(weiyue,'weiyue.csv')
#统计违约的⼈中"青年","中年","⽼年"的⼈数及⽐例
weiyuenum2<-data.frame(table(weiyue[,3]))
#算出占⽐
weiyuenum2$percent<- weiyuenum2$Freq/sum(weiyuenum2$Freq)
write.csv(weiyuenum2,'weiyuenum.csv')
#绘制饼图
library('vcd')
names <-paste(weiyuenum2$Var1,weiyuenum2$percent,p="---")
#饼图
pie(weiyuenum2$Freq,labels=names,col=rainbow(10),main="不同年龄段中违约数量统计")
#可以看出中年违约⼈数最多,信⽤危机越⼤,即信⽤不好。
#将完整数据中的违约的⼈提取出来
weiyuefull <-subt(bankfull,bankfull$default=="yes")
write.csv(weiyuefull,'weiyuefull.csv')
#在全部数据中将是否认购定期存款为yes的提取出来
yyes <-subt(bankfull,bankfull$y=="yes")
write.csv(yues,'yyes.csv')
#提取数据的第三列(婚姻),第⼗七列(是否认购定期存款);
maritalisyyes <- yyes[,c(3,17)]
write.csv(maritalisyyes,'maritalisyyes.csv')
#统计⼈数及⽐例
maritalisyyesnum<-data.frame(table(maritalisyyes[,1]))
#算出占⽐
maritalisyyesnum$percent<- maritalisyyesnum$Freq/sum(maritalisyyesnum$Freq)
write.csv(maritalisyyesnum,'maritalisyyesnum.csv')
#绘制饼图
library('vcd')
names <-paste(maritalisyyesnum$Var1,maritalisyyesnum$percent,p="---")
#饼图
pie(maritalisyyesnum$Freq,labels=names,col=rainbow(10),main="不同婚姻状态中认购定期存款数量统计")
#可以看出已婚的⼈去认购定期存款的⼏率⼤
#在全部数据中将是否认购定期存款为yes的提取出来
yyes <-subt(bankfull,bankfull$y=="yes")
write.csv(yyes,'yyes.csv')
#提取数据的第四列(教育),第⼗七列(是否认购定期存款);
educationisyyes <- yyes[,c(4,17)]
write.csv(educationisyyes,'educationisyyes.csv')
#统计⼈数及⽐例
educationisyyesnum<-data.frame(table(educationisyyes[,1]))
#算出占⽐
educationisyyesnum$percent<- educationisyyesnum$Freq/sum(educationisyyesnum$Freq)
write.csv(educationisyyesnum,'educationisyyesnum.csv')
#绘制饼图
library('vcd')
names <-paste(educationisyyesnum$Var1,educationisyyesnum$percent,p="---")
#饼图
pie(educationisyyesnum$Freq,labels=names,col=rainbow(10),main="不同受教育程度中认购定期存款数量统计")
#可以看出受教育程度为中级去认购定期存款的⼏率⼤,其次是⾼级
#把银⾏已认购定期存款的客户原始数据建⽴决策树模型,从⽽预测新⼀批客户是否会认购定期存款
#设置⼯作空间,导⼊数据
twd('D:/bankfull')
newbank <- read.csv2("bank-full.csv",stringsAsFactors =F)# 数据读取
#获取描述性统计量,可以提供最⼩值、最⼤值、四分位数和数值型变量的均值,以及因⼦向量和逻辑型向量的频数统计bankdata<-summary(newbank)
#t.ed()括号⾥⾯的参数可以是任意数字,是代表你设置的第⼏号种⼦⽽已,不会参与运算,是个标记⽽已。
#t.ed()函数是为了保证你随机⽣成的随机数前后⼀致
t.ed(1)
#做训练集和测试集
sub<-sample(1:nrow(newbank),round(nrow(newbank)*2/3))
sub<-sample(1:nrow(newbank),round(nrow(newbank)*2/3))
length(sub)#30141
data_train<-newbank[sub,]#取2/3的数据做训练集
data_test<-newbank[-sub,]#取1/3的数据做测试集
dim(data_train)#训练集⾏数和列数30141 17
dim(data_test)#测试集⾏数和列数15070 17
table(data_train$y)#看该列分布的 no-26610 yes-3531
table(data_test$y)#看该列分布的 no-26610 yes-3531
#CART ID3决策树
library(sampling)
library(party)
library(rpart)
library(rpart.plot)
library(rattle)
#⽤训练集建模,观察模型结果
bank_tree<-rpart(as.factor(y)~.,data=data_train,method='class',minsplit=20,minbucket=150,cp=0.00017) summary(bank_tree)
print(bank_tree)
#绘制决策树
rpart.plot(bank_tree)
#对测试集进⾏测试
test_pre =predict(bank_tree,newdata = data_test)
test_pre <-data.frame(test_pre)
#写出最终的测试结果
b<-cut(test_pre$no,breaks=c(-Inf,0.5,Inf),
labels =c("yes","no"))
test_pre<-cbind(test_pre,b)
write.csv(test_pre,'test_pre.csv')
#将预测结果与真实结果对⽐并进⾏分析
ac <-table(test_pre[,3],data_test$y)
#计算出该决策树的accuracy(分类正确的样本数除以总样本数)
acc<-(ac[1,2]+ac[2,1])/(ac[1,1]+ac[1,2]+ac[2,1]+ac[2,2])
acc #0.9019244
#⽣成规则
asRules(bank_tree)
#CART剪枝
cp=bank_tree$cptable[which.min(bank_tree$cptable[,"xerror"]),"CP"]
cp #0.004106485
bank_tree2<-prune(bank_tree,cp=bank_tree$cptable[which.min(bank_tree$cptable[,"xerror"]),"CP"])
#再次绘制决策树
rpart.plot(bank_tree2)
#对测试集进⾏再次测试
test_pre2 =predict(bank_tree2,newdata = data_test)
test_pre2 <-data.frame(test_pre2)
#写出最终的测试结果
c<-cut(test_pre2$no,breaks=c(-Inf,0.5,Inf),
labels =c("yes","no"))
test_pre2<-cbind(test_pre2,c)
write.csv(test_pre2,'test_pre2.csv')
#将预测结果与真实结果对⽐并再次进⾏分析
ac2<-table(test_pre2[,3],data_test$y)
#再次计算出该决策树的accuracy(分类正确的样本数除以总样本数)
acc2<-(ac2[1,2]+ac2[2,1])/(ac2[1,1]+ac2[1,2]+ac2[2,1]+ac2[2,2])
acc2 #0.9021234
#再次⽣成规则
asRules(bank_tree2)