big_contest_final
Yang_Kwon_Cho_Lim
2019-09-09
라이브러리 설치
library(tidyverse)
## ── Attaching packages ───────────────────
## ✔ ggplot2 3.1.0 ✔ purrr 0.3.1
## ✔ tibble 2.0.1 ✔ dplyr 0.8.0.1
## ✔ tidyr 0.8.3 ✔ stringr 1.4.0
## ✔ readr 1.3.1 ✔ forcats 0.4.0
## ── Conflicts ─── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
library(randomForest)
## randomForest 4.6-14
## Type rfNews() to see new features/changes/bug fixes.
##
## Attaching package: 'randomForest'
## The following object is masked from 'package:dplyr':
##
## combine
## The following object is masked from 'package:ggplot2':
##
## margin
library(MLmetrics)
##
## Attaching package: 'MLmetrics'
## The following object is masked from 'package:base':
##
## Recall
library(caret)
## Loading required package: lattice
##
## Attaching package: 'caret'
## The following objects are masked from 'package:MLmetrics':
##
## MAE, RMSE
## The following object is masked from 'package:purrr':
##
## lift
library(dplyr)
library(ROCR)
## Loading required package: gplots
##
## Attaching package: 'gplots'
## The following object is masked from 'package:stats':
##
## lowess
library(pROC)
## Type 'citation("pROC")' for a citation.
##
## Attaching package: 'pROC'
## The following objects are masked from 'package:stats':
##
## cov, smooth, var
library(plyr)
## -------------------------------------------------------------------------
## You have loaded plyr after dplyr - this is likely to cause problems.
## If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
## library(plyr); library(dplyr)
## -------------------------------------------------------------------------
##
## Attaching package: 'plyr'
## The following objects are masked from 'package:dplyr':
##
## arrange, count, desc, failwith, id, mutate, rename, summarise,
## summarize
## The following object is masked from 'package:purrr':
##
## compact
데이터 불러오기(afsnt, afsnt_dly)
afsnt <- read.csv("AFSNT.csv", header = TRUE, fileEncoding = 'euc-kr')
afsnt_dly <- read.csv("AFSNT_DLY.csv", header = TRUE, fileEncoding = 'euc-kr')
afsnt_dly[3, 5] <- 'ARP1'
head(afsnt)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP ODP FLO FLT REG AOD IRR STT
## 1 2017 1 1 일 ARP1 ARP3 A A1901 SEw3Nzc2 D N 6:10
## 2 2017 1 1 일 ARP1 ARP3 A A1905 SEw4MjM2 D N 6:15
## 3 2017 1 1 일 ARP1 ARP3 L L1751 SEw4MjM3 D N 6:20
## 4 2017 1 1 일 ARP1 ARP3 F F1201 SEw4MjA3 D N 6:25
## 5 2017 1 1 일 ARP3 ARP1 A A1900 SEw3NzAz D N 6:30
## 6 2017 1 1 일 ARP1 ARP3 H H1101 SEw4MDMx D N 6:30
## ATT DLY DRR CNL CNR
## 1 6:18 N N
## 2 6:25 N N
## 3 6:30 N N
## 4 6:34 N N
## 5 6:37 N N
## 6 6:38 N N
head(afsnt_dly)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP ODP FLO FLT AOD STT DLY DLY_RATE
## 1 2019 9 16 월 ARP1 ARP3 L L1702 A 9:05 NA NA
## 2 2019 9 16 월 ARP3 ARP1 L L1702 D 7:55 NA NA
## 3 2019 9 16 월 ARP1 ARP3 L L1720 A 14:40 NA NA
## 4 2019 9 16 월 ARP3 ARP1 L L1720 D 13:30 NA NA
## 5 2019 9 16 월 ARP4 ARP3 L L1808 A 20:10 NA NA
## 6 2019 9 16 월 ARP3 ARP4 L L1808 D 19:10 NA NA
결항편 삭제하기
afsnt <- afsnt %>% dplyr::filter(CNL == "N")
head(afsnt)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP ODP FLO FLT REG AOD IRR STT
## 1 2017 1 1 일 ARP1 ARP3 A A1901 SEw3Nzc2 D N 6:10
## 2 2017 1 1 일 ARP1 ARP3 A A1905 SEw4MjM2 D N 6:15
## 3 2017 1 1 일 ARP1 ARP3 L L1751 SEw4MjM3 D N 6:20
## 4 2017 1 1 일 ARP1 ARP3 F F1201 SEw4MjA3 D N 6:25
## 5 2017 1 1 일 ARP3 ARP1 A A1900 SEw3NzAz D N 6:30
## 6 2017 1 1 일 ARP1 ARP3 H H1101 SEw4MDMx D N 6:30
## ATT DLY DRR CNL CNR
## 1 6:18 N N
## 2 6:25 N N
## 3 6:30 N N
## 4 6:34 N N
## 5 6:37 N N
## 6 6:38 N N
연, 월, 일 데이터 범주형으로 바꾸기
afsnt$SDT_YY <- as.factor(afsnt$SDT_YY)
afsnt$SDT_MM <- as.factor(afsnt$SDT_MM)
afsnt$SDT_DD <- as.factor(afsnt$SDT_DD)
head(afsnt)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP ODP FLO FLT REG AOD IRR STT
## 1 2017 1 1 일 ARP1 ARP3 A A1901 SEw3Nzc2 D N 6:10
## 2 2017 1 1 일 ARP1 ARP3 A A1905 SEw4MjM2 D N 6:15
## 3 2017 1 1 일 ARP1 ARP3 L L1751 SEw4MjM3 D N 6:20
## 4 2017 1 1 일 ARP1 ARP3 F F1201 SEw4MjA3 D N 6:25
## 5 2017 1 1 일 ARP3 ARP1 A A1900 SEw3NzAz D N 6:30
## 6 2017 1 1 일 ARP1 ARP3 H H1101 SEw4MDMx D N 6:30
## ATT DLY DRR CNL CNR
## 1 6:18 N N
## 2 6:25 N N
## 3 6:30 N N
## 4 6:34 N N
## 5 6:37 N N
## 6 6:38 N N
시간대별 편 수 계산
afsnt$STT <- as.character(afsnt$STT)
b <- sapply(afsnt[, "STT"], function(x) {x %>% str_split(pattern = ':') %>% `[[`(1) })
HOUR <- b[1, ] %>% as.numeric()
afsnt$HOUR <- HOUR
afsnt$HOUR <- as.factor(afsnt$HOUR)
afsnt_count <- afsnt %>%
dplyr::group_by(SDT_YY, SDT_MM, SDT_DD, ARP, HOUR) %>%
dplyr::summarise('count' = n())
afsnt <- left_join(afsnt, afsnt_count, by = c("SDT_YY", "SDT_MM", "SDT_DD", "ARP", "HOUR"))
head(afsnt)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP ODP FLO FLT REG AOD IRR STT
## 1 2017 1 1 일 ARP1 ARP3 A A1901 SEw3Nzc2 D N 6:10
## 2 2017 1 1 일 ARP1 ARP3 A A1905 SEw4MjM2 D N 6:15
## 3 2017 1 1 일 ARP1 ARP3 L L1751 SEw4MjM3 D N 6:20
## 4 2017 1 1 일 ARP1 ARP3 F F1201 SEw4MjA3 D N 6:25
## 5 2017 1 1 일 ARP3 ARP1 A A1900 SEw3NzAz D N 6:30
## 6 2017 1 1 일 ARP1 ARP3 H H1101 SEw4MDMx D N 6:30
## ATT DLY DRR CNL CNR HOUR count
## 1 6:18 N N 6 10
## 2 6:25 N N 6 10
## 3 6:30 N N 6 10
## 4 6:34 N N 6 10
## 5 6:37 N N 6 2
## 6 6:38 N N 6 10
시간 변수로 바꾸기
afsnt$STT <- strptime(as.character(afsnt$STT), format = "%H:%M")
afsnt$ATT <- strptime(as.character(afsnt$ATT), format = "%H:%M")
head(afsnt)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP ODP FLO FLT REG AOD IRR
## 1 2017 1 1 일 ARP1 ARP3 A A1901 SEw3Nzc2 D N
## 2 2017 1 1 일 ARP1 ARP3 A A1905 SEw4MjM2 D N
## 3 2017 1 1 일 ARP1 ARP3 L L1751 SEw4MjM3 D N
## 4 2017 1 1 일 ARP1 ARP3 F F1201 SEw4MjA3 D N
## 5 2017 1 1 일 ARP3 ARP1 A A1900 SEw3NzAz D N
## 6 2017 1 1 일 ARP1 ARP3 H H1101 SEw4MDMx D N
## STT ATT DLY DRR CNL CNR HOUR count
## 1 2019-09-10 06:10:00 2019-09-10 06:18:00 N N 6 10
## 2 2019-09-10 06:15:00 2019-09-10 06:25:00 N N 6 10
## 3 2019-09-10 06:20:00 2019-09-10 06:30:00 N N 6 10
## 4 2019-09-10 06:25:00 2019-09-10 06:34:00 N N 6 10
## 5 2019-09-10 06:30:00 2019-09-10 06:37:00 N N 6 2
## 6 2019-09-10 06:30:00 2019-09-10 06:38:00 N N 6 10
시간 차 변수 생성하기
afsnt$timediff <- difftime(afsnt$ATT, afsnt$STT, units = "mins")
head(afsnt)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP ODP FLO FLT REG AOD IRR
## 1 2017 1 1 일 ARP1 ARP3 A A1901 SEw3Nzc2 D N
## 2 2017 1 1 일 ARP1 ARP3 A A1905 SEw4MjM2 D N
## 3 2017 1 1 일 ARP1 ARP3 L L1751 SEw4MjM3 D N
## 4 2017 1 1 일 ARP1 ARP3 F F1201 SEw4MjA3 D N
## 5 2017 1 1 일 ARP3 ARP1 A A1900 SEw3NzAz D N
## 6 2017 1 1 일 ARP1 ARP3 H H1101 SEw4MDMx D N
## STT ATT DLY DRR CNL CNR HOUR count
## 1 2019-09-10 06:10:00 2019-09-10 06:18:00 N N 6 10
## 2 2019-09-10 06:15:00 2019-09-10 06:25:00 N N 6 10
## 3 2019-09-10 06:20:00 2019-09-10 06:30:00 N N 6 10
## 4 2019-09-10 06:25:00 2019-09-10 06:34:00 N N 6 10
## 5 2019-09-10 06:30:00 2019-09-10 06:37:00 N N 6 2
## 6 2019-09-10 06:30:00 2019-09-10 06:38:00 N N 6 10
## timediff
## 1 8 mins
## 2 10 mins
## 3 10 mins
## 4 9 mins
## 5 7 mins
## 6 8 mins
시간차 변수가 0보다 작은 것은 0으로 변환하기
afsnt <- afsnt[!is.na(afsnt$ATT), ]
afsnt[(afsnt$timediff) < 0, "timediff"] <- 0
afsnt$timediff <- as.numeric(afsnt$timediff)
head(afsnt)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP ODP FLO FLT REG AOD IRR
## 1 2017 1 1 일 ARP1 ARP3 A A1901 SEw3Nzc2 D N
## 2 2017 1 1 일 ARP1 ARP3 A A1905 SEw4MjM2 D N
## 3 2017 1 1 일 ARP1 ARP3 L L1751 SEw4MjM3 D N
## 4 2017 1 1 일 ARP1 ARP3 F F1201 SEw4MjA3 D N
## 5 2017 1 1 일 ARP3 ARP1 A A1900 SEw3NzAz D N
## 6 2017 1 1 일 ARP1 ARP3 H H1101 SEw4MDMx D N
## STT ATT DLY DRR CNL CNR HOUR count
## 1 2019-09-10 06:10:00 2019-09-10 06:18:00 N N 6 10
## 2 2019-09-10 06:15:00 2019-09-10 06:25:00 N N 6 10
## 3 2019-09-10 06:20:00 2019-09-10 06:30:00 N N 6 10
## 4 2019-09-10 06:25:00 2019-09-10 06:34:00 N N 6 10
## 5 2019-09-10 06:30:00 2019-09-10 06:37:00 N N 6 2
## 6 2019-09-10 06:30:00 2019-09-10 06:38:00 N N 6 10
## timediff
## 1 8
## 2 10
## 3 10
## 4 9
## 5 7
## 6 8
시간변수 삭제
afsnt <- afsnt[, -c(12:13)]
head(afsnt)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP ODP FLO FLT REG AOD IRR DLY DRR
## 1 2017 1 1 일 ARP1 ARP3 A A1901 SEw3Nzc2 D N N
## 2 2017 1 1 일 ARP1 ARP3 A A1905 SEw4MjM2 D N N
## 3 2017 1 1 일 ARP1 ARP3 L L1751 SEw4MjM3 D N N
## 4 2017 1 1 일 ARP1 ARP3 F F1201 SEw4MjA3 D N N
## 5 2017 1 1 일 ARP3 ARP1 A A1900 SEw3NzAz D N N
## 6 2017 1 1 일 ARP1 ARP3 H H1101 SEw4MDMx D N N
## CNL CNR HOUR count timediff
## 1 N 6 10 8
## 2 N 6 10 10
## 3 N 6 10 10
## 4 N 6 10 9
## 5 N 6 2 7
## 6 N 6 10 8
새로운 변수 만들기 (A/C 정비와 그 외의 지연코드)
afsnt$DRR.group <- ifelse(afsnt$DRR == "C02",
"C02",
"Non-C02")
afsnt$DRR.group <- as.factor(afsnt$DRR.group)
head(afsnt)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP ODP FLO FLT REG AOD IRR DLY DRR
## 1 2017 1 1 일 ARP1 ARP3 A A1901 SEw3Nzc2 D N N
## 2 2017 1 1 일 ARP1 ARP3 A A1905 SEw4MjM2 D N N
## 3 2017 1 1 일 ARP1 ARP3 L L1751 SEw4MjM3 D N N
## 4 2017 1 1 일 ARP1 ARP3 F F1201 SEw4MjA3 D N N
## 5 2017 1 1 일 ARP3 ARP1 A A1900 SEw3NzAz D N N
## 6 2017 1 1 일 ARP1 ARP3 H H1101 SEw4MDMx D N N
## CNL CNR HOUR count timediff DRR.group
## 1 N 6 10 8 Non-C02
## 2 N 6 10 10 Non-C02
## 3 N 6 10 10 Non-C02
## 4 N 6 10 9 Non-C02
## 5 N 6 2 7 Non-C02
## 6 N 6 10 8 Non-C02
편명별 C02 비율
a <- afsnt %>%
dplyr::group_by(FLT) %>%
dplyr::summarise(n = n())
b <- afsnt %>%
dplyr::filter(DRR.group == "C02") %>% dplyr::group_by(FLT) %>% dplyr::summarise(n = n())
c <- as.data.frame(left_join(a, b, by = "FLT"))
c[is.na(c)] <- 0
colnames(c) <- c("FLT", "x", "y")
c$x <- as.numeric(c$x)
c$FLT_C02_ratio <- (c$y/c$x)*100
colnames(c) <- c("FLT", "x", "y", "FLT_C02_ratio")
c <- c %>% select(-c(x,y))
head(c)
## FLT FLT_C02_ratio
## 1 A1001 2.398524
## 2 A1002 36.229508
## 3 A1003 11.299435
## 4 A1004 12.109375
## 5 A1005 11.574074
## 6 A1006 7.421875
편명별 부정기 비율
a <- afsnt %>%
dplyr::group_by(FLT) %>%
dplyr::summarise(n = n())
b <- afsnt %>%
dplyr::filter(IRR == "Y") %>% dplyr::group_by(FLT) %>% dplyr::summarise(n = n())
i <- as.data.frame(left_join(a, b, by = "FLT"))
i[is.na(i)] <- 0
colnames(i) <- c("FLT", "x", "y")
i$x <- as.numeric(i$x)
i$FLT.IRR_ratio <- (i$y/i$x)*100
colnames(i) <- c("FLT","x","y", "FLT_IRR_ratio")
i <- i %>% select(-c(x,y))
head(i)
## FLT FLT_IRR_ratio
## 1 A1001 0.000000
## 2 A1002 0.000000
## 3 A1003 6.779661
## 4 A1004 10.156250
## 5 A1005 0.000000
## 6 A1006 2.343750
편명별 평균 지연 시간
f <- afsnt %>%
dplyr::group_by(FLT) %>%
dplyr::summarise(mean(timediff, na.rm = TRUE))
colnames(f) <- c("FLT", "FLT_meantimediff")
f$FLT_meantimediff <- as.numeric(f$FLT_meantimediff)
head(f)
## # A tibble: 6 x 2
## FLT FLT_meantimediff
## <fct> <dbl>
## 1 A1001 10.3
## 2 A1002 27.9
## 3 A1003 18.3
## 4 A1004 18.6
## 5 A1005 21.3
## 6 A1006 18.4
편명별 지연율
a <- afsnt %>%
dplyr:::group_by(FLT) %>%
dplyr:::summarise(n = n())
b <- afsnt %>% dplyr:::filter(DLY == "Y") %>%
dplyr:::group_by(FLT) %>%
dplyr:::summarise(n = n())
g <- as.data.frame(left_join(a, b, by = "FLT"))
g[is.na(g)] <- 0
colnames(g) <- c("FLT", "x", "y")
g$x <- as.numeric(g$x)
g$FLT_DLY_ratio <- (g$y/g$x)*100
g <- g %>% select(-c(x,y))
colnames(g) <- c("FLT","FLT_DLY_ratio")
m <- left_join(c, i, by = "FLT")
m <- left_join(m, f, by = "FLT")
m <- left_join(m, g, by = "FLT")
afsnt <- left_join(afsnt, m, by = "FLT")
head(afsnt)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP ODP FLO FLT REG AOD IRR DLY DRR
## 1 2017 1 1 일 ARP1 ARP3 A A1901 SEw3Nzc2 D N N
## 2 2017 1 1 일 ARP1 ARP3 A A1905 SEw4MjM2 D N N
## 3 2017 1 1 일 ARP1 ARP3 L L1751 SEw4MjM3 D N N
## 4 2017 1 1 일 ARP1 ARP3 F F1201 SEw4MjA3 D N N
## 5 2017 1 1 일 ARP3 ARP1 A A1900 SEw3NzAz D N N
## 6 2017 1 1 일 ARP1 ARP3 H H1101 SEw4MDMx D N N
## CNL CNR HOUR count timediff DRR.group FLT_C02_ratio FLT_IRR_ratio
## 1 N 6 10 8 Non-C02 0.8324084 0.0000000
## 2 N 6 10 10 Non-C02 0.7168459 0.0000000
## 3 N 6 10 10 Non-C02 0.0000000 0.0000000
## 4 N 6 10 9 Non-C02 0.6365741 0.0000000
## 5 N 6 2 7 Non-C02 0.2257336 0.3386005
## 6 N 6 10 8 Non-C02 0.4540295 0.0000000
## FLT_meantimediff FLT_DLY_ratio
## 1 8.551054 2.164262
## 2 9.765233 2.508961
## 3 8.232143 2.380952
## 4 9.984954 3.298611
## 5 6.276524 1.467269
## 6 10.640182 3.064699
afsnt_dly에 변수 추가
afsnt_dly <- left_join(afsnt_dly, m, by = "FLT")
## Warning: Column `FLT` joining factors with different levels, coercing to
## character vector
afsnt_dly$FLT <- as.factor(afsnt_dly$FLT)
head(afsnt_dly)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP ODP FLO FLT AOD STT DLY DLY_RATE
## 1 2019 9 16 월 ARP1 ARP3 L L1702 A 9:05 NA NA
## 2 2019 9 16 월 ARP3 ARP1 L L1702 D 7:55 NA NA
## 3 2019 9 16 월 ARP1 ARP3 L L1720 A 14:40 NA NA
## 4 2019 9 16 월 ARP3 ARP1 L L1720 D 13:30 NA NA
## 5 2019 9 16 월 ARP4 ARP3 L L1808 A 20:10 NA NA
## 6 2019 9 16 월 ARP3 ARP4 L L1808 D 19:10 NA NA
## FLT_C02_ratio FLT_IRR_ratio FLT_meantimediff FLT_DLY_ratio
## 1 5.091312 1.8262313 12.28832 5.755396
## 2 5.091312 1.8262313 12.28832 5.755396
## 3 22.232472 0.1845018 20.32472 22.785978
## 4 22.232472 0.1845018 20.32472 22.785978
## 5 22.436604 0.2205072 21.50331 20.507166
## 6 22.436604 0.2205072 21.50331 20.507166
afsnt_dly의 편명별 비율 데이터 결측치 채우기
FLO_J <- afsnt %>%
dplyr::filter(FLO == "J") %>%
select(20:23) %>%
summarise(mean_FLT_CO2_ratio = median(FLT_C02_ratio),
mean_FLT_IRR_ratio = median(FLT_IRR_ratio),
mean_FLT_meantimediff = median(FLT_meantimediff),
mean_FLT_DLY_ratio = median(FLT_DLY_ratio))
IRR_y <- afsnt %>%
dplyr::filter(IRR == "Y")
IRR_yy <- IRR_y %>%
select(20:23) %>%
summarise(mean_FLT_CO2_ratio = median(FLT_C02_ratio),
mean_FLT_IRR_ratio = 0,
mean_FLT_meantimediff = median(FLT_meantimediff),
mean_FLT_DLY_ratio = median(FLT_DLY_ratio))
afsnt_dly[afsnt_dly$FLO == "J" & afsnt_dly$FLT_C02_ratio %>% is.na(), c(13:16)] <- FLO_J
afsnt_dly[afsnt_dly$FLO == "M", c(13:16)] <- IRR_yy
afsnt_dly 시간대별 편 수 계산
afsnt_dly$STT <- as.character(afsnt_dly$STT)
b <- sapply(afsnt_dly[, "STT"], function(x) {x %>% str_split(pattern = ':') %>% `[[`(1) })
HOUR_nd <- b[1, ] %>% as.numeric()
afsnt_dly$HOUR <- HOUR_nd
afsnt_dly$HOUR <- as.factor(afsnt_dly$HOUR)
afsnt_dly_count <- afsnt_dly %>%
dplyr::group_by(SDT_YY, SDT_MM, SDT_DD, ARP, HOUR) %>%
dplyr::summarise('count' = n())
afsnt_dly <- left_join(afsnt_dly, afsnt_dly_count, by = c("SDT_YY", "SDT_MM", "SDT_DD", "ARP", "HOUR"))
head(afsnt_dly)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP ODP FLO FLT AOD STT DLY DLY_RATE
## 1 2019 9 16 월 ARP1 ARP3 L L1702 A 9:05 NA NA
## 2 2019 9 16 월 ARP3 ARP1 L L1702 D 7:55 NA NA
## 3 2019 9 16 월 ARP1 ARP3 L L1720 A 14:40 NA NA
## 4 2019 9 16 월 ARP3 ARP1 L L1720 D 13:30 NA NA
## 5 2019 9 16 월 ARP4 ARP3 L L1808 A 20:10 NA NA
## 6 2019 9 16 월 ARP3 ARP4 L L1808 D 19:10 NA NA
## FLT_C02_ratio FLT_IRR_ratio FLT_meantimediff FLT_DLY_ratio HOUR count
## 1 5.091312 1.8262313 12.28832 5.755396 9 25
## 2 5.091312 1.8262313 12.28832 5.755396 7 24
## 3 22.232472 0.1845018 20.32472 22.785978 14 26
## 4 22.232472 0.1845018 20.32472 22.785978 13 30
## 5 22.436604 0.2205072 21.50331 20.507166 20 3
## 6 22.436604 0.2205072 21.50331 20.507166 19 28
Train set, Test set 샘플링
afsnt <- afsnt[ , -c(6,8,9,11,13,14,15,18,19)]
afsnt_dly$SDT_YY <- as.factor(afsnt_dly$SDT_YY)
afsnt_dly$SDT_MM <- as.factor(afsnt_dly$SDT_MM)
afsnt_dly$SDT_DD <- as.factor(afsnt_dly$SDT_DD)
afsnt_dly$HOUR <- as.factor(afsnt_dly$HOUR)
# 예측률을 높이기 위하여 미지연과 지연 비율을 73:27로 맞춰서 학습데이터 적합
# 같은 결과를 얻기 위해 seed를 설정합니다.
set.seed(seed = 123)
# 목적변수 비율 맞춰 샘플링 하기
afsnt_Y <- afsnt[(afsnt$DLY == "Y"), ]
afsnt_N <- afsnt[(afsnt$DLY == "N"), ]
# 트레인 테스트 셋 샘플링하기 위해 다음과 같이 처리합니다.
index <- sample(x = 1:2,
size = nrow(x = afsnt_N),
prob = c(0.7, 0.3),
replace = TRUE)
trainSet_N <- afsnt_N[index == 2,]
index <- sample(x = 1:2,
size = nrow(x = afsnt_Y),
prob = c(0.8, 0.2),
replace = TRUE)
trainSet_Y <- afsnt_Y[index == 1,]
trainSet <- rbind(trainSet_Y, trainSet_N)
# 테스트 데이터 셋은 실제 미지연과 지연 데이터 비율인 87:13에 맞춰 적합
testSet_N <- afsnt_N[index == 1,]
testSet_N <- sample_n(testSet_N, 160000)
testSet_Y <- afsnt_Y[index == 2, ]
testSet <- rbind(testSet_Y, testSet_N)
# 훈련용, 시험용 데이터셋의 목표변수 비중을 확인합니다.
trainSet$DLY %>% table() %>% prop.table()
## .
## N Y
## 0.7305399 0.2694601
testSet$DLY %>% table() %>% prop.table()
## .
## N Y
## 0.8704925 0.1295075
랜덤포레스트 모델 성능확인
# 랜덤 포레스트 분류모형 성능 확인하기 위해 ntree = 50, mtry = 5를 임의로 넣어 모델 적합
fitRFC <- randomForest(x = trainSet[, -8],
y = trainSet[, 8],
xtest = testSet[, -8],
ytest = testSet[, 8],
ntree = 50,
mtry = 5,
importance = TRUE,
do.trace = 50,
keep.forest = TRUE)
## ntree OOB 1 2| Test 1 2
## 50: 22.05% 11.91% 49.52%| 13.02% 7.59% 49.54%
# 모형 적합 결과를 확인합니다.
print(x = fitRFC)
##
## Call:
## randomForest(x = trainSet[, -8], y = trainSet[, 8], xtest = testSet[, -8], ytest = testSet[, 8], ntree = 50, mtry = 5, importance = TRUE, do.trace = 50, keep.forest = TRUE)
## Type of random forest: classification
## Number of trees: 50
## No. of variables tried at each split: 5
##
## OOB estimate of error rate: 22.05%
## Confusion matrix:
## N Y class.error
## N 227195 30717 0.1190988
## Y 47113 48018 0.4952434
## Test set error rate: 13.02%
## Confusion matrix:
## N Y class.error
## N 147859 12141 0.07588125
## Y 11793 12011 0.49542094
# OOB 에러 추정값을 그래프로 그립니다.
plot(x = fitRFC$err.rate[, 1],
ylab = 'OOB Error',
type = 'l')
# 변수의 중요도를 그래프로 출력합니다. 내림차순으로 정렬되어 출력되므로 한 눈에 파악됩니다.
varImpPlot(x = fitRFC, main = 'Random Forest Classification Model with afsnt Dataset')
AUROC 구하는 함수 적합
# 분류모형의 ROC 커브 및 AUROC를 반환하는 사용자 정의 함수를 생성합니다.
getROC <- function(real, pred) {
# pred와 real이 범주형일 수 있으므로 숫자형 벡터로 변환합니다.
pred <- pred %>% as.numeric()
real <- real %>% as.numeric()
# ROC 커브를 그리기 위해 prediction object를 생성합니다.
# pred와 real이 범주형일 수 있으므로 숫자형 벡터로 변환합니다.
predObj <- prediction(predictions = pred,
labels = real)
# predObj 객체를 활용하여 performance 객체를 생성합니다.
perform <- performance(prediction.obj = predObj,
measure = 'tpr',
x.measure = 'fpr')
# ROC 커브를 그립니다.
plot(x = perform, main = 'ROC curve')
# 편의상 왼쪽 아래 모서리에서 오른쪽 위 모서리를 잇는 대각선을 추가합니다.
lines(x = c(0, 1), y = c(0, 1), col = 'red', lty = 2)
# AUROC를 계산합니다.
auroc <- auc(real, pred)
print(x = auroc)
# AUROC를 ROC 그래프 오른쪽 아래에 추가합니다.
text(x = 0.9, y = 0, labels = str_c('AUROC : ', auroc), col = 'red', font = 2)
}
모델 성능 확인
# trainSet의 추정확률과 추정값(레이블)을 trProb, trPred에 할당합니다.
trProb <- fitRFC$test$votes[, 2]
trPred <- fitRFC$test$predicted
# 훈련셋의 실제값을 trReal에 할당합니다.
trReal <- testSet$DLY
# 혼동행렬을 출력합니다.
confusionMatrix(data = trPred, reference = trReal, positive = 'Y')
## Confusion Matrix and Statistics
##
## Reference
## Prediction N Y
## N 147859 11793
## Y 12141 12011
##
## Accuracy : 0.8698
## 95% CI : (0.8682, 0.8713)
## No Information Rate : 0.8705
## P-Value [Acc > NIR] : 0.8177
##
## Kappa : 0.426
## Mcnemar's Test P-Value : 0.0249
##
## Sensitivity : 0.50458
## Specificity : 0.92412
## Pos Pred Value : 0.49731
## Neg Pred Value : 0.92613
## Prevalence : 0.12951
## Detection Rate : 0.06535
## Detection Prevalence : 0.13140
## Balanced Accuracy : 0.71435
##
## 'Positive' Class : Y
##
# F1 점수를 확인합니다.
F1_Score(y_pred = trPred, y_true = trReal, positive = 'Y')
## [1] 0.5009175
# 추정레이블로 ROC 그래프를 그리고 AUROC를 확인합니다.
getROC(real = trReal, pred = trPred)
## Area under the curve: 0.7143
# 추정확률로 ROC 그래프를 그리고 AUROC를 확인합니다.
getROC(real = trReal, pred = trProb)
## Area under the curve: 0.8562
afsnt_dly DLY 예측 학습 셋 적합
# 위와 마찬가지로 미지연과 지연의 비율을 73:27로 맞춰 학습셋 적합
afsnt_Y <- afsnt[(afsnt$DLY == "Y"), ]
afsnt_N <- afsnt[(afsnt$DLY == "N"), ]
# 존재하는 지연 데이터 개수에 맞는 미지연 데이터(32150행) 추출 후 바인딩
trainSet_N <- sample_n(afsnt_N, 321560)
trainSet <- rbind(afsnt_Y, trainSet_N)
afsnt_dly <- afsnt_dly[c(colnames(trainSet))]
# 랜덤 포레스트 분류모형을 적합합니다. (그리드 서칭 결과 최적의 ntree, mtry 결정)
# 다른 범주가 존재하는 'FLO' 변수 제거
fitRFC <- randomForest(x = trainSet[, -c(6,8)],
y = trainSet[, 8],
xtest = afsnt_dly[, -c(6,8)],
ntree = 500,
mtry = 5,
importance = TRUE,
do.trace = 50,
keep.forest = TRUE)
## ntree OOB 1 2
## 50: 21.91% 11.63% 49.70%
## 100: 21.08% 10.66% 49.24%
## 150: 20.79% 10.34% 49.05%
## 200: 20.66% 10.17% 49.02%
## 250: 20.58% 10.07% 49.00%
## 300: 20.53% 10.03% 48.91%
## 350: 20.47% 9.97% 48.85%
## 400: 20.42% 9.92% 48.80%
## 450: 20.42% 9.91% 48.85%
## 500: 20.40% 9.89% 48.82%
trProb <- fitRFC$test$votes[, 2]
trPred <- fitRFC$test$predicted
final <- cbind(trPred, trProb) %>% as.data.frame()
colnames(final) <- c("DLY", "DLY_RATE")
final$DLY <- as.factor(final$DLY)
final$DLY = revalue(final$DLY, replace=c("1"="N", "2"="Y"))
# 기존 afsnt_dly에 예측한 DLY, DLY_RATE 컬럼 추가
afsnt_dly_final <- cbind(afsnt_dly, final)
write.csv(afsnt_dly_final, file = "afsnt_dly_final.csv", row.names = FALSE)
head(afsnt_dly_final)
## SDT_YY SDT_MM SDT_DD SDT_DY ARP FLO AOD DLY HOUR count FLT_C02_ratio
## 1 2019 9 16 월 ARP1 L A NA 9 25 5.091312
## 2 2019 9 16 월 ARP3 L D NA 7 24 5.091312
## 3 2019 9 16 월 ARP1 L A NA 14 26 22.232472
## 4 2019 9 16 월 ARP3 L D NA 13 30 22.232472
## 5 2019 9 16 월 ARP4 L A NA 20 3 22.436604
## 6 2019 9 16 월 ARP3 L D NA 19 28 22.436604
## FLT_IRR_ratio FLT_meantimediff FLT_DLY_ratio DLY DLY_RATE
## 1 1.8262313 12.28832 5.755396 N 0.062
## 2 1.8262313 12.28832 5.755396 N 0.272
## 3 0.1845018 20.32472 22.785978 N 0.346
## 4 0.1845018 20.32472 22.785978 Y 0.842
## 5 0.2205072 21.50331 20.507166 N 0.346
## 6 0.2205072 21.50331 20.507166 Y 0.560