성능 평가
가족 정보를 사용한 모델의 성능을 알아보자. 이 모델을 위해 설명한 내용이 길어 이해를 도우려고 전체 코드를 보였다.
family_result <- foreach(f=folds) %do% { f$train$type <- "T" f$validation$type <- "V" all <- rbind(f$train, f$validation) ctree_model <- ctree( survived ~ pclass + sex + age + sibsp + parch + fare + embarked, data=f$train) all$prob <- sapply(predict(ctree_model, type="prob", newdata=all), function(result) { result[1] }) # 티켓 번호를 사용한 family_id family_idx <- 0 ticket_based_family_id <- ddply(all, .(ticket), function(rows) { family_idx <<- family_idx + 1 return(data.frame(family_id=paste0("TICKET_", family_idx))) }) all <- adply(all, 1, function(row) { family_id <- NA if (!is.na(row$ticket)) { family_id <- subset(ticket_based_family_id, ticket == row$ticket)$family_id } return(data.frame(family_id=family_id)) }) # avg_prob all <- ddply(all, .(family_id), function(rows) { rows$avg_prob <- mean(rows$prob) return(rows) }) # maybe_parent, may_be_child all <- ddply(all, .(family_id), function(rows) { rows$maybe_parent <- FALSE rows$maybe_child <- FALSE if (NROW(rows) == 1 || sum(rows$parch) == 0 || NROW(rows) == sum(is.na(rows$age))) { return(rows) } max_age <- max(rows$age, na.rm=TRUE) min_age <- min(rows$age, na.rm=TRUE) return(adply(rows, 1, function(row) { if (!is.na(row$age) && !is.na(row$sex)) { row$maybe_parent <- (max_age - row$age) < 10 row$maybe_child <- (row$age - min_age) < 10 } return(row) })) }) # avg_parent_prob, avg_child_prob all <- ddply(all, .(family_id), function(rows) { rows$avg_parent_prob <- rows$avg_prob rows$avg_child_prob <- rows$avg_prob if (NROW(rows) == 1 || sum(rows$parch) == 0) { return(rows) } parent_prob <- subset(rows, maybe_parent == TRUE)[, "prob"] if (NROW(parent_prob) > 0) { rows$avg_parent_prob <- mean(parent_prob) } child_prob <- c(subset(rows, maybe_child == TRUE)[, "prob"]) if (NROW(child_prob) > 0) { rows$avg_child_prob <- mean(child_prob) } return(rows) }) # ctree 모델 f$train <- subset(all, type == "T") f$validation <- subset(all, type == "V") (m <- ctree(survived ~ pclass + sex + age + sibsp + parch + fare + embarked + maybe_parent + maybe_child + age + sex + avg_prob + avg_parent_prob + avg_child_prob, data=f$train)) print(m) predicted <- predict(m, newdata=f$validation) return(list(actual=f$validation$survived, predicted=predicted)) }
성능 평가 결과는 다음과 같다.
> family_accuracy <- evaluation(family_result)
[1] "MEAN +/- SD: 0.815 +/- 0.028"
ctree( )만 사용한 이전 모델의 경우 성능이 0.812 +/- 0.030이었으므로, 가족 정보를 사용해 정확도의 평균이 개선되었고 표준 편차가 줄어들어 서로 다른 데이터에 대해서도 성능이 좀 더 일관적으로 나옴을 알 수 있다.
이제 최종적으로 11.2.2절에서 분리해둔 테스트 데이터에 세 가지 알고리즘(rpart, ctree, family_id를 사용한 모델)을 적용해서 결과를 비교해볼 차례다. 이 부분은 독자의 연습 문제로 남겨둔다.