1 RDBMS 배포 모형

빅데이터 출현으로 NoSQL이 많은 관심을 가졌지만, 데이터의 가치로만 보면 RDBMS도 못지않게 중요한 정보가 많이 담겨있고 체계적으로 관리되고 있는 것도 사실이다. 기계학습 예측모형을 개발하여 이를 RDBMS에 배포하는 상황도 일반적인 사례다.

데이터베이스 배포

특정 데이터베이스를 특정하면 tidypredict 예측모형(lm, glm, randomForest, ranger) 변환 기능을 사용해서 예측모형 R 코드를 SQL 코드로 변환이 가능하다. 변환된 SQL 코드를 특정 데이터베이스에 배포하는 모형이다. 현재, lm, glm, randomForest, ranger 네가지 팩키지에 대한 예측모형 배포기능만 지원하다.

2 회귀 예측모형 사례

가장 먼저 자동차 연비 데이터(mtcars)를 바탕으로 연비예측모형을 개발하고 이를 sqlite3 데이터베이스에 배포하는 사례를 살펴보자.

2.1 연비예측 모형 구축

mtcars 데이터를 티블로 변환시키고 나서 lm() 회귀모형을 구축하고 과적합방지를 위해서 stepAIC() 함수로 변수선택을 하고 이를 연비예측모형으로 지정한다. \(R^2\)값도 나름 준수하게 나온다.

# 0. 환경설정 ------
# install.packages(c("dbplyr", "RSQLite"))

library(tidyverse)
library(dbplyr)
library(RSQLite)
library(tidypredict)
library(randomForest)

# 1. 기계학습 통계모형 ---------
## 1.1. 데이터 가져오기 -----
mtcars_dat <- mtcars %>% rownames_to_column(var="maker") %>% 
    tbl_df

## 1.2. 기계학습 통계모형 -----

mtcars_lm <- lm(mpg ~ ., mtcars_dat[,-1])  %>% 
    MASS::stepAIC(direction="both", trace = FALSE)

summary(mtcars_lm)

Call:
lm(formula = mpg ~ wt + qsec + am, data = mtcars_dat[, -1])

Residuals:
    Min      1Q  Median      3Q     Max 
-3.4811 -1.5555 -0.7257  1.4110  4.6610 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   9.6178     6.9596   1.382 0.177915    
wt           -3.9165     0.7112  -5.507 6.95e-06 ***
qsec          1.2259     0.2887   4.247 0.000216 ***
am            2.9358     1.4109   2.081 0.046716 *  
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 2.459 on 28 degrees of freedom
Multiple R-squared:  0.8497,    Adjusted R-squared:  0.8336 
F-statistic: 52.75 on 3 and 28 DF,  p-value: 1.21e-11

2.2 연비 예측 배포모형

src_sqlite() 함수로 sqlite3 데이터베이스를 생성하고 나서 mtcars_dat 데이터프레임을 데이터베이스 테이블로 등록한다. 그리고 나서, 쿼리를 던져 제대로 동작하는 테스트한다.

tidypredict 팩키지 tidypredict_sql() 함수에 인자로 simulate_sqlite()을 넘겨 sqlite3 데이터베이스 쿼리로 생성하도록 지정하여 R 연비예측모형을 SQL 코드로 변환시키도록 한다.

# 2. 데이터베이스 ---------
## 2.1. 데이터베이스 테이블 생성 ------
mtcars_db_file <- "mtcars_sqlite"
mtcars_sqlite <- src_sqlite(mtcars_db_file, create = TRUE)

copy_to(mtcars_sqlite, mtcars_dat, overwrite = TRUE)

# mtcars_dbf <- tbl(mtcars_sqlite, "mtcars_dat")
# 
# mtcars_dbf %>%
#     filter(mpg > 25) %>%
#     select(maker, wt, qsec, am) %>%
#     sample_n(5)

## 2.2. 연비예측 스코어 생성 ------
mtcars_mpg_lm <- lm(mpg ~ wt + qsec + am, data = mtcars_dat)

predict_sql <- tidypredict_sql(mtcars_mpg_lm, simulate_sqlite())

# <SQL> 9.61778051456159 + (`wt`) * (-3.91650372494249) + (`qsec`) * (1.2258859715837) + (`am`) * (2.93583719188942)

