반응형
k-nn을 german credit data 에 적용하고 다음과 같은 내용을 수행해본다.
1. 여러 가지 k 값에 대하여 실험 적으로 분류를 실행하고 accuracy 가 최대가 되는 k 값을 선택한다.
2. cross validation을 이용하고 cross validation의 결과를 평균한다.
3. 막대 그래프를 그려서 시각화 시킨다.
German Credit Data의 RESPONSE를 factor로 변경하여 RESPONSE에 대한 k-nn을 구하고자 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | rm(list=ls()) library('caret') df <- read.csv('C:/Users/kkw56/Documents/R/GermanCredit.csv', header = TRUE, stringsAsFactors = FALSE, na.strings="") tmp <- factor() for(i in 1:length(df$RESPONSE)){ if(df$RESPONSE[i] == 1){ tmp <- c(tmp, "YES") } else{ tmp <- c(tmp, "NO") } } df$RESPONSE <- as.factor(tmp) head(df) | cs |
5개의 집단으로 나누고(createFolds 이용) 그리고 k는 1~31의 값을 이용한다.(홀수만)
1 2 3 4 5 6 7 8 9 10 | k.fold <- 5 folds <- createFolds(df$RESPONSE, k = k.fold) folds kk.seq = seq(1, 31, by = 2) names(kk.seq) <- sapply(kk.seq, function(kk){ paste("k = ", kk) }) | cs |
xval.result에 5번의 cross validation한 값의 정확도가 저장되고
kk.Result에는 1~31개의 k값을 이용하여 k에 대한 평균 값들이 저장된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | kk.result <- sapply(kk.seq, function(kk){ xval.result <- sapply(folds, function(idx){ df.train.i <- df[-idx, ] df.test.i <- df[idx, ] model.i <- knn3(RESPONSE ~., data = df.train.i, k = kk) predict.i <- predict(model.i, df.test.i, type ="class") accuracy.i <- sum(predict.i == df.test.i$RESPONSE) / length(predict.i) return(accuracy.i) }) print(xval.result) return(mean(xval.result)) }) print(kk.result) | cs |
이때 위의 Fold1 ~ Fold5가 여러번 나오는 것의 의미는
k = 1일때 Fold의 5번의 Cross Validation 값,
k = 3일때 Fold의 5번의 Cross Validation 값,
... k = 31일때 Fold의 5번의 Cross Validation 값이다.
K에 대한 값을 그래프로 나타내고 최적의 k는 27임을 파악 할 수 있다.
1 2 3 4 5 6 | plot.data = data.frame(k = kk.seq, Accuracy = kk.result) plot(formula = Accuracy ~ k, data = plot.data, type="o", pch = 20, main = "validation - optimal k") with(plot.data, text(Accuracy ~ k, labels = plot.data$k, pos = 1, cex = 0.7)) min(plot.data[plot.data$Accuracy %in% max(plot.data$Accuracy), "k"]) | cs |
이 과정에서 k 는 무조건 27이 최적이 아닐 수 있다.
createFold에 의해 집단이 나눠지고, training set, test set이 달라질 때 마다 최적의 k 값이 변경될 수 있음을 유의하자.
전체 코드는 다음과 같다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | rm(list=ls()) library('caret') df <- read.csv('C:/Users/kkw56/Documents/R/GermanCredit.csv', header = TRUE, stringsAsFactors = FALSE, na.strings="") tmp <- factor() for(i in 1:length(df$RESPONSE)){ if(df$RESPONSE[i] == 1){ tmp <- c(tmp, "YES") } else{ tmp <- c(tmp, "NO") } } df$RESPONSE <- as.factor(tmp) head(df) k.fold <- 5 folds <- createFolds(df$RESPONSE, k = k.fold) folds kk.seq = seq(1, 31, by = 2) names(kk.seq) <- sapply(kk.seq, function(kk){ paste("k = ", kk) }) kk.result <- sapply(kk.seq, function(kk){ xval.result <- sapply(folds, function(idx){ df.train.i <- df[-idx, ] df.test.i <- df[idx, ] model.i <- knn3(RESPONSE ~., data = df.train.i, k = kk) predict.i <- predict(model.i, df.test.i, type ="class") accuracy.i <- sum(predict.i == df.test.i$RESPONSE) / length(predict.i) return(accuracy.i) }) print(xval.result) return(mean(xval.result)) }) print(kk.result) plot.data = data.frame(k = kk.seq, Accuracy = kk.result) plot(formula = Accuracy ~ k, data = plot.data, type="o", pch = 20, main = "validation - optimal k") with(plot.data, text(Accuracy ~ k, labels = plot.data$k, pos = 1, cex = 0.7)) min(plot.data[plot.data$Accuracy %in% max(plot.data$Accuracy), "k"]) | cs |
반응형
'Basic > R' 카테고리의 다른 글
R언어 Random Forest (0) | 2018.06.27 |
---|---|
의사 결정 트리(Decision Tree), 프루닝(Pruning) (0) | 2018.06.20 |
R언어 의사 결정 트리 및 다양한 개념 (0) | 2018.06.19 |
R언어 데이터 프레임 몇가지 예제 (0) | 2018.05.26 |
R언어 예제를 통한 몇가지 정리 (0) | 2018.05.25 |