1 펭귄 데이터셋1

데이터 과학의 기본 데이터셋으로 인정받던 붓꽃(Iris) 데이터가 이제는 자리를 펭귄 데이터셋에게 자리를 물려주는 듯 싶다. 기초 통계학, 시각화 뿐만 아니라 tidymodels에도 이를 기본 데이터셋으로 활용하는 사례가 심심치 않게 보여주고 있다. 이런 추세는 최근 TidyTuesday 2020년 31번째 데이터셋(2020-07-28)으로 팔머 팽귄(Palmer Penguins)으로 당첨되면서 Iris 데이터를 대체하는 것은 기정사실화 된 듯 싶다.

library(tidyverse)
tuesdata <- tidytuesdayR::tt_load('2020-07-28')

    Downloading file 1 of 2: `penguins.csv`
    Downloading file 2 of 2: `penguins_raw.csv`
penguin <- tuesdata$penguins

penguin
# A tibble: 344 x 8
   species island bill_length_mm bill_depth_mm flipper_length_~ body_mass_g
   <chr>   <chr>           <dbl>         <dbl>            <dbl>       <dbl>
 1 Adelie  Torge~           39.1          18.7              181        3750
 2 Adelie  Torge~           39.5          17.4              186        3800
 3 Adelie  Torge~           40.3          18                195        3250
 4 Adelie  Torge~           NA            NA                 NA          NA
 5 Adelie  Torge~           36.7          19.3              193        3450
 6 Adelie  Torge~           39.3          20.6              190        3650
 7 Adelie  Torge~           38.9          17.8              181        3625
 8 Adelie  Torge~           39.2          19.6              195        4675
 9 Adelie  Torge~           34.1          18.1              193        3475
10 Adelie  Torge~           42            20.2              190        4250
# ... with 334 more rows, and 2 more variables: sex <chr>, year <dbl>

2 팩키지2

2.1 tidymverse 팩키지

데이터 팩키지와는 별도로 tidymodels 예측모형 개발에 간접적으로 사용된 팩키지는 다음과 같다.

library(magick)

pkgs <- c('tidyverse', 'tidymodels', 'parsnip', 'ggplot2', 'pipe', 'purrr', 'usethis')

pkgs_path <- glue::glue("https://raw.githubusercontent.com/rstudio/hex-stickers/master/SVG/{pkgs}.svg")

pkgs_img <- purrr::map(pkgs_path, magick::image_read) %>% 
  magick::image_join(.)

pkgs_img %>% 
  image_scale('150') %>% 
  image_append(stack = FALSE)  

2.2 tidymodels 팩키지

tidymodels를 구성하는 핵심 팩키지는 다음과 같다.

tidymodels_pkgs <- c('rsample', 'recipes', 'parsnip', 'yardstick', 'tune', 'dials', 'workflows', 'plumber')

tidymodels_pkgs_path <- glue::glue("https://raw.githubusercontent.com/rstudio/hex-stickers/master/SVG/{tidymodels_pkgs}.svg")

tidymodels_pkgs_img <- purrr::map(tidymodels_pkgs_path, magick::image_read) %>% 
  magick::image_join(.)

tidymodels_pkgs_img %>% 
  image_scale('150') %>% 
  image_append(stack = FALSE)  

3 데이터 전처리

나름 잘 정리되어 있어 결측값만 처리하고 연도와 펭귄이 거주하고 있는 섬만 제거한다.

penguin_df <- penguin %>%
  filter(!is.na(sex)) %>%
  select(-year, -island) %>% 
  mutate_if(is.character, as.factor)

4 성별예측 모형3

펭귄 데이터셋에서 성별(sex)을 예측하는 모형을 구축해본다.

4.1 훈련/시험 데이터셋

initial_split() 함수로 훈련/시험 데이터셋으로 나누고, training(), testing() 함수로 훈련/시험 데이터를 기계학습을 위한 데이터로 준비한다.

library(tidymodels)