2.3 예측모형 DB 배포

데이터베이스에 배포할 테이블을 지정하여 ALTER TABLE mtcars_score_tbl ADD COLUMN score REAL 쿼리로 score 필드를 생성시키고 나서, 앞서 연비예측모형 SQL 쿼리를 사용해서 score 즉 해당 차종에 대한 연비를 예측시킨다.

# 3. 데이터베이스 스코어 적용 ---------
## 스코어 데이터베이스 테이블 생성 -----
con <- dbConnect(drv=RSQLite::SQLite(), "mtcars_sqlite")

dbWriteTable(con, "mtcars_score_tbl", mtcars_dat)

dbListTables(con)
[1] "mtcars_score_tbl"
dbExecute(con, "ALTER TABLE mtcars_score_tbl ADD COLUMN score REAL")
[1] 0
# dbGetQuery(con, "SELECT * FROM mtcars_score_tbl")

## 데이터 베이스 스코어링 -----
dbExecute(con, 
          "UPDATE mtcars_score_tbl SET score = 9.61778051456159 + (`wt`) * (-3.91650372494249) + (`qsec`) * (1.2258859715837) + (`am`) * (2.93583719188942)")
[1] 32
dbGetQuery(con, "SELECT maker, mpg, cyl,  disp,  hp,  wt,  qsec, vs, am, carb, score FROM mtcars_score_tbl")
                 maker  mpg cyl  disp  hp    wt  qsec vs am carb    score
1            Mazda RX4 21.0   6 160.0 110 2.620 16.46  0  1    4 22.47046
2        Mazda RX4 Wag 21.0   6 160.0 110 2.875 17.02  0  1    4 22.15825
3           Datsun 710 22.8   4 108.0  93 2.320 18.61  1  1    1 26.28107
4       Hornet 4 Drive 21.4   6 258.0 110 3.215 19.44  1  0    1 20.85744
5    Hornet Sportabout 18.7   8 360.0 175 3.440 17.02  0  0    2 17.00959
6              Valiant 18.1   6 225.0 105 3.460 20.22  1  0    1 20.85409
7           Duster 360 14.3   8 360.0 245 3.570 15.84  0  0    4 15.05390
8            Merc 240D 24.4   4 146.7  62 3.190 20.00  1  0    2 21.64185
9             Merc 230 22.8   4 140.8  95 3.150 22.90  1  0    2 25.35358
10            Merc 280 19.2   6 167.6 123 3.440 18.30  1  0    4 18.57872
11           Merc 280C 17.8   6 167.6 123 3.440 18.90  1  0    4 19.31425
12          Merc 450SE 16.4   8 275.8 180 4.070 17.40  0  0    3 15.00803
13          Merc 450SL 17.3   8 275.8 180 3.730 17.60  0  0    3 16.58481
14         Merc 450SLC 15.2   8 275.8 180 3.780 18.00  0  0    3 16.87934
15  Cadillac Fleetwood 10.4   8 472.0 205 5.250 17.98  0  0    4 11.09757
16 Lincoln Continental 10.4   8 460.0 215 5.424 17.82  0  0    4 10.21995
17   Chrysler Imperial 14.7   8 440.0 230 5.345 17.42  0  0    4 10.03900
18            Fiat 128 32.4   4  78.7  66 2.200 19.47  1  1    1 27.80531
19         Honda Civic 30.4   4  75.7  52 1.615 18.52  1  1    2 28.93187
20      Toyota Corolla 33.9   4  71.1  65 1.835 19.90  1  1    1 29.76196
21       Toyota Corona 21.5   4 120.1  97 2.465 20.01  1  0    1 24.49358
22    Dodge Challenger 15.5   8 318.0 150 3.520 16.87  0  0    2 16.51238
23         AMC Javelin 15.2   8 304.0 150 3.435 17.30  0  0    2 17.37242
24          Camaro Z28 13.3   8 350.0 245 3.840 15.41  0  0    4 13.46931
25    Pontiac Firebird 19.2   8 400.0 175 3.845 17.05  0  0    2 15.46018
26           Fiat X1-9 27.3   4  79.0  66 1.935 18.90  1  1    1 28.14443
27       Porsche 914-2 26.0   4 120.3  91 2.140 16.70  0  1    2 24.64460
28        Lotus Europa 30.4   4  95.1 113 1.513 16.90  1  1    2 27.34542
29      Ford Pantera L 15.8   8 351.0 264 3.170 14.50  0  1    4 17.91365
30        Ferrari Dino 19.7   6 145.0 175 2.770 15.50  0  1    6 20.70613
31       Maserati Bora 15.0   8 301.0 335 3.570 14.60  0  1    8 16.46963
32          Volvo 142E 21.4   4 121.0 109 2.780 18.60  1  1    2 24.46722

