R2D3 웹사이트에 기계학습에 대한 시각적 소개가 잘 정리되어 있다. 뉴욕과 샌프란시스코 두 도시의 부동산을 분류하는 데이터를 바탕으로 의사결정나무(Decision Tree) 기계학습 알고리즘이 동작하는 방식을 마우스 스크롤을 아래로 내리게 되면 시각적으로 확인할 수 있다.
FAQ 웹사이트에서 CSV 파일을 다운로드 받아 직접 기계학습 예측모형을 제작해보자.
xgBoost
예측모형 설명과 이해뉴욕, 샌프란시스코 집값데이터를 다운로드 받아 작업을 하는데 xgBoost에서는 분류예측모형을 개발할 때 종속변수가 0,1로 코딩이 되어야 되서 이를 사전에 반영한다.
# 0. 환경설정 -----
library(tidyverse)
library(recipes)
library(skimr)
library(DALEX)
library(xgboost)
# 1. 데이터 -----
## 1.1. 데이터 가져오기
r2d3_df <- read_csv("https://raw.githubusercontent.com/jadeyee/r2d3-part-1-data/master/part_1_data.csv", skip=2) %>%
mutate(in_sf = as.integer(as.factor(in_sf))-1)
glimpse(r2d3_df)
Observations: 492
Variables: 8
$ in_sf <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,...
$ beds <dbl> 2, 2, 2, 1, 0, 0, 1, 1, 1, 2, 3, 1, 1, 1, 0, 2,...
$ bath <dbl> 1.0, 2.0, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1....
$ price <int> 999000, 2750000, 1350000, 629000, 439000, 43900...
$ year_built <int> 1960, 2006, 1900, 1903, 1930, 1930, 1920, 1930,...
$ sqft <int> 1000, 1418, 2150, 500, 500, 500, 500, 900, 900,...
$ price_per_sqft <int> 999, 1939, 628, 1258, 878, 878, 950, 1083, 1083...
$ elevation <int> 10, 0, 9, 9, 10, 10, 10, 10, 12, 12, 4, 5, 5, 3...
recipes
팩키지를 이용하여 요리를 한 후에 xgb.DMatrix()
함수로 데이터프레임을 xgBoost 행렬로 변환시킨다. 그리고 나서 예측모형을 생성한다.
## 1.2. X/Y 데이터 분할
x_train_tbl <- r2d3_df %>% select(-in_sf)
y_train_tbl <- r2d3_df %>% select(in_sf)
## 1.3. X/Y 데이터 요리
rec_obj <- recipe(~ ., data = x_train_tbl) %>%
# step_scale(all_numeric()) %>%
prep(stringsAsFactors = FALSE)
x_train_processed_tbl <- bake(rec_obj, x_train_tbl)
y_train_processed_tbl <- y_train_tbl
xy_train <- bind_cols(y_train_processed_tbl, x_train_processed_tbl)
# 2. 모형 -----
## 2.1. xgBoost 데이터프레임 --> 행렬 변환 -----
model_martix_train <- model.matrix(in_sf ~ . - 1, xy_train)
data_train <- xgb.DMatrix(model_martix_train, label = xy_train$in_sf)
## 2.2. CV 훈련 -----
param <- list(max_depth = 3, eta = 0.5, silent = 1,
nrounds =10, objective = "binary:logistic", eval_metric = "auc")
bst.cv <- xgb.cv(param = param, data_train,
nfold = 5, nrounds = 10)
[1] train-auc:0.941450+0.005091 test-auc:0.917379+0.032575
[2] train-auc:0.961154+0.005281 test-auc:0.933966+0.020488
[3] train-auc:0.976706+0.002428 test-auc:0.946442+0.017506
[4] train-auc:0.978945+0.002187 test-auc:0.951946+0.015630
[5] train-auc:0.982998+0.001408 test-auc:0.954841+0.010607
[6] train-auc:0.987774+0.001967 test-auc:0.957372+0.008616
[7] train-auc:0.988662+0.002205 test-auc:0.958932+0.009653
[8] train-auc:0.991129+0.002379 test-auc:0.959631+0.011810
[9] train-auc:0.992328+0.002224 test-auc:0.961647+0.008428
[10] train-auc:0.993288+0.002132 test-auc:0.961771+0.010259
## 2.3. xgBoost 모형 -----
xgb_model <- xgb.train(param, data_train, nrounds = 5)
xgb_model
##### xgb.Booster
raw: 3.6 Kb
call:
xgb.train(params = param, data = data_train, nrounds = 5)
params (as set within xgb.train):
max_depth = "3", eta = "0.5", silent = "1", nrounds = "10", objective = "binary:logistic", eval_metric = "auc", silent = "1"
xgb.attributes:
niter
callbacks:
cb.print.evaluation(period = print_every_n)
# of features: 7
niter: 5
nfeatures : 7
블랙박스 xgBoost 모형 이해와 설명을 위해서 DALEX 팩키지 explain()
함수를 사용한다. 연속형 변수 예측이 아니라 범주 예측이라 Przemyslaw Biecek(2018-04-28), “How to use DALEX with the xgboost models”을 참조하여 준용한다.
# 3. 모형 설명 -----
predict_logit <- function(model, x) {
raw_x <- predict(model, x)
exp(raw_x)/(1 + exp(raw_x))
}
logit <- function(x) exp(x)/(1+exp(x))
explainer_xgb <- explain(xgb_model,
data = model_martix_train,
y = xy_train$in_sf,
predict_function = predict_logit,
link = logit,
label = "xgboost")
예측모형 성능을 이해하기 위해서 model_performance()
함수를 사용한다. 경우에 따라 차이가 있기는 하지만, 대체로 xgBoost
가 회귀분석이나 분류모형 거의 모든 경우에 가장 성능이 좋게 나오거나 유사한 성능을 보이고 있다.
## 3.1. 모형성능(Performance) -----
mp_xgb <- model_performance(explainer_xgb)
plot(mp_xgb, geom = "boxplot", show_outliers = 3)
variable_importance()
함수로 중요한 변수가 무엇인지 시각적으로 파악한다.
## 3.2. 변수 중요도(Variable Importance)
vd_xgb <- variable_importance(explainer_xgb, type = "raw")
plot(vd_xgb)
variable_response()
함수로 관심있는 변수가 뉴욕, 샌프란시스코 부동산 분류 예측에 어떻게 연관되는지 파악한다.
## 3.3. 변수 반응도
sv_xgb_price <- variable_response(explainer_xgb,
variable = "price",
type = "pdp")
plot(sv_xgb_price) +
scale_x_log10(labels=scales::comma)
마지막으로 특정 관측점에 영향을 주는 요인이 무엇인지 prediction_breakdown()
함수로 파악한다. 예측에 대한 각 변수별 기여도를 분해(breakdown)하여 자세히 살펴볼 수 있다.
## 3.4. 특정 관측점 Breakdown
target_obs <- model_martix_train[1, , drop = FALSE]
sp_xgb <- prediction_breakdown(explainer_xgb,
observation = target_obs)
plot(sp_xgb)