# 훈련 시험 데이터 분할
splits <- initial_split(penguin_df, prop = 0.8, strata = sex)
penguin_train <- training(splits)
penguin_test <- testing(splits)

4.2 모형 설정

parsnip 팩키지를 사용해서 데이터를 학습할 혹은 데이터를 가장 잘 설명할 수 있는 모형을 구축한다. 분류 모형이냐 예측모형이냐에 따라 적합한 모형명세(Model Specification) 작업을 수행한다. 펭귄 성별 수컷과 암컷을 예측하는 문제는 분류문제이기 때문에 GLM 모형으로 모형을 선정한다.

library(tidymodels)

glm_model <- logistic_reg() %>% 
  set_engine('glm') %>% 
  set_mode('classification')

4.3 모형 적합

fit() 함수를 통해 모형 공식을 작성하고 데이터에 적합시킨다. 모형공식은 sex ~ .으로 종속예측변수는 sex가 되고 나머지 모든 변수를 예측에 사용하도록 모형공식을 작성한다.

glm_fit <- glm_model %>% 
  fit(sex ~ ., data = training(splits))

4.4 모형 예측

glm_fit 예측모형이 준비되면 시험 데이터 testing(splits)을 준비하여 시험데이터에 대한 예측값을 뽑아낼 수 있다. 특히 predict() 함수의 인자값을 범주(type = 'class')나 확률(type = 'prob')로 지정함으로써 예측값을 정답과 편하게 비교할 수 있다.

class_pred <- glm_fit %>% 
  predict(new_data = testing(splits), type = 'class')

prob_pred <- glm_fit %>% 
  predict(new_data = testing(splits), type = 'prob')
  
evaluation_tbl <- testing(splits) %>% 
  select(sex) %>% 
  bind_cols(class_pred) %>% 
  bind_cols(prob_pred)

evaluation_tbl
# A tibble: 65 x 4
   sex    .pred_class .pred_female .pred_male
   <fct>  <fct>              <dbl>      <dbl>
 1 female female         0.672        0.328  
 2 female female         0.679        0.321  
 3 female female         0.949        0.0507 
 4 male   female         0.689        0.311  
 5 female female         0.973        0.0270 
 6 female female         0.939        0.0612 
 7 female female         0.996        0.00436
 8 male   male           0.0140       0.986  
 9 female female         0.990        0.00962
10 male   male           0.0000891    1.00   
# ... with 55 more rows

4.5 모형 평가4

모형성능에 대한 평가는 yardstick 팩키지의 다양한 평가함수를 통해 수행한다. 이를 위해서 시험데이터에 대한 정답과 모형의 예측값과 예측확률이 함께 준비되어야 한다. 가장 먼저 정답과 모형의 성능을 평가하는 가장 일반적인 방식이 오차행렬(confusion matrix)을 사용하는 것이다. 이를 위해서 앞서 준비한 evaluation_tbl 데이터프레임을 정답과 모형 예측값과 관측점별로 비교하여 오차표를 작성한다.

conf_mat(evaluation_tbl,
         truth = sex,
         estimate = .pred_class)
          Truth
Prediction female male
    female     30    5
    male        2   28

혹은 한 발 더 나아가 conf_mat() 함수와 summmary() 함수를 파이프로 조합시키게 되면 가능한 모형성능 측정지표를 얻을 수 있다.

conf_mat(evaluation_tbl,
         truth = sex,
         estimate = .pred_class) %>%
  summary()
# A tibble: 13 x 3
   .metric              .estimator .estimate
   <chr>                <chr>          <dbl>
 1 accuracy             binary         0.892
 2 kap                  binary         0.785
 3 sens                 binary         0.938
 4 spec                 binary         0.848
 5 ppv                  binary         0.857
 6 npv                  binary         0.933
 7 mcc                  binary         0.788
 8 j_index              binary         0.786
 9 bal_accuracy         binary         0.893
10 detection_prevalence binary         0.538
11 precision            binary         0.857
12 recall               binary         0.938
13 f_meas               binary         0.896