3 로지스틱 회귀 예측모형 사례

mtcars 데이터로 연속형 변수(연비, mpg)를 예측하여 이를 데이터베이스에 배포하는 사례를 살펴봤는데, 이번에는 입학당락을 가르는 로지스틱 회귀모형을 배포하는 사례를 살펴보자. 이 경우 score는 입학 확률이 된다.

3.1 입학확률 예측모형

gre, gpa, rank를 예측변수로 합격/불합격이 기록된 데이터를 입수하여 범주형 변수는 요인형으로 변환시켜서 admit_glm 객체에 입학확률 예측모형을 저장시킨다.

# 1. 기계학습 통계모형 ---------
## 1.1. 데이터 가져오기 -----
admit_dat <- read_csv("https://stats.idre.ucla.edu/stat/data/binary.csv")

## 1.2. 데이터 변환 -----
admit_df <- admit_dat %>% 
    mutate(admit = factor(admit),
           rank  = factor(rank))

## 1.3. 기계학습 통계모형 -----
set.seed(777)
admit_glm <- glm(admit ~ ., family="binomial", data=admit_df) 

summary(admit_glm)

Call:
glm(formula = admit ~ ., family = "binomial", data = admit_df)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-1.6268  -0.8662  -0.6388   1.1490   2.0790  

Coefficients:
             Estimate Std. Error z value Pr(>|z|)    
(Intercept) -3.989979   1.139951  -3.500 0.000465 ***
gre          0.002264   0.001094   2.070 0.038465 *  
gpa          0.804038   0.331819   2.423 0.015388 *  
rank2       -0.675443   0.316490  -2.134 0.032829 *  
rank3       -1.340204   0.345306  -3.881 0.000104 ***
rank4       -1.551464   0.417832  -3.713 0.000205 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 499.98  on 399  degrees of freedom
Residual deviance: 458.52  on 394  degrees of freedom
AIC: 470.52

Number of Fisher Scoring iterations: 4

3.2 입학확률 배포모형

admit_glm 모형이 R 코드로 작성되어 있어, 이를 tidypredict_sql() 함수로 sqlite 베이스에서 돌 수 있는 SQL 코드로 변형시킨다.

# 2. 데이터베이스 ---------
## 2.1. 입학 예측모형 생성 ------

admit_glm_sql <- tidypredict_sql(admit_glm, simulate_sqlite())

# <SQL> 1.0 - 1.0 / (1.0 + EXP(-3.98997907333103 + (`gre`) * (0.00226442578617915) + (`gpa`) * (0.804037549280222) + (CASE WHEN (`rank` = '2') THEN (1.0) WHEN NOT(`rank` = '2') THEN (0.0) END) * (-0.675442927963559) + (CASE WHEN (`rank` = '3') THEN (1.0) WHEN NOT(`rank` = '3') THEN (0.0) END) * (-1.34020391646788) + (CASE WHEN (`rank` = '4') THEN (1.0) WHEN NOT(`rank` = '4') THEN (0.0) END) * (-1.55146367691807)))

3.3 입학확률 DB 배포

앞선 연비예측과 동일하게 score 필드에 입학예측확률이 저장되도록 작업을 수행한다.

# 3. 데이터베이스 스코어 적용 ---------
## 스코어 데이터베이스 테이블 생성 -----
con <- dbConnect(drv=RSQLite::SQLite(), "admit_sqlite")

dbWriteTable(con, "admit_score_rf_tbl", admit_dat)

dbListTables(con)
[1] "admit_score_rf_tbl"
# dbGetQuery(con, "SELECT * FROM admit_score_tbl")

