์์ํ๋ฉฐ
์ด์ ์ ์งํํ๋ ํ๋ก์ ํธ์ ๋ํด ์ ๋ฆฌํด๋ณด๋ ค๊ณ ํ๋ค. ํผ์์ ํ์ผ๊ณผ ๋ฌธ์ํ์์ผ๋ก ์ ์ฅํด๋์์์ง๋ง, ๊ณต์ ํ๋ ์ถ์ ์ด์๋ณด๊ณ ์ ๋ชจ๋ ํ๋ก์ ํธ๋ฅผ ์ฐจ๊ทผ์ฐจ๊ทผ ์ ๋ก๋ํด๋ณผ ์์ ์ด๋ค :)
ํ๋ถ์ ์์ค์์ ์งํํ ํ๋ก์ ํธ์ด๊ธฐ์, ๋๋จํ์ง๋ ๋ฐ์ด๋์ง๋ ์๋๋ค.
๋จ์ง ์ ๋ช
ํ ๋ฐ์ดํฐ์
์ ๊ฐ์ง๊ณ ๋ด๊ฐ ๊ฐ์ง ๊ธฐ์ ์ ์ฆ๋ช
ํด๋ณด๊ธฐ ์ํด ์งํํ๋ ํ๋ก์ ํธ๊ฐ ๋๋ถ๋ถ์ด๋ค.
ํผ์ ์งํํ ๊ฒ์ด ์๋, ํ์๋ค๊ณผ ์งํํ ๊ฒ์ผ๋ก ์์ธํ ์ ์ฒด ์ฝ๋์ ๋ํ ์
๋ก๋๋ ํ์ง ์์ ์์ ์ด๊ณ
๋ด๊ฐ ๋ด๋นํ๋ ๋ถ๋ถ ๋ถ๋ถ๋ง ์
๋ก๋ํ ์์ ์ด๋ค ;)
๊ทธ๋๋! ์ง๋๊ฐ์๋ค๊ฐ ํน์ ์ฝ์ด๋ณด์๊ณ , ์๋ชป๋ ๋ถ๋ถ, ๊ฐ์ ์ ์ฌ์ง๊ฐ ์๋ ๋ถ๋ถ, ๋ฌธ์ ์ ๋ฑ์ ๋ํ ๋ชจ๋ ํผ๋๋ฐฑ์ ํ์์ ๋๋ค. ๋ง์์ฌ๋๋ค์๊ฒ ๋ฐฐ์ฐ๊ณ ์ถ์ด์!
ํ๋ก์ ํธ ์ฃผ์
TM(ํ ๋ ๋ง์ผํ )์ด ์ํ๊ฐ์ ์ผ๋ก ์ด์ด์ง๋ ๊ณ ๊ฐ๊ตฐ ๋ถ์
์ฃผ์ ์ ์ ๋ฐฐ๊ฒฝ
TM(ํ ๋ ๋ง์ผํ )์ ํ๋งค ์ค์ ์ ๋ณดํ์ฌ / ์นด๋์ฌ์์ ๊ฐ๊ฐ 8%์ 5%๋ฅผ ์ฐจ์งํ๋ฏ๋ก ๋ฌด์ํ์ง ๋ชปํ๋ ์ค์ ์ ๋ฌ์ฑํ๊ณ ์๋ ๊ฒ์ ํ์ธํด ๋ณผ ์ ์๋ค. ์ฆ, ๊ธ์ต๊ถ, ๋ณดํ์ฌ, ํต์ ์ฌ ๋ฑ ๋ค์ํ ์ฐ์ ์ ๊ธฐ์ ์์ TM์ ํ์ฉํ์ฌ ๊ณ ๊ฐ ์์ ์ ํ๋ ์ค์ด๊ณ , ์์ต์ ๊พธ์คํ ์ฌ๋ฆฌ๊ณ ์๋ ๊ฒ์ผ๋ก ํ๋จํ๋ค.
ํ์ง๋ง ๋๋ถ๋ถ์ ์ฌ๋๋ค์ TM ์ ํ๋ฅผ ์คํธ ์ ํ๋ก ์ธ์ํ๊ณ ์๋ค. ๋ฐ๋ผ์ ๊ธฐ์ ์๊ฒ๋ ๊ผญ ํ์ํ ๋ง์ผํ ์ ๋ต์ด์ง๋ง, ๊ณ ๊ฐ์ ๋๋ถ๋ถ์ TM ์ ํ ์์ ์ ์์น ์๋๋ค๊ณ ํ๋จํ ์ ์์๋ค.
๊ฒฐ๋ก ์ ์ผ๋ก, ๊ธฐ์ ์ ์ ์ฅ์์๋ TM ์ ํ๋ฅผ ๋ฐ์๋ค๊ฐ ๋์ด๋ฒ๋ฆฌ๊ฑฐ๋, ์ ๊ณ ํ๋ ๊ณ ๊ฐ๊ตฐ์ ์ ์ธํ ์ต์ํ์ ๊ณ ๊ฐ๊ตฐ์ ์ ์ ํ์ฌ TM ๋ง์ผํ ์ ์งํํด์ผํจ์ ์ ์ ์๋ค.
์ ์ฒด ๊ณ ๊ฐ๊ตฐ ๋ณด๋ค๋ ์์ ์ฑ๊ณต๋ฅ ์ด ๋์ ํน์ ํ๊ฒ์ ๋์์ผ๋ก TM์ ์งํํ์ฌ TM ํฌ์ ๋น์ฉ์ ์ ๊ฐํ ์ ์๋ ๋ฐฉ์์ ์ฐพ์๋ณด๊ณ ์ ์ด๋ฐ ํ๋ก์ ํธ๋ฅผ ์งํํ๊ฒ ๋์๋ค.
ํ๋ก์ ํธ์ ๋ชฉ์
TM์ด ์ํ ๊ฐ์ ์ผ๋ก ์ด์ด์ง๋ ๊ณ ๊ฐ๊ตฐ์ ํน์ฑ์ ๋ถ์ํ์ฌ ์ด๋ค ๊ณ ๊ฐ์๊ฒ TM์ ์ํํด์ผํ๋ ๊ฒ์ด ํ๋นํ ์ง ์์ธกํ๊ณ , ์ด๋ฅผ ํตํด TM์ ํจ๊ณผ๋ฅผ ๋์ด๊ณ ํฌ์ ๋น์ฉ์ ์ต์ํํ๋ ๋ฐฉ๋ฒ์ ๋ชจ์ํ๋ค.
ํ์ฉ ๋ฐ์ดํฐ
UCI์ ์ํ ํ ๋ ๋ง์ผํ ๋ฐ์ดํฐ
ํ์ฉ ์๊ณ ๋ฆฌ์ฆ
Naive Bayes / Decision Tree / CART / Random Forest / SVM / Logistic Regression / ANN
Step1. ๋ฐ์ดํฐ ํ์
1. poutcome - previous ์ ๊ด๊ณ
- ์ด์ TM์ด ์ฑ๊ณตํ ๊ณ ๊ฐ์ TM์ด์ ์ฐ๋ฝ ํ์๊ฐ ์ ์ผ๋ฉด ์ํ ๊ฐ์ ์ผ๋ก ์ด์ด์ง ํ๋ฅ ์ด ๋๋ค.
- ์ด์ TM ์ฑ๊ณต ์ ๋ฌด๊ฐ ๋ถ๋ถ๋ช ํ ๊ฒฝ์ฐ๋ TM ์ด์ ์ฐ๋ฝ ํ์์ ๊ด๊ณ ์์ด ๋์ฒด๋ก ์ํ์ ๊ฐ์ ํ์ง ์๋๋ค.
2. poutcome - campaign ์ ๊ด๊ณ
- ์ด์ TM์ด ์ฑ๊ณตํ ๊ฒฝ์ฐ TMํ์๊ฐ ์ ์ด์ผ ์ํ๊ฐ์ ์ผ๋ก ์ด์ด์ง๋ค.
- ์ด์ TM์ ์ฑ๊ณต์ ๋ฌด๊ฐ ๋ถ๋ถ๋ช ํ ๊ฒฝ์ฐ TMํ์๊ฐ ๋ง์ผ๋ฉด ์ํ์ ๊ฐ์ ํ์ง ์๋๋ค.
- ์ด์ TM์ด ์ฑ๊ณต๋ ์คํจ๋ ์๋๋ผ๋ฉด, ํ์๊ฐ ๋๋ฌด ๋ง๊ฑฐ๋ ์ ์ ๋ ์ํ์ ๊ฐ์ ํ์ง ์๋๋ค.
3. poutcome - pdays ์ ๊ด๊ณ
- ์ด์ TM์ด ์ฑ๊ณตํ ๊ณ ๊ฐ์๊ฒ ์งง์ ๊ฐ๊ฒฉ์ ๋๊ณ ๋ค์ TM์ ์ํํ๋ฉด ์ํ ๊ฐ์ ์ด ์คํจ๋ก ์ด์ด์ง ํ๋ฅ ์ด ํฌ๋ค.
- ์ด์ TM์ด ์คํจํ ๊ณ ๊ฐ์๊ฒ ํ์ฐธ ํ์ ๋ค์ TM์ ์ํํ๋ฉด ์ํ ๊ฐ์ ์ ์ฑ๊ณตํ ๊ฐ๋ฅ์ฑ์ด ํฌ๋ค.
Step2. ๋ณ์ ํ์ ๋ณ๊ฒฝ
์ข ์๋ณ์๋ฅผ ๋ฒ์ฃผํ ๋ณ์๋ก ๋ฐ๊ฟ์ฃผ๋ ๊ณผ์ ์ ์ํ
setwd('C:\\Users\\Desktop')
bank<-read.csv('bank_term_deposit.csv')
str(bank)
#์ข
์๋ณ์๋ฅผ ๋ฒ์ฃผํ ๋ณ์๋ก ๋ฐ๊ฟ
bank$y<-factor(bank$y)
summary(bank)
str(bank)
#1ํ & age ๋ณ์ ์ญ์
bank<-bank[,-1:-2]
str(bank)
๋ฐ์ดํฐ๋ฅผ bank ๋ณ์์ ์ ์ฅํ ํ, y๊ฐ์ ๋ฒ์ฃผํ ๋ณ์๋ก ๋ณํํด์ฃผ์๋ค.
๊ทธ๋ฆฌ๊ณ ๋ถ์์ ํ์ ์๋ค๊ณ ์๊ฐ๋๋ age ๋ณ์์, ์ฒซ๋ฒ์งธ ํ์ ์ญ์ ํด ์ฃผ์๋ค.
step3. ๋ฐ์ดํฐ ๋ถํ ๋ฐ ์ค๋ฒ์ํ๋ง
#๋ฐ์ดํฐ ๋ถํ
set.seed(123)
index<-sample(3,nrow(bank),replace=TRUE,prob=c(0.5,0.25,0.25))
bank.train<-bank[index==1,]
bank.validation<-bank[index==2,]
bank.test<-bank[index==3,]
table(bank.train$y)
#์ค๋ฒ์ํ๋ง
library(ROSE)
data.balanced.over<-ovun.sample(y~., data=bank.train,
p=0.5, seed=1,
method='over')$data
table(bank.train$y) #ํ๋ จ ๋ฐ์ดํฐ
table(data.balanced.over$y) #์ค๋ฒ์ํ๋ง ๋ฐ์ดํฐ
์ค๋ฒ์ํ๋ง์ ์งํํ์ง ์์๋ ํ๋ก์ ํธ์ ์ด๊ธฐ ๋จ๊ณ์์๋, Accuracy๊ฐ ์๋นํ ๋ฎ๊ณ , ๋ฐ์ดํฐ์ ๊ฐฏ์๊ฐ ์ถฉ๋ถํ์ง ๋ชปํ๋ค๊ณ ์๊ฐ๋์ด ์ค๋ฒ์ํ๋ง์ ์งํํ๊ฒ ๋์๋ค.
Step3. ๋ชจ๋ธ๋ง
1. Decision Tree
#Decision tree _ data.balanced.over
DT.bank2<-C5.0(y ~ ., data = bank.train)
DT.bank.predict2<-predict(DT.bank2, bank.validation)
DT.bank.table2<-table(bank.validation$y, DT.bank.predict2)
DT.bank.table2
paste('decision tree accuracy2 :',
(DT.bank.table2[1,1]+DT.bank.table2[2,2])/sum(DT.bank.table2))
2. CART
# CART
bank.cart = rpart(y~., data=bank.train, control = rpart.control(minsplit=10))
print(bank.cart)
plot(bank.cart)
text(bank.cart,use.n = T)
print(bank.cart$cptable)
opt=which.min(bank.cart$cptable[,"xerror"])
cp=bank.cart$cptable[opt,"CP"]
bank_prune=prune(bank.cart,cp=cp) #๊ฐ์ง์น๊ธฐ
print(bank_prune)
plot(bank_prune)
text(bank_prune)
bank.prune_pre=predict(bank_prune, newdata = bank.validation, type = 'class')
bank.prune_pre
bank.prune_tab = table(bank.validation$y,bank.prune_pre)
bank.prune_tab
bank.prune_tab
paste('CART accuracy :',
(bank.prune_tab[1,1]+bank.prune_tab[2,2])/sum(bank.prune_tab))
3. RandomForest
3-1) CV๋ฅผ ํ์ฉํ ํ๋ผ๋ฏธํฐ ํ๋ ์งํ
library(cvTools)
library(foreach)
set.seed(123); K=10 ;R=3
cv <- cvFolds(Nrow(bank), K=K, R=R)
grid <- expand.grid(ntree = c(10, 100, 200), .combine = rbind) %do% {
foreach(r = 1:R, .combine = rbind) %do% {
foreach(k=1:K, .combine = rbind) %do% {
validation_idx <- cv$subsets[which(cv$which == k), r]
train <- bank[-validation_idx, ]
validation <- bank[validation_idx, ]
#๋ชจ๋ธํ๋ จ
m <- randomForest(y~., data = train, ntree=grid[g, "ntree"],
mtry = grid[g, "mtry" ]
#์์ธก
predicted <- predict(m, newdata = validation)
#์ฑ๋ฅํ๊ฐ
accuracy <- sum(predicted == validation $ y) / NROW(predicted)
return(data.frame(g=g, accuracy = accuracy))
}
}
}
result
library(plyr)
ddply(result, .(g), summarize, mean_accuracy = mean(accuracy))
grid[c(6), ]
- ntree = 200, myry = 4 ์ผ ๋ ์ ํ๋๊ฐ 90.83%๋ก ๊ฐ์ฅ ๋์
3-2) ๋ชจ๋ธ๋ง
#Random Forest
install.packages("randomForest")
library(randomForest)
RF.bank<-randomForest(y~., data=bank.train)
RF.bank.predict<-predict(RF.bank, bank.validation)
RF.bank.table<-table(bank.validation$y,RF.bank.predict)
paste('random forest accuracy :',
(RF.bank.table[1,1]+RF.bank.table[2,2])/sum(RF.bank.table))
4. Logistic Regression
#Logistic Regression
logit.bank<-glm(y~., family=binomial, data=bank.train)
logit.bank.predict<-(predict(logit.bank,bank.validation, type="response")>=0.5)
logit.bank.table<-table(bank.validation$y, logit.bank.predict)
logit.bank.table
paste('logistic regression accuracy :',
(logit.bank.table[1,1]+logit.bank.table[2,2])/sum(logit.bank.table))
5. SVM
#SVM
library(e1071)
#numeric ๋ณ์ normalization
normalize<-function(x){
return((x-min(x))/(max(x)-min(x)))
}
bank.train$age<-normalize(bank.train$age)
bank.train$balance<-normalize(bank.train$balance)
bank.train$duration<-normalize(bank.train$duration)
head(bank.train)
bank.validation$age<-normalize(bank.validation$age)
bank.validation$balance<-normalize(bank.validation$balance)
bank.validation$duration<-normalize(bank.validation$duration)
SVM.bank<-svm(y~age+balance+duration+campaign+pdays+previous, data=bank.train)
SVM.bank.predict<-predict(SVM.bank,bank.validation)
SVM.bank.table<-table(bank.validation$y, SVM.bank.predict)
SVM.bank.table
step4. ๋ชจ๋ธ ์ ์
์์ Accuracy ๊ฐ ํ์ ํ ๋ฎ์์, ์ค๋ฒ์ํ๋ง์ ํ๊ณ ๋ค์ ๋ชจ๋ธ๋ง์ ์งํํ๋ค๊ณ ์ธ๊ธํ๋ค.
๋ฐ๋ผ์ ์ต์ข ์ ์ผ๋ก๋,
0.928์ Accuracy, 0.808์ recall ๊ฐ์ ๋์ถํด๋ธ, Logistic Regression ๋ชจ๋ธ์ ์ต์ข ๋ชจ๋ธ๋ก ์ ์ ํ๋ค.
step7. ROC ์ปค๋ธ ํ์ธ
#ROC curve๋ฅผ ํตํ ์ต์ cut-off value ํ์ธ
ROC = roc(bank.validation$y, pred.bin3)
plot.roc(ROC, col = 'red', print.auc = FALSE, max.auc.polygen=True,
print.thres=True, prin.thres.pch=19, print.thres.col="black",
auc.polygon=True, auc.polygon.col = "#D1F2EB")
cut-off value๊ฐ 0.5์ผ ๋ ๊ฐ์ฅ ์ข์ ์ฑ๋ฅ์ ๋ณด์.
0.5 ์ด์์ด๋ฉด 1๋ก ๋ถ๋ฅํ๋๋ก ํ๋ฉด ๋ ๊ฒ์ด๋ผ๊ณ ํ๋จํ๋ค.
step6. ์ฑ๋ฅ ํ์ธ
#Lift Chart
pr <- prediction(pred.test, bank.test$y)
model.lift2 <- performance(pr, "lift", "rpp")
with.pragh(); plot(model.lift2, col = "red")
ํ ์คํธ ๋ฐ์ดํฐ์ ๋ํ Lift Chart๋ฅผ ์ถ๋ ฅํด ๋ณด์๋๋ฐ, ์ต์์ ํ๋ฅ ์ ๊ฐ์ง ๊ณ ๊ฐ์๊ฒ๋ ์ฝ๊ฐ ๋ถ์์ ํ์ง๋ง ์ ์ ์์ ๋๊ฒ ์ฌ๋ฐ๋ฅด๊ฒ ๋ถ์ํ๊ณ ์์์ ์ ์ ์๋ค.
๊ธฐ๋ํจ๊ณผ
1. ์ ์ฒด ๊ณ ๊ฐ๊ตฐ ์ค ์ผ๋ถ๋ง ์ถ์ถํ๋๋ผ๋ ์ํ ๊ฐ์
๊ฐ๋ฅ์ฑ์ด ๋์ ๊ณ ๊ฐ์ ์ ๋ณ ๊ฐ๋ฅํ๋ค.
2. ๋ชจ๋ ๊ณ ๊ฐ์๊ฒ ํ๋ ์ผ๊ด์ ์ธ ๋ง์ผํ
๋ณด๋ค ๋น์ฉ์ด ํฌ๊ฒ ๊ฐ์ํ ๊ฒ์ด๋ค.
3. ์ฌํ๋ฅ (recall)์ ๋์์ผ๋ก์จ ๋ฎ์ ์ ํ๋ ๋๋น ๋์ ์์ต์ ๊ธฐ๋ํ ์ ์์ ๊ฒ์ด๋ค.
์ด ํ๋ก์ ํธ์ ํ๊ณ์
1. ๊ณ ๊ฐ๋ณ ์ํ ๊ฐ์
์ ๊ท๋ชจ๋ฅผ ๊ณ ๋ คํ์ง ์์๋ค.
2. ์ ๋ฐ๋ (Precision)์ด ๋ฎ์ ์ ํ๋ ๊ณ ๊ฐ ์ค ๊ฐ์
์์ฌ๊ฐ ์๋ ๊ณ ๊ฐ์ด ์๋ค.
3. ์ค๋ฒ์ํ๋งํ ๋ฐ์ดํฐ์ด๊ธฐ ๋๋ฌธ์ ์ค์ ์ ๋ค๋ฅผ ์ ์๋ค.
๋ง์น๋ฉฐ
ํ๋ถ์๋ ์งํํ๋ ์ฝ๋๋ฅด ๋ณด๋ ์ ํํ์ง ์์ ๋ณ์๋ช ๋ ๋ง๊ณ , ์ฝ๋๊ฐ ์ข ์ด์ง๋ฝ๋ค. ๋๋ถ์ด ๋ถ์์ ์ ๋๋ก ์ํํ๋ค ํ๋ ์์ (?)๋ํ ์๋ค. ํ์ง๋ง ์ด ์์ ์ ๋ค์ ์ ๋ฆฌํด๋ด์ผ๋ก์จ ๋์๊ฒ ๋ฌด์์ด ๋ถ์กฑํ์ง, ๋ฌด์จ ๊ณต๋ถ๊ฐ ๋ ํ์ํ์ง์ ๋ํด ์ฐพ์๋ณผ ์ ์์๋ค. ์์ผ๋ก๋ ํต๊ณ๊ณต๋ถ๋ฅผ ์กฐ๊ธ ๋ ํ๊ณ , ํ์๋ณ์๋ฅผ ์์ฑํ๋ค๋์ง, ๋ค๋ฅธ ์์์๋ธ๋ชจ๋ธ์ ํ์ฉํ๋ค๋์งํด์ ์ ํ๋๋ฅผ ์ฌ๋ฆฌ๋ ๋ฐฉ๋ฒ์ ๋ชจ์ํด ๋ณผ๊ฒ์ด๋ค.