iris
데이터 작업흐름탐색적 데이터 분석에 대해서 모형개발에 필요한 전반적인 사항은 모두 파악한다. 여기서는 skimr
팩키지로 붓꽃데이터에 대한 모든 사항을 파악한 것으로 갈음한다.
library(tidyverse)
::skim(iris) skimr
Name | iris |
Number of rows | 150 |
Number of columns | 5 |
_______________________ | |
Column type frequency: | |
factor | 1 |
numeric | 4 |
________________________ | |
Group variables | None |
Variable type: factor
skim_variable | n_missing | complete_rate | ordered | n_unique | top_counts |
---|---|---|---|---|---|
Species | 0 | 1 | FALSE | 3 | set: 50, ver: 50, vir: 50 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
Sepal.Length | 0 | 1 | 5.84 | 0.83 | 4.3 | 5.1 | 5.80 | 6.4 | 7.9 | ▆▇▇▅▂ |
Sepal.Width | 0 | 1 | 3.06 | 0.44 | 2.0 | 2.8 | 3.00 | 3.3 | 4.4 | ▁▆▇▂▁ |
Petal.Length | 0 | 1 | 3.76 | 1.77 | 1.0 | 1.6 | 4.35 | 5.1 | 6.9 | ▇▁▆▇▂ |
Petal.Width | 0 | 1 | 1.20 | 0.76 | 0.1 | 0.3 | 1.30 | 1.8 | 2.5 | ▇▁▇▅▃ |
tidymodels
도구tidymodels
팩키지에 tidyverse
체계에서 예측모형을 구현하는 다양한 팩키지가 일괄적으로 포함되어 있다.
library(tidymodels)
기계학습 예측모형을 개발할 때 훈련/시험 데이터로 쪼개고 피쳐 공학(Feature Engineering)을 통해 Basetable을 다양한 기계학습 알고리즘에 적합시키도록 사전 정지작업을 수행한다.
가장 먼저 initial_split()
함수로 훈련/시험 데이터를 7:3 비율로 쪼갠다. 특히 층화(strata
)를 두어 7:3 비율이 정확히 유지되도록 지정한다. training()
, testing()
함수로 basetable 모형 데이터를 훈련/시험 데이터로 분리시킨다.
<- iris %>% as_tibble %>%
iris_tbl ::clean_names()
janitor
<- initial_split(iris_tbl, prop = 0.7, strata = species)
iris_split iris_split
<Analysis/Assess/Total>
<105/45/150>
<- training(iris_split)
train_iris <- testing(iris_split) test_iris
다음으로 recipes
팩키지를 사용해서 피쳐 공학 기법을 적용하여 다양한 기계학습 알고리즘을 적용시키도록 준비시킨다. ggplot
사용법에 익숙하신 분은 recipes
팩키지의 다양한 함수 사용법을 어려움 없이 사용할 수 있을 것이다.
recipe()
함수에 모형 공식을 작성하고, step_*
함수에 다양한 피처 공학 기법을 적용시켜 준비시킨다. 만약 피처공학된 결과를 보고자 한다면 iris_recipe %>% prep() %>% bake(new_data = train_iris)
명령어로 레서피에 정의된 결과를 파악할 수 있다.
<- recipe(species ~., data = train_iris) %>%
iris_recipe step_center(all_predictors(), -all_outcomes()) %>%
step_scale(all_predictors(), -all_outcomes()) %>%
step_zv(all_predictors()) %>%
prep()
summary(iris_recipe)
# A tibble: 5 x 4
variable type role source
<chr> <chr> <chr> <chr>
1 sepal_length numeric predictor original
2 sepal_width numeric predictor original
3 petal_length numeric predictor original
4 petal_width numeric predictor original
5 species nominal outcome original
iris_recipe
요리법을 그대로 시험 데이터에 적용시켜 나중에 예측모형 성능평가에 사용한다. 이때 사용되는 동사가 bake()
로 구워둔다.
<- iris_recipe %>%
iris_testdata prep() %>%
bake(new_data = test_iris)
glimpse(iris_testdata)
Rows: 45
Columns: 5
$ sepal_length <dbl> -0.9058716, -1.1398606, -0.2039047, -0.5548881, -0.905871…
$ sepal_width <dbl> 1.02642375, -0.13744767, 3.12139232, 0.79364947, 1.491972…
$ petal_length <dbl> -1.323235432, -1.323235432, -1.268056830, -1.157699626, -…
$ petal_width <dbl> -1.3178584, -1.3178584, -1.0575101, -1.3178584, -1.057510…
$ species <fct> setosa, setosa, setosa, setosa, setosa, setosa, setosa, s…
시험 데이터에 대한 전처리 및 피처 공학 적용이 완료되었다면, 다음 단계로 훈련 데이터에도 동일한 작업을 수행하는데 juice()
동사를 사용해서 해당 작업을 수행시키는데 이때 사용되는 요리법도 iris_recipe
가 된다.
prep()
, bake()
, juice()
동사로 중간중간 결과물을 파악한다.
juice(iris_recipe) %>%
head()
# A tibble: 6 x 5
sepal_length sepal_width petal_length petal_width species
<dbl> <dbl> <dbl> <dbl> <fct>
1 -1.37 0.328 -1.38 -1.32 setosa
2 -1.49 0.0953 -1.27 -1.32 setosa
3 -1.02 1.26 -1.32 -1.32 setosa
4 -0.555 1.96 -1.16 -1.06 setosa
5 -1.49 0.794 -1.32 -1.19 setosa
6 -1.02 0.794 -1.27 -1.32 setosa
Random Forest 모형의 경우 ranger
, randomForest
팩키지가 사실의 표준으로 학계와 산업계를 대표하고 있는데 인터페이스가 서로 달라 동일한 알고리즘임에도 불구하고 구문을 별도 작성해야 하는 어려움이 있는데 parsnip
이 이를 표준화했다. rand_forest()
으로 모형을 정의하고 set_engine()
에 팩키지명을 지정한다.
<- rand_forest(trees = 100) %>%
iris_ranger set_mode("classification") %>%
set_engine("ranger") # `ranger` 팩키지
# set_engine("randomForest") %>% # `randomForest` 팩키지
목적은 동일하지만 데이터 형태와 예측이냐 분류냐, 적용하고자 하는 예측모형에 따라 차이가 나더라도 workflows
를 사용하면 앞선 예측모형 적용과정을 매우 단순화할 수 있다.
library(workflows)
<-
iris_workflow workflow() %>%
add_model(iris_ranger) %>%
add_recipe(iris_recipe)
recipes
단계에서 모형공식은 지정했기 때문에 fit()
함수 내부에 이를 중복해서 지정할 필요는 없다.
<- iris_workflow %>%
iris_fit fit(data = train_iris)
iris_fit
══ Workflow [trained] ══════════════════════════════════════════════════════════
Preprocessor: Recipe
Model: rand_forest()
── Preprocessor ────────────────────────────────────────────────────────────────
3 Recipe Steps
● step_center()
● step_scale()
● step_zv()
── Model ───────────────────────────────────────────────────────────────────────
Ranger result
Call:
ranger::ranger(x = maybe_data_frame(x), y = y, num.trees = ~100, num.threads = 1, verbose = FALSE, seed = sample.int(10^5, 1), probability = TRUE)
Type: Probability estimation
Number of trees: 100
Sample size: 105
Number of independent variables: 4
Mtry: 2
Target node size: 10
Variable importance mode: none
Splitrule: gini
OOB prediction error (Brier s.): 0.03441589
예측모형에 대한 성능을 파악하려면 예측값을 생성되어야 한다. predict()
함수를 사용하게 되면 예측모형에 대한 예측값을 생성시킬 수 있는데 broom
팩키지와 마찬가지로 사용해서 bind_cols()
함수를 사용하게 되면 데이터프레임으로 후속 작업이 가능한 형태로 구현이 가능하다.
<- train_iris %>%
iris_pred bind_cols(iris_fit %>% predict(train_iris)) %>%
bind_cols(iris_fit %>% predict(train_iris, type = "prob"))
head(iris_pred)
# A tibble: 6 x 9
sepal_length sepal_width petal_length petal_width species .pred_class
<dbl> <dbl> <dbl> <dbl> <fct> <fct>
1 4.7 3.2 1.3 0.2 setosa setosa
2 4.6 3.1 1.5 0.2 setosa setosa
3 5 3.6 1.4 0.2 setosa setosa
4 5.4 3.9 1.7 0.4 setosa setosa
5 4.6 3.4 1.4 0.3 setosa setosa
6 5 3.4 1.5 0.2 setosa setosa
# … with 3 more variables: .pred_setosa <dbl>, .pred_versicolor <dbl>,
# .pred_virginica <dbl>
yardstic
팩키지 metrics()
함수를 사용해서 예측모형의 성능을 파악할 수 있다. 먼저, yardstick
팩키지 accuracy()
함수로 정확도를 파악한다.
%>%
iris_pred accuracy(truth = species, estimate = .pred_class)
# A tibble: 1 x 3
.metric .estimator .estimate
<chr> <chr> <dbl>
1 accuracy multiclass 0.981
conf_mat()
함수를 사용해서 혼동행렬(confusion matrix)을 계산할 수 있다.
%>%
iris_pred conf_mat(truth = species, estimate = .pred_class)
Truth
Prediction setosa versicolor virginica
setosa 35 0 0
versicolor 0 33 0
virginica 0 2 35
metrics()
함수를 사용하게 되면 특정 예측모형 측도를 지정하지 않고도 예측모형 성능에 대한 대략적인 정보를 획득할 수 있다.
%>%
iris_pred metrics(truth = species, estimate = .pred_class)
# A tibble: 2 x 3
.metric .estimator .estimate
<chr> <chr> <dbl>
1 accuracy multiclass 0.981
2 kap multiclass 0.971
iris
데이터는 3가지 품종을 꽃에 대한 4가지 측정정보를 바탕으로 예측하는 것이라 보통 정확도만을 따지지만, tidyverse
의 dplyr
, broom
을 사용한 경험이 있다면 각 범주별로 ROC, AUC를 계산하는 것도 수월하게 진행할 수 있다.
gain_curve()
, roc_curve()
함수를 사용해서 이득(Gain), ROC 곡선도 코드 한줄로 작성이 가능하다.
%>%
iris_pred # gain_curve(species, .pred_setosa:.pred_virginica) %>%
roc_curve(species, .pred_setosa:.pred_virginica) %>%
autoplot()
마지막으로 예측모형 성능평가만을 위해서 추출한 성능평가지표(metrics)만 추출하여 데이터프레임으로 제작하여 성능지표에 대한 마무리를 한다.
%>%
iris_pred metrics(species, .pred_setosa:.pred_virginica, estimate = .pred_class)
# A tibble: 4 x 3
.metric .estimator .estimate
<chr> <chr> <dbl>
1 accuracy multiclass 0.981
2 kap multiclass 0.971
3 mn_log_loss multiclass 0.0562
4 roc_auc hand_till 0.999
predict()
함수를 사용하게 되면 예측모형에 대한 예측값을 생성시킬 수 있는데 broom
팩키지와 마찬가지로 사용해서 bind_cols()
함수를 사용하게 되면 데이터프레임으로 후속 작업이 가능한 형태로 구현이 가능하다.
<- test_iris %>%
test_pred bind_cols(iris_fit %>% predict(test_iris)) %>%
bind_cols(iris_fit %>% predict(test_iris, type = "prob"))
test_pred
# A tibble: 45 x 9
sepal_length sepal_width petal_length petal_width species .pred_class
<dbl> <dbl> <dbl> <dbl> <fct> <fct>
1 5.1 3.5 1.4 0.2 setosa setosa
2 4.9 3 1.4 0.2 setosa setosa
3 5.7 4.4 1.5 0.4 setosa setosa
4 5.4 3.4 1.7 0.2 setosa setosa
5 5.1 3.7 1.5 0.4 setosa setosa
6 4.8 3.4 1.9 0.2 setosa setosa
7 5 3 1.6 0.2 setosa setosa
8 5 3.4 1.6 0.4 setosa setosa
9 5.2 3.4 1.4 0.2 setosa setosa
10 4.8 3.1 1.6 0.2 setosa setosa
# … with 35 more rows, and 3 more variables: .pred_setosa <dbl>,
# .pred_versicolor <dbl>, .pred_virginica <dbl>
yardstick
팩키지 accuracy()
함수로 시험데이터에 대한 정확도를 파악한다.
%>%
test_pred accuracy(truth = species, estimate = .pred_class)
# A tibble: 1 x 3
.metric .estimator .estimate
<chr> <chr> <dbl>
1 accuracy multiclass 0.978
conf_mat()
함수를 사용해서 혼동행렬(confusion matrix)을 계산할 수 있다.
%>%
test_pred conf_mat(truth = species, estimate = .pred_class)
Truth
Prediction setosa versicolor virginica
setosa 15 0 0
versicolor 0 15 1
virginica 0 0 14
데이터 과학자 이광춘 저작
kwangchun.lee.7@gmail.com