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 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | ######### 분석과제! rm(list=ls()) ### setwd Sys.setlocale(category = "LC_CTYPE", locale = "ko_KR.UTF-8") rm(list=ls()) getwd() setwd("/Users/sungjinpark/Desktop/투빅스/week2/knnlda") ### packages if(!require(caret)) install.packages("caret"); library(caret) if(!require(e1071)) install.packages("e1071"); library(e1071) if(!require(dplyr)) install.packages("dplyr"); library(dplyr) if(!require(data.table)) install.packages("data.table"); library(data.table) if(!require(readr)) install.packages("readr"); library(readr) # MAC 기준 csv 읽을때, 한글 깨짐 방지 read.any <- function(text, sep = "", ...) { encoding <- as.character(guess_encoding(text)[1,1]) setting <- as.character(tools::file_ext(text)) if(sep != "" | !(setting %in% c("csv", "txt")) ) setting <- "custom" separate <- list(csv = ",", txt = "\n", custom = sep) result <- read.table(text, sep = separate[[setting]], fileEncoding = encoding, ...) return(result) } #### load data pro.train <- fread('profiles_train.csv') pro.train <- as.data.frame(pro.train) pro.test <- fread('profiles_test.csv') pro.test <- as.data.frame(pro.test) click.train <- read.any('click_train.csv',header=TRUE) click.train <- as.data.frame(click.train) click.test <- read.any('click_test.csv',header=TRUE) click.test <- as.data.frame(click.test) ### 변수추가 1. DT # st_t 총합 = 총 체류시간 a <-click.train %>% group_by(id) %>% summarise(DT = sum(st_t)) # or aggregate pro.train <- inner_join(pro.train,a) # or merge pro.train %>% head ### 변수추가 2. PV # st_c 총합 = 총 페이지 뷰 b <- click.train %>% group_by(id) %>% summarise(PV = sum(st_c)) pro.train <- inner_join(pro.train,b) head(pro.train) ### 변수추가 3. COV # 얼마나 다양한 cate 접속했나 알아보는것 . # 서로 다른 cate 갯수 / 22개 c <- click.train %>% group_by(id) %>% summarise(COV = round(length(unique(cate))/22,2)) pro.train <- inner_join(pro.train,c) pro.train %>% head ### 변수추가 4. Day # 총 접속일수 click.train$time <- as.character(click.train$time) d <- click.train %>% group_by(id) %>% summarise(Day = length(unique(substr(time,1,8)))) pro.train <- inner_join(pro.train,d) pro.train %>% head # 같은 변수 추가를 pro.test 에도 해준다 a_1 <-click.test %>% group_by(id) %>% summarise(DT = sum(st_t)) # or aggregate pro.test <- inner_join(pro.test,a_1) # or merge b_1 <- click.test %>% group_by(id) %>% summarise(PV = sum(st_c)) pro.test <- inner_join(pro.test,b_1) c_1 <- click.test %>% group_by(id) %>% summarise(COV = round(length(unique(cate))/22,2)) pro.test <- inner_join(pro.test,c_1) click.test$time <- as.character(click.test$time) d_1 <- click.test %>% group_by(id) %>% summarise(Day = length(unique(substr(time,1,8)))) pro.test <- inner_join(pro.test,d_1) pro.test %>% head #### data partition str(pro.train) # 종속변수(y) 분포 확인 table(pro.train$gen) prop.table(table(pro.train$gen)) # 남자 여자 # 255 147 # 남자 여자 # 0.6343284 0.3656716 # factor 처리 pro.train$gen <- factor(pro.train$gen, level=c("남자","여자")) pro.train$job <-as.factor(pro.train$job) pro.train$resid <-as.factor(pro.train$resid) # set.seed(1) : 난수 고정 set.seed(1) ######### 분석과제 안에 들어있는 구현 # 순서대로 KNN ,WKNN, LDA, Logistic Regression # pro.train 데이터를 pro_train/pro_test로 나눈다 # 즉, pro.test 데이터는 사용하지 않고 남겨둔다. ######### cross validation #cross validation은 하이퍼 파라미터 개념이 아님! # cross validation을 한번만 할것인가(cv) # cross validation을 n번 반복해서 할 것인가(repcv)의 차이! # 당연히 n번 반복해서 할 때 데이터를 어떻게 분할 하냐에 따라서 결과값이 다르게 나옴. # 따라서 어떤 모델, 파라미터가 더 나은지 확인하기 위해선 같은 cv, repcv를 해준 상태에서 비교를 해야함 cv <- trainControl(method = "cv", number = 5, verbose = T) repCv <- trainControl(method = "repeatedcv", number = 5,repeats = 3, verbose = T) # createDataPartition # caret패키지 안에 있는 데이터 파티션, 층화추출 idx <- createDataPartition(y = pro.train$gen, p = 0.7, list =FALSE) pro_train <- pro.train[idx,] pro_test <- pro.train[-idx,] str(pro_train) str(pro_test) ######### knn Accuracy : 0.6417 #### tune parameter Sensitivity : 1.00000 # Specificity : 0.02273 knn.grid = expand.grid( .k = c(19) # k값 조정 ) train.knn <- train(gen~.,pro_train, method = "knn",trControl = repCv, tuneGrid = knn.grid) train.knn$results train.knn$bestTune # k # 10 19 predict.knn <- predict(train.knn,pro_test) confusionMatrix(predict.knn, pro_test$gen) ######### wknn Accuracy : 0.6167 #### tune parameter Sensitivity : 0.7763 # Specificity : 0.3409 # best tune #kmax distance kernel #20 19 2 optimal # kmax = 근접값 # distance = 1 -> 맨하탄 # distance = 2 -> 유클리디안 wknn.grid = expand.grid( .kmax = c(1,3,5,7,9,11,13,15,17,19), .distance = c(1,2), .kernel = "optimal" ) # Fitting kmax = 19, distance = 2, kernel = optimal on full training set train.wknn <- train(gen~.,pro_train, method = "kknn", trControl = cv, tuneGrid = wknn.grid) train.wknn$results train.wknn$bestTune # kmax distance kernel # 19 2 optimal predict.wknn <- predict(train.wknn,pro_test) confusionMatrix(predict.wknn, pro_test$gen) ######### lda Accuracy : 0.6167 # Sensitivity : 0.6842 # Specificity : 0.5000 train.lda <- train(gen~.,pro_train, method = "lda", trControl = repCv) predict.lda <- predict(train.lda,pro_test) confusionMatrix(predict.lda, pro_test$gen) ######### logistic Accuracy : 0.6083 # Sensitivity : 0.6974 # Specificity : 0.4545 train.glm <- train(gen~.,pro_train, method = "glm", trControl =repCv) predict.glm <- predict(train.glm,pro_test) confusionMatrix(predict.glm, pro_test$gen) ##################################################### # knn 경우 특이도, 민감도 밸런스가 많이 안좋아서 뺸다. # wknn, lda, glm을 사용하겠다. voteClassifier <- function(a,b,c) { #wknn을 위한 변수 wknn.grid = expand.grid( .kmax = c(19), .distance = c(2), .kernel = "optimal" ) train.wknn_1 <- train(gen~.,pro.train, method = a, trControl = cv, tuneGrid = wknn.grid) train.lda_1 <- train(gen~.,pro.train, method = b, trControl = repCv) train.glm_1 <- train(gen~.,pro.train, method = c, trControl =cv) # 예측 부분 predict.wknn_1 <- predict(train.wknn_1,pro.test) predict.lda_1 <- predict(train.lda_1,pro.test) predict.glm_1 <- predict(train.glm,pro.test) # predict count 부분 calculator_wknn <-c() for (i in predict.wknn_1) { if ( i =='남자'){ calculator_wknn <-c(calculator_wknn,1) } else{ calculator_wknn <-c(calculator_wknn,0) } } calculator_lda <-c() for (i in predict.lda_1) { if ( i =='남자'){ calculator_lda <-c(calculator_lda,1) } else{ calculator_lda <-c(calculator_lda,0) } } calculator_glm <-c() for ( i in predict.glm_1) { if (i =='남자'){ calculator_glm <-c(calculator_glm,1) } else { calculator_glm <-c(calculator_glm,0) } } result = calculator_wknn + calculator_lda + calculator_glm result_vec <-c() for (i in result) { if (i == 2 | i == 3) { result_vec <-c(result_vec,"남자") } else { result_vec <-c(result_vec,"여자") } } return(result_vec) } voteClassifier('kknn','lda','glm') # Fitting final model on full training set # [1] "여자" "남자" "남자" "여자" "여자" "여자" "남자" "남자" # [9] "여자" "여자" "남자" "남자" "남자" "남자" "남자" "여자" # [17] "여자" "남자" "남자" "여자" "여자" "남자" "여자" "남자" # [25] "여자" "남자" "남자" "남자" "남자" "남자" "남자" "남자" # [33] "남자" "여자" "남자" "여자" "여자" "남자" "남자" "남자" # [41] "여자" "여자" "남자" "남자" "남자" "남자" "남자" "남자" # [49] "여자" "여자" "남자" "남자" "남자" "남자" "남자" "남자" # [57] "남자" "여자" "남자" "여자" "남자" "여자" "남자" "남자" # [65] "남자" "남자" "여자" "남자" "여자" "여자" "남자" "여자" # [73] "남자" "남자" "남자" "남자" "남자" "남자" "남자" "여자" # [81] "남자" "여자" "남자" "남자" "여자" "남자" "남자" "여자" # [89] "여자" "남자" "남자" "남자" "남자" "남자" "여자" "남자" # [97] "남자" "남자" "남자" ######### 일반화 vote classifier_general #voteClassifier_general (a : formula (y~x), #b : Dependent variable, 종속변수 #c : train data, 학습 데이터 #d : test data, 예측 데이터 #e : method, 학습할 모델들! #f : cv option, trControl 옵션! #g : majority option, method가 짝수개인 경우 절반값을 예측한 경우 어디로 부여할지를 결정 # ex) ("knn","lda","qda","glm")과 같이 짝수로 모델이 들어오고 # 여 남 남 여와 같이 예측한 경우 # TRUE로 지정하면 factor의 첫번째 levels로 (남) # FALSE로 지정하면 factor의 두번째 levels로 (여) # 주어진 데이터에서 여성의 비율이 더 낮기 때문에 동일하게 예측한 경우 여성으로 분류하도록 default를 FALSE로 조정 voteClassifier_general <- function(a,b,c,d,e,f,g = FALSE) { # 학습 부분 for (i in 1:length(e)) { assign(paste("train.",i,sep=""),train(a,c, method = e[i], trControl = f)) } # 예측 부분 for (i in 1:length(e)) { assign(paste("predict.",i,sep=""),predict.train(get(paste("train.",i,sep="")),d)) } # predict count 부분 predict.all <- data.frame(rep(0,nrow(d))) for (i in 1:length(e)) { predict.all[,i] <- get(paste("predict.",i,sep="")) } b <- as.factor(b) if (g == TRUE) { vote.predict <- ifelse(rowSums(predict.all == levels(b)[1]) >= length(e)/2,levels(b)[1],levels(b)[2]) } else { vote.predict <- ifelse(rowSums(predict.all == levels(b)[1]) > length(e)/2,levels(b)[1],levels(b)[2]) } vote.predict <- as.factor(vote.predict) # 최종 결과물 반환 return(vote.predict) } # ex a <- gen~DT+PV+COV+Day b <- pro.train$gen c <- pro.train d <- pro.test[-1] e <- c("knn","kknn","glm","lda","qda") f <- trainControl(method = "cv", number = 5, verbose = T) voteClassifier_general(a,b,c,d,e,f,FALSE) # Fitting final model on full training set # [1] 남자 남자 남자 남자 남자 여자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 # [19] 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 # [37] 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 여자 남자 남자 남자 남자 남자 # [55] 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 # [73] 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 남자 # [91] 남자 남자 남자 남자 남자 여자 남자 남자 남자 # Levels: 남자 여자 | cs |
cs |
Designed by sketchbooks.co.kr / sketchbook5 board skin
Sketchbook5, 스케치북5
Sketchbook5, 스케치북5
Sketchbook5, 스케치북5
Sketchbook5, 스케치북5