## 데이터 베이스 스코어링 -----
dbExecute(con, 
          "ALTER TABLE admit_score_rf_tbl ADD COLUMN score REAL")
[1] 0
dbExecute(con, 
          "UPDATE admit_score_rf_tbl SET score = 1.0 - 1.0 / (1.0 + EXP(-3.98997907333103 + (`gre`) * (0.00226442578617915) + (`gpa`) * (0.804037549280222) + (CASE WHEN (`rank` = '2') THEN (1.0) WHEN NOT(`rank` = '2') THEN (0.0) END) * (-0.675442927963559) + (CASE WHEN (`rank` = '3') THEN (1.0) WHEN NOT(`rank` = '3') THEN (0.0) END) * (-1.34020391646788) + (CASE WHEN (`rank` = '4') THEN (1.0) WHEN NOT(`rank` = '4') THEN (0.0) END) * (-1.55146367691807)))")
[1] 400
dbGetQuery(con, "SELECT * FROM admit_score_rf_tbl LIMIT 5")
  admit gre  gpa rank     score
1     0 380 3.61    3 0.1726265
2     1 660 3.67    3 0.2921750
3     1 800 4.00    1 0.7384082
4     1 640 3.19    4 0.1783846
5     0 520 2.93    4 0.1183539

3.4 배포 스코어 검증

DB에 배포된 입학확률 스코어와 R 예측확률이 동일한지 값을 뽑아내서 정확도도를 검증한다.

## 스코어링 검증 -----

glm_score_df <- predict(admit_glm, newdata = admit_df, type="response") %>% tbl_df %>% 
    rename(glm_score = value)

sqlite_score_df <- tbl(con, "admit_score_rf_tbl") %>% 
    collect() %>% select(sqlite_score = score)

score_comp_df <- bind_cols(glm_score_df, sqlite_score_df) %>% 
    mutate(score_diff = abs(glm_score - sqlite_score))

score_comp_df %>% 
    summarise(sum(score_diff))
# A tibble: 1 x 1
  `sum(score_diff)`
              <dbl>
1 0.000000000000184

4 분류 Random Forest 사례

4.1 예측모형 구축

입학데이터를 동일하게 사용하고 모형은 ranger 대신 randomForest를 사용한다. 성능면에서는 ranger가 더 좋기는 하시만, 데이터가 적은 경우 큰 차이는 없다.

## 1.2. 데이터 변환 -----
admit_df <- admit_dat %>% 
    mutate(admit = factor(admit),
           rank  = factor(rank))

admit_m_df <- model.matrix(admit~.-1, admit_df) %>% 
    as.data.frame()

admit_xy_df <- admit_df %>% select(admit) %>% 
    bind_cols(admit_m_df)

## 1.3. 기계학습 통계모형 -----
set.seed(777)
admit_rf <- randomForest(admit ~ ., data=admit_xy_df) 

admit_rf

Call:
 randomForest(formula = admit ~ ., data = admit_xy_df) 
               Type of random forest: classification
                     Number of trees: 500
No. of variables tried at each split: 2

        OOB estimate of  error rate: 27.75%
Confusion matrix:
    0  1 class.error
0 263 10  0.03663004
1 101 26  0.79527559

4.2 RF 예측모형 생성

tidypredict에서 randomForest, ranger를 지원하기 때문에 내부적으로 randomForest 팩키지 getTree() 함수를 사용하는 tidypredict_sql() 기능을 통해서 R 객체를 SQL 코드로 변환시킨다.

# 2. 데이터베이스 ---------
## 2.1. 입학 예측모형 생성 ------

admit_sql <- tidypredict_sql(admit_rf, simulate_sqlite())

4.3 RF 예측모형 배포

동일한 방식으로 RF 모형을 생성된 SQL 코드 형태로 데이터베이스에 배포시킨다.

# 3. 데이터베이스 스코어 적용 ---------
## 스코어 데이터베이스 테이블 생성 -----
con <- dbConnect(drv=RSQLite::SQLite(), "admit_sqlite")

dbWriteTable(con, "admit_score_tbl", admit_xy_df)

dbListTables(con)
[1] "admit_score_rf_tbl" "admit_score_tbl"   
# dbGetQuery(con, "SELECT * FROM admit_score_tbl ")

