이론 설명 링크
1. Random Forest
Randomization
- Bootstrap samples (Bagging)
- Random selection of K <= p split variables (Random input selection)

장단점
- 숲의 크기(나무의 수)가 커질수록 일반화오류가 특정값으로 수렴하게 되어 over-fitting을 피할 수 있음
- 전체 학습용 데이터에서 무작위로 복원추출된 데이터를 사용함으로써 잡음이나 outlier로부터 크게 영향을 받지 않음
- 분석가가 입력변수 선정으로부터 자유로울 수 있음
- Class의 빈도가 불균형일 경우 타기법에 비해 우수한 예측력을 보임
- 최종결과에 대한 해석이 어려움
library(randomForest)
library(caret)
library(ROCR)
# 홈쇼핑 반품 고객 예측

cb <- read.delim("data/Hshopping.txt", stringsAsFactors=FALSE)
cb$반품여부 <- factor(cb$반품여부)

set.seed(1)
inTrain <- createDataPartition(y=cb$반품여부, p=0.6, list=FALSE)
cb.train <- cb[inTrain,]
cb.test <- cb[-inTrain,]

# 모델링
# mtry : Number of variables randomly sampled as candidates at each split.
# ntree : Number of trees to grow.

set.seed(123)
rf_model <- randomForest(반품여부 ~ .-ID, data=cb.train, ntree=50, mtry=2)

rf_model     # OOB estimate : out-of-bag 샘플을 사용하여 검증
## 
## Call:
##  randomForest(formula = 반품여부 ~ . - ID, data = cb.train, ntree = 50,      mtry = 2) 
##                Type of random forest: classification
##                      Number of trees: 50
## No. of variables tried at each split: 2
## 
##         OOB estimate of  error rate: 9.3%
## Confusion matrix:
##     0  1 class.error
## 0 193 14  0.06763285
## 1  14 80  0.14893617
plot(rf_model, main="random Forest model")
legend("topright", c("worst","overall","best"), fill = c("green", "black", "red"))

# 변수의 중요도
importance(rf_model)
##          MeanDecreaseGini
## 성별             7.648143
## 나이            65.864872
## 구매금액        17.421254
## 출연자          18.225289
varImpPlot(rf_model)

cb.test$rf_pred <- predict(rf_model, cb.test, type="response")
confusionMatrix(cb.test$rf_pred, cb.test$반품여부)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1
##          0 125  11
##          1  12  51
##                                           
##                Accuracy : 0.8844          
##                  95% CI : (0.8316, 0.9253)
##     No Information Rate : 0.6884          
##     P-Value [Acc > NIR] : 7.026e-11       
##                                           
##                   Kappa : 0.7318          
##  Mcnemar's Test P-Value : 1               
##                                           
##             Sensitivity : 0.9124          
##             Specificity : 0.8226          
##          Pos Pred Value : 0.9191          
##          Neg Pred Value : 0.8095          
##              Prevalence : 0.6884          
##          Detection Rate : 0.6281          
##    Detection Prevalence : 0.6834          
##       Balanced Accuracy : 0.8675          
##                                           
##        'Positive' Class : 0               
## 
cb.test$rf_pred_prob <- predict(rf_model, cb.test, type="prob")
rf_pred <- prediction(cb.test$rf_pred_prob[,2],cb.test$반품여부)

rf_model.perf1 <- performance(rf_pred, "tpr", "fpr") 
plot(rf_model.perf1, colorize=TRUE); abline(a=0, b=1, lty=3)  # ROC-chart

rf_model.perf2 <- performance(rf_pred, "lift", "rpp") 
plot(rf_model.perf2, colorize=TRUE); abline(v=0.4, lty=3)     # Lift chart

performance(rf_pred, "auc")@y.values[[1]] 
## [1] 0.9574405


2. Support Vector Machine (SVM)
참고자료1
참고자료2

- 두 카테고리 중 어느 하나에 속한 데이터의 집합이 주어졌을 때, SVM 알고리즘은 주어진 데이터 집합을 바탕으로 새로운 데이터가 어느 카테고리에 속할지 판단하는 비확률적 이진 선형 분류모델을 만든다.
- 만들어진 분류모델은 데이터가 사상된 공간에서 경계로 표현되는데 SVM 알고리즘은 그 중 가장 큰 폭을 가진 경계를 찾는 알고리즘이다.
- SVM은 선형분류와 더불어 비선형 분류에서도 사용될 수 있다.
- 비선형분류를 하기 위해서 주어진 데이터를 고차원 특징 공간으로 사상하는 작업이 필요한데, 이를 효율적으로 하기 위해 '커널트릭'을 사용하기도 한다.
- Support Vector = 의사결정 경계에서 가장 가까운 데이터.

SVM의 특징
- 기존의 지도학습 모형과 같이 예측 부분에서 활용될 수 있으며 기계학습 부분에서 다른 모델에 비해 예측률이 높다고 알려져 있다.
- 넓은 형태의 데이터셋(많은 예측변수를 가지고 있는)에 적합하다.
- 모델을 생성할 때는 기본적인 설정사항을 이용해 비교적 빨리 모형을 생성할 수 있다.
- 실제 응용에 있어서 인공신경망보다 높은 성과를 내고 명백한 이론적 근거에 기반하므로 결과해석이 상대적으로 용이하다.
library(e1071)