범주 분류예측모형에서 가장 많이 인용되는 분류모형 측정지표(metric)을 사용해서 앞서 개발한 예측모형에 대한 성능을 파악해보자.

penguin_metrics <- metric_set(accuracy, sens, precision, recall, f_meas)

penguin_metrics(evaluation_tbl,
                truth = sex,
                estimate = .pred_class)
# A tibble: 5 x 3
  .metric   .estimator .estimate
  <chr>     <chr>          <dbl>
1 accuracy  binary         0.892
2 sens      binary         0.938
3 precision binary         0.857
4 recall    binary         0.938
5 f_meas    binary         0.896

roc_auc() 함수를 사용하게 되면 한계점(threshold) 별로 모형성능을 판단할 수 있다. ROC AUC 값은 다음과 같은 모형성능 등급표가 많이 참고되고 있다.

  • A: 0.9 ~ 1
  • B: 0.8 ~ 0.9
  • C: 0.7 ~ 0.8
  • D: 0.6 ~ 0.7
  • F: 0.5 ~ 0.6
roc_auc(evaluation_tbl,
        truth = sex,
        .pred_female)
# A tibble: 1 x 3
  .metric .estimator .estimate
  <chr>   <chr>          <dbl>
1 roc_auc binary         0.982

이를 시각화하면 다음과 같다.

roc_curve(evaluation_tbl,
          truth = sex,
          .pred_female) %>% 
  autoplot()

5 모형 구축 자동화

훈련/시험 데이터셋 구분부터 시작하여 예측모형 설정과 적합 및 평가과정을 자동화할 수 있다. 특히 마지막 last_fit(), collect_metrics(), collect_predictions()을 통해서 중간과정을 생략하고 Auto-ML에 한 걸음 다가설 수 있다.

# 훈련 시험 데이터 분할
splits <- initial_split(penguin_df, prop = 0.8, strata = sex)

# 모형상세
glm_model <- logistic_reg() %>% 
  set_engine('glm') %>% 
  set_mode('classification')

# 모형 최종적합
glm_last_fit <- glm_model %>% 
  last_fit(sex ~ ., split = splits)

# 모형 평가
glm_last_fit %>% 
  collect_metrics()
# A tibble: 2 x 4
  .metric  .estimator .estimate .config             
  <chr>    <chr>          <dbl> <chr>               
1 accuracy binary         0.892 Preprocessor1_Model1
2 roc_auc  binary         0.942 Preprocessor1_Model1
# 모형 예측
last_fit_tbl <- glm_last_fit %>% 
  collect_predictions()

last_fit_tbl
# A tibble: 65 x 7
   id            .pred_female .pred_male  .row .pred_class sex   .config        
   <chr>                <dbl>      <dbl> <int> <fct>       <fct> <chr>          
 1 train/test s~  0.893        0.107         3 female      fema~ Preprocessor1_~
 2 train/test s~  0.639        0.361         4 female      fema~ Preprocessor1_~
 3 train/test s~  0.000533     0.999        10 male        male  Preprocessor1_~
 4 train/test s~  0.000000662  1.00         15 male        male  Preprocessor1_~
 5 train/test s~  0.737        0.263        17 female      male  Preprocessor1_~
 6 train/test s~  0.920        0.0799       20 female      male  Preprocessor1_~
 7 train/test s~  0.947        0.0529       23 female      fema~ Preprocessor1_~
 8 train/test s~  0.00543      0.995        46 male        male  Preprocessor1_~
 9 train/test s~  1.00         0.0000293    53 female      fema~ Preprocessor1_~
10 train/test s~  0.216        0.784        54 male        male  Preprocessor1_~
# ... with 55 more rows
# 모형 평가 최종 지표 : https://github.com/tidymodels/yardstick/issues/128
# classification_metrics <- metric_set(accuracy, sens, spec, precision, recall, roc_auc)
# 
# classification_metrics(last_fit_tbl,
#                        truth = sex,
#                        estimate = .pred_female,
#                        .pred_class)
 

데이터 과학자 이광춘 저작

kwangchun.lee.7@gmail.com