## 데이터 베이스 스코어링 -----
dbExecute(con, 
          "ALTER TABLE admit_score_tbl ADD COLUMN score REAL")
[1] 0
dbExecute(con, 
          "UPDATE admit_score_tbl SET score = CASE
WHEN ((`rank1` > 0.5)) THEN ('0')
          WHEN ((`gpa` > 3.115 AND `gre` <= 420.0 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`rank4` > 0.5 AND `gpa` <= 2.88 AND `gpa` <= 3.505 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gpa` > 2.88 AND `rank4` > 0.5 AND `gpa` <= 3.505 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gpa` > 3.755 AND `gpa` > 3.505 AND `rank4` > 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gre` <= 450.0 AND `gpa` <= 2.69 AND `gpa` <= 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gre` > 450.0 AND `rank2` <= 0.5 AND `gpa` <= 2.69 AND `gpa` <= 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`rank3` > 0.5 AND `gpa` > 2.69 AND `gre` <= 670.0 AND `gpa` <= 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`rank3` > 0.5 AND `gre` > 670.0 AND `gpa` > 2.69 AND `gpa` <= 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gre` > 420.0 AND `gpa` > 3.115 AND `gpa` <= 3.495 AND `rank3` <= 0.5 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gpa` > 3.505 AND `rank4` > 0.5 AND `gre` <= 520.0 AND `gpa` <= 3.625 AND `gpa` <= 3.755 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gre` > 520.0 AND `gpa` > 3.505 AND `rank4` > 0.5 AND `gpa` <= 3.625 AND `gpa` <= 3.755 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gpa` > 3.625 AND `gpa` > 3.505 AND `rank4` > 0.5 AND `gpa` <= 3.725 AND `gpa` <= 3.755 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gpa` > 3.725 AND `gpa` > 3.625 AND `gpa` > 3.505 AND `rank4` > 0.5 AND `gpa` <= 3.755 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`rank2` > 0.5 AND `gre` > 450.0 AND `gpa` <= 2.595 AND `gpa` <= 2.69 AND `gpa` <= 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gpa` > 2.595 AND `rank2` > 0.5 AND `gre` > 450.0 AND `gpa` <= 2.69 AND `gpa` <= 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gpa` > 2.69 AND `gre` <= 350.0 AND `rank3` <= 0.5 AND `gre` <= 670.0 AND `gpa` <= 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gre` > 670.0 AND `gpa` > 2.69 AND `gpa` <= 2.955 AND `rank3` <= 0.5 AND `gpa` <= 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gre` > 690.0 AND `gpa` > 3.495 AND `gre` > 420.0 AND `gpa` > 3.115 AND `rank3` <= 0.5 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gre` > 350.0 AND `gpa` > 2.69 AND `gre` <= 590.0 AND `rank3` <= 0.5 AND `gre` <= 670.0 AND `gpa` <= 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gpa` > 2.955 AND `gre` > 670.0 AND `gpa` > 2.69 AND `gpa` <= 3.08 AND `rank3` <= 0.5 AND `gpa` <= 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gpa` > 3.08 AND `gpa` > 2.955 AND `gre` > 670.0 AND `gpa` > 2.69 AND `rank3` <= 0.5 AND `gpa` <= 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gre` > 670.0 AND `gpa` > 3.495 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gre` <= 690.0 AND `rank3` <= 0.5 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gpa` > 3.445 AND `rank3` > 0.5 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gre` <= 590.0 AND `gre` <= 690.0 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gre` > 590.0 AND `rank3` > 0.5 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gpa` <= 3.255 AND `gre` <= 690.0 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gpa` > 3.52 AND `gre` > 690.0 AND `rank3` > 0.5 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gpa` <= 3.97 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gpa` > 3.97 AND `gre` > 690.0 AND `rank3` > 0.5 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gre` <= 730.0 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gre` > 730.0 AND `gpa` > 3.97 AND `gre` > 690.0 AND `rank3` > 0.5 AND `gre` > 420.0 AND `gpa` > 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gre` > 590.0 AND `gre` > 350.0 AND `gpa` > 2.69 AND `gpa` <= 2.885 AND `rank3` <= 0.5 AND `gre` <= 670.0 AND `gpa` <= 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gpa` > 2.885 AND `gre` > 590.0 AND `gre` > 350.0 AND `gpa` > 2.69 AND `rank3` <= 0.5 AND `gre` <= 670.0 AND `gpa` <= 3.115 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`rank3` > 0.5 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gpa` <= 3.135 AND `gpa` <= 3.445 AND `gre` <= 590.0 AND `gre` <= 690.0 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gpa` > 3.135 AND `rank3` > 0.5 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gpa` <= 3.445 AND `gre` <= 590.0 AND `gre` <= 690.0 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gpa` > 3.255 AND `gre` > 590.0 AND `rank3` > 0.5 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gpa` <= 3.54 AND `gre` <= 690.0 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gpa` > 3.54 AND `gpa` > 3.255 AND `gre` > 590.0 AND `rank3` > 0.5 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gre` <= 690.0 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gre` > 690.0 AND `rank3` > 0.5 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gre` <= 740.0 AND `gpa` <= 3.52 AND `gpa` <= 3.97 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gre` > 740.0 AND `gre` > 690.0 AND `rank3` > 0.5 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gpa` <= 3.52 AND `gpa` <= 3.97 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gpa` > 3.495 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gre` <= 550.0 AND `gre` <= 630.0 AND `gre` <= 670.0 AND `gre` <= 690.0 AND `rank3` <= 0.5 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gre` > 630.0 AND `gpa` > 3.495 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gre` <= 650.0 AND `gre` <= 670.0 AND `gre` <= 690.0 AND `rank3` <= 0.5 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gre` > 650.0 AND `gre` > 630.0 AND `gpa` > 3.495 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gre` <= 670.0 AND `gre` <= 690.0 AND `rank3` <= 0.5 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gre` > 550.0 AND `gpa` > 3.495 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gre` <= 590.0 AND `gre` <= 630.0 AND `gre` <= 670.0 AND `gre` <= 690.0 AND `rank3` <= 0.5 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          WHEN ((`gre` > 590.0 AND `gre` > 550.0 AND `gpa` > 3.495 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gpa` <= 3.57 AND `gre` <= 630.0 AND `gre` <= 670.0 AND `gre` <= 690.0 AND `rank3` <= 0.5 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('1')
          WHEN ((`gpa` > 3.57 AND `gre` > 590.0 AND `gre` > 550.0 AND `gpa` > 3.495 AND `gre` > 420.0 AND `gpa` > 3.115 AND `gre` <= 630.0 AND `gre` <= 670.0 AND `gre` <= 690.0 AND `rank3` <= 0.5 AND `rank4` <= 0.5 AND `rank1` <= 0.5)) THEN ('0')
          END")
[1] 400
dbGetQuery(con, "SELECT * FROM admit_score_tbl LIMIT 10")
   admit gre  gpa rank1 rank2 rank3 rank4 score
1      0 380 3.61     0     0     1     0     0
2      1 660 3.67     0     0     1     0     1
3      1 800 4.00     1     0     0     0     0
4      1 640 3.19     0     0     0     1     0
5      0 520 2.93     0     0     0     1     0
6      1 760 3.00     0     1     0     0     1
7      1 560 2.98     1     0     0     0     0
8      0 400 3.08     0     1     0     0     0
9      1 540 3.39     0     0     1     0     0
10     0 700 3.92     0     1     0     0     0

4.4 RF 예측모형 검증

배포된 모형 예측값과 R 환경 RF 예측값과 비교검증한다.

rf_resp_df <- predict(admit_rf, newdata = admit_xy_df) %>% 
    tbl_df %>% rename(rf_pred = value)

db_resp_df <- tbl(con, "admit_score_tbl") %>% 
    collect() %>% 
    select(db_pred = score)

bind_cols(rf_resp_df, db_resp_df) %>% 
    count(rf_pred, db_pred) %>% 
    spread(db_pred,n)
# A tibble: 2 x 3
  rf_pred   `0`   `1`
  <fct>   <int> <int>
1 0         273    81
2 1          43     3
tidypredict_test(admit_rf, admit_xy_df, threshold = 10)
tidypredict test results

Predictions that did not match predict(): 124