# svm 주요 옵션
# cost : Complexity parameter (C). 
# gamma : gamma parameter. 커질수록 가우시안 커브가 좁아진다. 즉, 튀어나온 봉우리들이 많아진다.
# probability : 확률적 예측 허용.

svm_model <- svm(반품여부~성별+나이+구매금액+출연자, data=cb.train, cost=100, gamma=1, probability = TRUE)
summary(svm_model)
## 
## Call:
## svm(formula = 반품여부 ~ 성별 + 나이 + 구매금액 + 출연자, data = cb.train, 
##     cost = 100, gamma = 1, probability = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  radial 
##        cost:  100 
##       gamma:  1 
## 
## Number of Support Vectors:  77
## 
##  ( 45 32 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  0 1
plot(svm_model, data=cb.train, 구매금액~나이)
legend(50, 1.7, "x : support vector")

# + : support vector
plot(cmdscale(dist(cb.train[,2:5])), col=cb.train$반품여부, pch=c("o","+")[1:nrow(cb.train) %in% svm_model$index+1])

cb.test$svm_pred <- predict(svm_model, cb.test)
confusionMatrix(cb.test$rf_pred, cb.test$반품여부)
## Confusion Matrix and Statistics
## 
##           Reference
## Prediction   0   1
##          0 125  11
##          1  12  51
##                                           
##                Accuracy : 0.8844          
##                  95% CI : (0.8316, 0.9253)
##     No Information Rate : 0.6884          
##     P-Value [Acc > NIR] : 7.026e-11       
##                                           
##                   Kappa : 0.7318          
##  Mcnemar's Test P-Value : 1               
##                                           
##             Sensitivity : 0.9124          
##             Specificity : 0.8226          
##          Pos Pred Value : 0.9191          
##          Neg Pred Value : 0.8095          
##              Prevalence : 0.6884          
##          Detection Rate : 0.6281          
##    Detection Prevalence : 0.6834          
##       Balanced Accuracy : 0.8675          
##                                           
##        'Positive' Class : 0               
## 
postResample(cb.test$svm_pred, cb.test$반품여부)
##  Accuracy     Kappa 
## 0.8844221 0.7293798
cb.test$svm_pred_prob <- attr(predict(svm_model, cb.test, probability = TRUE), "probabilities")[,2] # 1이 될 확률

svm_pred <- prediction(cb.test$svm_pred_prob, cb.test$반품여부)

svm_model.perf1 <- performance(svm_pred, "tpr", "fpr") # ROC-chart
plot(svm_model.perf1, colorize=TRUE); abline(a=0, b=1, lty=3)

svm_model.perf2 <- performance(svm_pred, "lift", "rpp") 
plot(svm_model.perf2, colorize=TRUE); abline(v=0.4, lty=3)

performance(svm_pred, "auc")@y.values[[1]]
## [1] 0.9210031
# the best values to use for the parameters gamma and cost
set.seed(123)
tune.svm(반품여부~성별+나이+구매금액+출연자, data=cb.train, gamma=seq(.5, .9, by=.1), cost=seq(100,1000, by=100))
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  gamma cost
##    0.9  300
## 
## - best performance: 0.1062366


3. K-fold Cross Validation
Data Analytics with Python & R
# Create a 5-fold partition using the caret package
set.seed(1)
flds <- createFolds(cb$반품여부, k=5, list=TRUE, returnTrain=FALSE)
str(flds)
## List of 5
##  $ Fold1: int [1:99] 5 7 12 14 18 19 21 25 30 32 ...
##  $ Fold2: int [1:101] 11 33 39 41 45 80 85 86 90 94 ...
##  $ Fold3: int [1:100] 10 15 16 22 24 31 34 35 36 48 ...
##  $ Fold4: int [1:100] 2 3 4 8 9 13 20 23 26 29 ...
##  $ Fold5: int [1:100] 1 6 17 27 28 43 46 47 53 54 ...
# Perform 5 experiments
experiment <- function(train, test, m) {
  rf <- randomForest(반품여부 ~ .-ID, data=train, ntree=50)
  rf_pred <- predict(rf, test, type="response")
  m$acc = c(m$acc, confusionMatrix(rf_pred, test$반품여부)$overall[1])   # 정확도
  rf_pred_prob <- predict(rf, test, type="prob")
  rf_pred <- prediction(rf_pred_prob[,2], cb.test$반품여부)    # 예측
  m$auc = c(m$auc, performance(rf_pred, "auc")@y.values[[1]])  # AUC
  return(m) 
}

measure = list()
for(i in 1:5){
  inTest <- flds[[i]]
  cb.test <- cb[inTest, ]
  cb.train <- cb[-inTest, ]
  measure = experiment(cb.train, cb.test, measure) 
}

measure 
## $acc
##  Accuracy  Accuracy  Accuracy  Accuracy  Accuracy 
## 0.8888889 0.8712871 0.9200000 0.9100000 0.9000000 
## 
## $auc
## [1] 0.9656072 0.9585598 0.9630669 0.9614306 0.9794296
mean(measure$acc); sd(measure$acc)
## [1] 0.8980352
## [1] 0.0188983
mean(measure$auc); sd(measure$auc)
## [1] 0.9656188
## [1] 0.008133616