Packages Needed

library(tidymodels)
library(tidyverse)
library(baguette)
library(vip)
library(pdp)
library(here)
library(kernlab)
library(ggplot2)
library(earth)
retention <- read.csv('data/customer_retention.csv')
sum(is.na(retention))
## [1] 11

Cleaning up dataset:

retention <- retention %>%
  mutate(Status = factor(Status)) %>%
  na.omit 
sum(is.na(retention))
## [1] 0

We now have 0 null variables, and can go ahead with processing the data.

Machine Learning:

For our first model, we will look at logistic regression.

set.seed(123)
log_split <- initial_split(retention, prop = .7, strata = Status)
log_train <- training(log_split)
log_test <- testing(log_split)
set.seed(123)
log_kfolds <- vfold_cv(log_train, v = 5, strata = Status)
results <- logistic_reg() %>%
  fit_resamples(Status ~ ., log_kfolds)
## → A | warning: prediction from rank-deficient fit; attr(*, "non-estim") has doubtful cases
## 
There were issues with some computations   A: x1

There were issues with some computations   A: x2

There were issues with some computations   A: x4

There were issues with some computations   A: x5

There were issues with some computations   A: x5
collect_metrics(results)
## # A tibble: 2 × 6
##   .metric  .estimator  mean     n std_err .config             
##   <chr>    <chr>      <dbl> <int>   <dbl> <chr>               
## 1 accuracy binary     0.799     5 0.00401 Preprocessor1_Model1
## 2 roc_auc  binary     0.845     5 0.00521 Preprocessor1_Model1

We found an roc_auc value of .8448, which is good, but should be able to be improved.

final_fit <- logistic_reg() %>%
  fit(Status ~ ., data = log_train)
tidy(final_fit)
## # A tibble: 31 × 5
##    term                          estimate std.error statistic   p.value
##    <chr>                            <dbl>     <dbl>     <dbl>     <dbl>
##  1 (Intercept)                     1.02     0.969      1.05    2.95e- 1
##  2 GenderMale                     -0.0461   0.0779    -0.592   5.54e- 1
##  3 SeniorCitizen                   0.258    0.101      2.55    1.08e- 2
##  4 PartnerYes                     -0.141    0.0925    -1.52    1.29e- 1
##  5 DependentsYes                  -0.0475   0.108     -0.441   6.59e- 1
##  6 Tenure                         -0.0646   0.00762   -8.47    2.35e-17
##  7 PhoneServiceYes                -0.0417   0.774     -0.0539  9.57e- 1
##  8 MultipleLinesNo phone service  NA       NA         NA      NA       
##  9 MultipleLinesYes                0.442    0.211      2.10    3.56e- 2
## 10 InternetServiceFiber optic      1.48     0.950      1.56    1.18e- 1
## # ℹ 21 more rows
final_fit %>%
  predict(log_test) %>%
  bind_cols(log_test %>% select(Status)) %>%
  conf_mat(truth = Status, estimate = .pred_class)
## Warning in predict.lm(object, newdata, se.fit, scale = 1, type = if (type == :
## prediction from rank-deficient fit; attr(*, "non-estim") has doubtful cases
##           Truth
## Prediction Current Left
##    Current    1362  225
##    Left        178  332

We find that our model is usually predicting correctly, but we are experiencing some false positives.

Next up, we will assess a Mars Model

set.seed(123) # for reproducibility
mars_split <- initial_split(retention, prop = .7, strata = Status)
mars_train <- training(mars_split)
mars_test <- testing(mars_split)
mars_recipe <- recipe(Status ~ ., data = mars_train) %>%
  step_YeoJohnson(all_numeric_predictors()) %>%
  step_normalize(all_numeric_predictors())
set.seed(123)
kfolds <- vfold_cv(mars_train, v = 5, strata = Status)
mars_mod <- mars(num_terms = tune(), prod_degree = tune()) %>%
  set_mode('classification')
mars_grid <- grid_regular(num_terms(range = c(1,30)), prod_degree(), levels = 40)
mars_wf <- workflow() %>%
  add_recipe(mars_recipe) %>%
  add_model(mars_mod)
tuning_results <- mars_wf %>%
  tune_grid(resamples = kfolds, grid = mars_grid)
tuning_results %>%
  collect_metrics() %>%
  filter(.metric == "roc_auc") %>%
  arrange(desc(mean))
## # A tibble: 60 × 8
##    num_terms prod_degree .metric .estimator  mean     n std_err .config         
##        <int>       <int> <chr>   <chr>      <dbl> <int>   <dbl> <chr>           
##  1        15           1 roc_auc binary     0.850     5 0.00509 Preprocessor1_M…
##  2        16           1 roc_auc binary     0.849     5 0.00502 Preprocessor1_M…
##  3        18           1 roc_auc binary     0.849     5 0.00503 Preprocessor1_M…
##  4        19           1 roc_auc binary     0.849     5 0.00503 Preprocessor1_M…
##  5        20           1 roc_auc binary     0.849     5 0.00503 Preprocessor1_M…
##  6        21           1 roc_auc binary     0.849     5 0.00503 Preprocessor1_M…
##  7        22           1 roc_auc binary     0.849     5 0.00503 Preprocessor1_M…
##  8        23           1 roc_auc binary     0.849     5 0.00503 Preprocessor1_M…
##  9        24           1 roc_auc binary     0.849     5 0.00503 Preprocessor1_M…
## 10        25           1 roc_auc binary     0.849     5 0.00503 Preprocessor1_M…
## # ℹ 50 more rows

Here we find a max roc_auc of .8499, but we hope that we can still do better.

autoplot(tuning_results)

Next we will finalize our workflow object with the optimal hyperparameter values,

best_hyperparameters <- select_best(tuning_results, metric = "roc_auc")
final_wf <- workflow() %>%
  add_recipe(mars_recipe) %>%
  add_model(mars_mod) %>%
  finalize_workflow(best_hyperparameters)

Then we fit our final workflow object across the full training set data

final_fit <- final_wf %>%
  fit(data = mars_train)
final_fit %>%
  extract_fit_parsnip() %>%
  vip()

This model shows our most important features to be tenure, total charges, and payment method.

final_fit %>%
  predict(mars_test) %>%
  bind_cols(mars_test %>% select(Status)) %>%
  conf_mat(truth = Status, estimate = .pred_class)
##           Truth
## Prediction Current Left
##    Current    1382  245
##    Left        158  312

Decision Trees

dt_mod <- decision_tree(mode = 'classification') %>%
  set_engine("rpart")
model_recipe <- recipe(Status ~ ., data = log_train)
dt_fit <- workflow() %>%
  add_recipe(model_recipe) %>%
  add_model(dt_mod) %>%
  fit(data = log_train)
rpart.plot::rpart.plot(dt_fit$fit$fit$fit)
## Warning: Cannot retrieve the data used to build the model (so cannot determine roundint and is.binary for the variables).
## To silence this warning:
##     Call rpart.plot with roundint=FALSE,
##     or rebuild the rpart model with model=TRUE.

The root node of the decision tree is contract = 1 year or 2 years

set.seed(123)
kfold <- vfold_cv(log_train, v = 5)
dt_results <- fit_resamples(dt_mod, model_recipe, kfold)
collect_metrics(dt_results)
## # A tibble: 2 × 6
##   .metric  .estimator  mean     n std_err .config             
##   <chr>    <chr>      <dbl> <int>   <dbl> <chr>               
## 1 accuracy binary     0.785     5 0.00552 Preprocessor1_Model1
## 2 roc_auc  binary     0.803     5 0.00777 Preprocessor1_Model1

The decision tree gave us a roc_auc of .8033, which is not an optimal value. With further tuning, we can hope to create an even better model.

dt_mod <- decision_tree(
  mode = "classification",
  cost_complexity = tune(),
  tree_depth = tune(),
  min_n = tune()
  ) %>%
  set_engine("rpart")
dt_hyper_grid <- grid_regular(
  cost_complexity(),
  tree_depth(),
  min_n(),
  levels = 5
  )
set.seed(123)
dt_results <- tune_grid(dt_mod, model_recipe, resamples = kfold, grid = dt_hyper_grid)
show_best(dt_results, metric = "roc_auc", n = 5)
## # A tibble: 5 × 9
##   cost_complexity tree_depth min_n .metric .estimator  mean     n std_err
##             <dbl>      <int> <int> <chr>   <chr>      <dbl> <int>   <dbl>
## 1    0.0000000001         15    40 roc_auc binary     0.814     5 0.00780
## 2    0.0000000178         15    40 roc_auc binary     0.814     5 0.00780
## 3    0.00000316           15    40 roc_auc binary     0.814     5 0.00780
## 4    0.0000000001         11    40 roc_auc binary     0.814     5 0.00827
## 5    0.0000000178         11    40 roc_auc binary     0.814     5 0.00827
## # ℹ 1 more variable: .config <chr>

We now got the roc_auc up to .8142, which is better, but still not the optimal model.

dt_best_model <- select_best(dt_results, metric = 'roc_auc')
dt_final_wf <- workflow() %>%
  add_recipe(model_recipe) %>%
  add_model(dt_mod) %>%
  finalize_workflow(dt_best_model)
dt_final_fit <- dt_final_wf %>%
  fit(data = log_train)
dt_final_fit %>%
  extract_fit_parsnip() %>%
  vip(20)

We find that with decision trees, the most important features are tenure, contract, and total charges.

dt_final_fit %>%
   predict(log_test) %>%
   bind_cols(log_test %>% select(Status)) %>%
   conf_mat(truth = Status, estimate = .pred_class)
##           Truth
## Prediction Current Left
##    Current    1346  275
##    Left        194  282

Finally, we will look at a Random Forest

set.seed(123)
rf_split <- initial_split(retention, prop = 0.7, strata = Status)
rf_train <- training(rf_split)
rf_test <- testing(rf_split)

rf_recipe <- recipe(Status ~ ., data = rf_train)

rf_mod <- rand_forest(mode = "classification") %>%
  set_engine("ranger")

set.seed(123)
rf_kfold <- vfold_cv(rf_train, v = 5)

rf_results <- fit_resamples(rf_mod, rf_recipe, rf_kfold)
## Warning: package 'ranger' was built under R version 4.3.3
collect_metrics(rf_results)
## # A tibble: 2 × 6
##   .metric  .estimator  mean     n std_err .config             
##   <chr>    <chr>      <dbl> <int>   <dbl> <chr>               
## 1 accuracy binary     0.798     5 0.00509 Preprocessor1_Model1
## 2 roc_auc  binary     0.837     5 0.0103  Preprocessor1_Model1

This model gives us a roc_auc of .8368, but with hyperparameter tuning we hope to do even better.

rf_mod <- rand_forest(
  mode = "classification",
  trees = tune(),
  mtry = tune(),
  min_n = tune()) %>%
  set_engine("ranger", importance = "impurity")

rf_hyper_grid <- grid_regular(
  trees(range = c(50, 800)),
  mtry(range = c(2, 50)),
  min_n(range = c(1, 20)),
  levels = 5)

set.seed(123)
rf_results <- tune_grid(rf_mod, rf_recipe, resamples = rf_kfold, grid = rf_hyper_grid)
## → A | warning: 26 columns were requested but there were 19 predictors in the data. 19 will be used.
## 
There were issues with some computations   A: x1

There were issues with some computations   A: x2

There were issues with some computations   A: x3

There were issues with some computations   A: x4

There were issues with some computations   A: x5

                                                 
→ B | warning: 38 columns were requested but there were 19 predictors in the data. 19 will be used.
## There were issues with some computations   A: x5

There were issues with some computations   A: x5   B: x1

There were issues with some computations   A: x5   B: x2

There were issues with some computations   A: x5   B: x3

There were issues with some computations   A: x5   B: x4

There were issues with some computations   A: x5   B: x5

                                                         
→ C | warning: 50 columns were requested but there were 19 predictors in the data. 19 will be used.
## There were issues with some computations   A: x5   B: x5

There were issues with some computations   A: x5   B: x5   C: x1

There were issues with some computations   A: x5   B: x5   C: x2

There were issues with some computations   A: x5   B: x5   C: x3

There were issues with some computations   A: x5   B: x5   C: x4

There were issues with some computations   A: x5   B: x5   C: x5

There were issues with some computations   A: x6   B: x5   C: x5

There were issues with some computations   A: x7   B: x5   C: x5

There were issues with some computations   A: x8   B: x5   C: x5

There were issues with some computations   A: x9   B: x5   C: x5

There were issues with some computations   A: x10   B: x5   C: x5

There were issues with some computations   A: x10   B: x6   C: x5

There were issues with some computations   A: x10   B: x7   C: x5

There were issues with some computations   A: x10   B: x8   C: x5

There were issues with some computations   A: x10   B: x9   C: x5

There were issues with some computations   A: x10   B: x10   C: x5

There were issues with some computations   A: x10   B: x10   C: x6

There were issues with some computations   A: x10   B: x10   C: x7

There were issues with some computations   A: x10   B: x10   C: x8

There were issues with some computations   A: x10   B: x10   C: x9

There were issues with some computations   A: x10   B: x10   C: x10

There were issues with some computations   A: x11   B: x10   C: x10

There were issues with some computations   A: x12   B: x10   C: x10

There were issues with some computations   A: x13   B: x10   C: x10

There were issues with some computations   A: x14   B: x10   C: x10

There were issues with some computations   A: x15   B: x10   C: x10

There were issues with some computations   A: x15   B: x11   C: x10

There were issues with some computations   A: x15   B: x12   C: x10

There were issues with some computations   A: x15   B: x13   C: x10

There were issues with some computations   A: x15   B: x14   C: x10

There were issues with some computations   A: x15   B: x15   C: x10

There were issues with some computations   A: x15   B: x15   C: x11

There were issues with some computations   A: x15   B: x15   C: x12

There were issues with some computations   A: x15   B: x15   C: x13

There were issues with some computations   A: x15   B: x15   C: x14

There were issues with some computations   A: x15   B: x15   C: x15

There were issues with some computations   A: x16   B: x15   C: x15

There were issues with some computations   A: x17   B: x15   C: x15

There were issues with some computations   A: x18   B: x15   C: x15

There were issues with some computations   A: x19   B: x15   C: x15

There were issues with some computations   A: x20   B: x15   C: x15

There were issues with some computations   A: x20   B: x16   C: x15

There were issues with some computations   A: x20   B: x17   C: x15

There were issues with some computations   A: x20   B: x18   C: x15

There were issues with some computations   A: x20   B: x19   C: x15

There were issues with some computations   A: x20   B: x20   C: x15

There were issues with some computations   A: x20   B: x20   C: x16

There were issues with some computations   A: x20   B: x20   C: x17

There were issues with some computations   A: x20   B: x20   C: x18

There were issues with some computations   A: x20   B: x20   C: x19

There were issues with some computations   A: x20   B: x20   C: x20

There were issues with some computations   A: x21   B: x20   C: x20

There were issues with some computations   A: x22   B: x20   C: x20

There were issues with some computations   A: x23   B: x20   C: x20

There were issues with some computations   A: x24   B: x20   C: x20

There were issues with some computations   A: x25   B: x20   C: x20

There were issues with some computations   A: x25   B: x21   C: x20

There were issues with some computations   A: x25   B: x22   C: x20

There were issues with some computations   A: x25   B: x23   C: x20

There were issues with some computations   A: x25   B: x24   C: x20

There were issues with some computations   A: x25   B: x25   C: x20

There were issues with some computations   A: x25   B: x25   C: x21

There were issues with some computations   A: x25   B: x25   C: x22

There were issues with some computations   A: x25   B: x25   C: x23

There were issues with some computations   A: x25   B: x25   C: x24

There were issues with some computations   A: x25   B: x25   C: x25

There were issues with some computations   A: x26   B: x25   C: x25

There were issues with some computations   A: x27   B: x25   C: x25

There were issues with some computations   A: x28   B: x25   C: x25

There were issues with some computations   A: x29   B: x25   C: x25

There were issues with some computations   A: x30   B: x25   C: x25

There were issues with some computations   A: x30   B: x26   C: x25

There were issues with some computations   A: x30   B: x27   C: x25

There were issues with some computations   A: x30   B: x28   C: x25

There were issues with some computations   A: x30   B: x29   C: x25

There were issues with some computations   A: x30   B: x30   C: x25

There were issues with some computations   A: x30   B: x30   C: x26

There were issues with some computations   A: x30   B: x30   C: x27

There were issues with some computations   A: x30   B: x30   C: x28

There were issues with some computations   A: x30   B: x30   C: x29

There were issues with some computations   A: x30   B: x30   C: x30

There were issues with some computations   A: x31   B: x30   C: x30

There were issues with some computations   A: x32   B: x30   C: x30

There were issues with some computations   A: x33   B: x30   C: x30

There were issues with some computations   A: x34   B: x30   C: x30

There were issues with some computations   A: x35   B: x30   C: x30

There were issues with some computations   A: x35   B: x31   C: x30

There were issues with some computations   A: x35   B: x32   C: x30

There were issues with some computations   A: x35   B: x33   C: x30

There were issues with some computations   A: x35   B: x34   C: x30

There were issues with some computations   A: x35   B: x35   C: x30

There were issues with some computations   A: x35   B: x35   C: x31

There were issues with some computations   A: x35   B: x35   C: x32

There were issues with some computations   A: x35   B: x35   C: x33

There were issues with some computations   A: x35   B: x35   C: x34

There were issues with some computations   A: x35   B: x35   C: x35

There were issues with some computations   A: x36   B: x35   C: x35

There were issues with some computations   A: x37   B: x35   C: x35

There were issues with some computations   A: x38   B: x35   C: x35

There were issues with some computations   A: x39   B: x35   C: x35

There were issues with some computations   A: x40   B: x35   C: x35

There were issues with some computations   A: x40   B: x36   C: x35

There were issues with some computations   A: x40   B: x37   C: x35

There were issues with some computations   A: x40   B: x38   C: x35

There were issues with some computations   A: x40   B: x39   C: x35

There were issues with some computations   A: x40   B: x40   C: x35

There were issues with some computations   A: x40   B: x40   C: x36

There were issues with some computations   A: x40   B: x40   C: x37

There were issues with some computations   A: x40   B: x40   C: x38

There were issues with some computations   A: x40   B: x40   C: x39

There were issues with some computations   A: x40   B: x40   C: x40

There were issues with some computations   A: x41   B: x40   C: x40

There were issues with some computations   A: x42   B: x40   C: x40

There were issues with some computations   A: x43   B: x40   C: x40

There were issues with some computations   A: x44   B: x40   C: x40

There were issues with some computations   A: x45   B: x40   C: x40

There were issues with some computations   A: x45   B: x41   C: x40

There were issues with some computations   A: x45   B: x42   C: x40

There were issues with some computations   A: x45   B: x43   C: x40

There were issues with some computations   A: x45   B: x44   C: x40

There were issues with some computations   A: x45   B: x45   C: x40

There were issues with some computations   A: x45   B: x45   C: x41

There were issues with some computations   A: x45   B: x45   C: x42

There were issues with some computations   A: x45   B: x45   C: x43

There were issues with some computations   A: x45   B: x45   C: x44

There were issues with some computations   A: x45   B: x45   C: x45

There were issues with some computations   A: x46   B: x45   C: x45

There were issues with some computations   A: x47   B: x45   C: x45

There were issues with some computations   A: x48   B: x45   C: x45

There were issues with some computations   A: x49   B: x45   C: x45

There were issues with some computations   A: x50   B: x45   C: x45

There were issues with some computations   A: x50   B: x46   C: x45

There were issues with some computations   A: x50   B: x47   C: x45

There were issues with some computations   A: x50   B: x48   C: x45

There were issues with some computations   A: x50   B: x49   C: x45

There were issues with some computations   A: x50   B: x50   C: x45

There were issues with some computations   A: x50   B: x50   C: x46

There were issues with some computations   A: x50   B: x50   C: x47

There were issues with some computations   A: x50   B: x50   C: x48

There were issues with some computations   A: x50   B: x50   C: x49

There were issues with some computations   A: x50   B: x50   C: x50

There were issues with some computations   A: x51   B: x50   C: x50

There were issues with some computations   A: x52   B: x50   C: x50

There were issues with some computations   A: x53   B: x50   C: x50

There were issues with some computations   A: x54   B: x50   C: x50

There were issues with some computations   A: x55   B: x50   C: x50

There were issues with some computations   A: x55   B: x51   C: x50

There were issues with some computations   A: x55   B: x52   C: x50

There were issues with some computations   A: x55   B: x53   C: x50

There were issues with some computations   A: x55   B: x54   C: x50

There were issues with some computations   A: x55   B: x55   C: x50

There were issues with some computations   A: x55   B: x55   C: x51

There were issues with some computations   A: x55   B: x55   C: x52

There were issues with some computations   A: x55   B: x55   C: x53

There were issues with some computations   A: x55   B: x55   C: x54

There were issues with some computations   A: x55   B: x55   C: x55

There were issues with some computations   A: x56   B: x55   C: x55

There were issues with some computations   A: x57   B: x55   C: x55

There were issues with some computations   A: x58   B: x55   C: x55

There were issues with some computations   A: x59   B: x55   C: x55

There were issues with some computations   A: x60   B: x55   C: x55

There were issues with some computations   A: x60   B: x56   C: x55

There were issues with some computations   A: x60   B: x57   C: x55

There were issues with some computations   A: x60   B: x58   C: x55

There were issues with some computations   A: x60   B: x59   C: x55

There were issues with some computations   A: x60   B: x60   C: x55

There were issues with some computations   A: x60   B: x60   C: x56

There were issues with some computations   A: x60   B: x60   C: x57

There were issues with some computations   A: x60   B: x60   C: x58

There were issues with some computations   A: x60   B: x60   C: x59

There were issues with some computations   A: x60   B: x60   C: x60

There were issues with some computations   A: x61   B: x60   C: x60

There were issues with some computations   A: x62   B: x60   C: x60

There were issues with some computations   A: x63   B: x60   C: x60

There were issues with some computations   A: x64   B: x60   C: x60

There were issues with some computations   A: x65   B: x60   C: x60

There were issues with some computations   A: x65   B: x61   C: x60

There were issues with some computations   A: x65   B: x62   C: x60

There were issues with some computations   A: x65   B: x63   C: x60

There were issues with some computations   A: x65   B: x64   C: x60

There were issues with some computations   A: x65   B: x65   C: x60

There were issues with some computations   A: x65   B: x65   C: x61

There were issues with some computations   A: x65   B: x65   C: x62

There were issues with some computations   A: x65   B: x65   C: x63

There were issues with some computations   A: x65   B: x65   C: x64

There were issues with some computations   A: x65   B: x65   C: x65

There were issues with some computations   A: x66   B: x65   C: x65

There were issues with some computations   A: x67   B: x65   C: x65

There were issues with some computations   A: x68   B: x65   C: x65

There were issues with some computations   A: x69   B: x65   C: x65

There were issues with some computations   A: x70   B: x65   C: x65

There were issues with some computations   A: x70   B: x66   C: x65

There were issues with some computations   A: x70   B: x67   C: x65

There were issues with some computations   A: x70   B: x68   C: x65

There were issues with some computations   A: x70   B: x69   C: x65

There were issues with some computations   A: x70   B: x70   C: x65

There were issues with some computations   A: x70   B: x70   C: x66

There were issues with some computations   A: x70   B: x70   C: x67

There were issues with some computations   A: x70   B: x70   C: x68

There were issues with some computations   A: x70   B: x70   C: x69

There were issues with some computations   A: x70   B: x70   C: x70

There were issues with some computations   A: x71   B: x70   C: x70

There were issues with some computations   A: x72   B: x70   C: x70

There were issues with some computations   A: x73   B: x70   C: x70

There were issues with some computations   A: x74   B: x70   C: x70

There were issues with some computations   A: x75   B: x70   C: x70

There were issues with some computations   A: x75   B: x71   C: x70

There were issues with some computations   A: x75   B: x72   C: x70

There were issues with some computations   A: x75   B: x73   C: x70

There were issues with some computations   A: x75   B: x74   C: x70

There were issues with some computations   A: x75   B: x75   C: x70

There were issues with some computations   A: x75   B: x75   C: x71

There were issues with some computations   A: x75   B: x75   C: x72

There were issues with some computations   A: x75   B: x75   C: x73

There were issues with some computations   A: x75   B: x75   C: x74

There were issues with some computations   A: x75   B: x75   C: x75

There were issues with some computations   A: x76   B: x75   C: x75

There were issues with some computations   A: x77   B: x75   C: x75

There were issues with some computations   A: x78   B: x75   C: x75

There were issues with some computations   A: x79   B: x75   C: x75

There were issues with some computations   A: x80   B: x75   C: x75

There were issues with some computations   A: x80   B: x76   C: x75

There were issues with some computations   A: x80   B: x77   C: x75

There were issues with some computations   A: x80   B: x78   C: x75

There were issues with some computations   A: x80   B: x79   C: x75

There were issues with some computations   A: x80   B: x80   C: x75

There were issues with some computations   A: x80   B: x80   C: x76

There were issues with some computations   A: x80   B: x80   C: x77

There were issues with some computations   A: x80   B: x80   C: x78

There were issues with some computations   A: x80   B: x80   C: x79

There were issues with some computations   A: x80   B: x80   C: x80

There were issues with some computations   A: x81   B: x80   C: x80

There were issues with some computations   A: x82   B: x80   C: x80

There were issues with some computations   A: x83   B: x80   C: x80

There were issues with some computations   A: x84   B: x80   C: x80

There were issues with some computations   A: x85   B: x80   C: x80

There were issues with some computations   A: x85   B: x81   C: x80

There were issues with some computations   A: x85   B: x82   C: x80

There were issues with some computations   A: x85   B: x83   C: x80

There were issues with some computations   A: x85   B: x84   C: x80

There were issues with some computations   A: x85   B: x85   C: x80

There were issues with some computations   A: x85   B: x85   C: x81

There were issues with some computations   A: x85   B: x85   C: x82

There were issues with some computations   A: x85   B: x85   C: x83

There were issues with some computations   A: x85   B: x85   C: x84

There were issues with some computations   A: x85   B: x85   C: x85

There were issues with some computations   A: x86   B: x85   C: x85

There were issues with some computations   A: x87   B: x85   C: x85

There were issues with some computations   A: x88   B: x85   C: x85

There were issues with some computations   A: x89   B: x85   C: x85

There were issues with some computations   A: x90   B: x85   C: x85

There were issues with some computations   A: x90   B: x86   C: x85

There were issues with some computations   A: x90   B: x87   C: x85

There were issues with some computations   A: x90   B: x88   C: x85

There were issues with some computations   A: x90   B: x89   C: x85

There were issues with some computations   A: x90   B: x90   C: x85

There were issues with some computations   A: x90   B: x90   C: x86

There were issues with some computations   A: x90   B: x90   C: x87

There were issues with some computations   A: x90   B: x90   C: x88

There were issues with some computations   A: x90   B: x90   C: x89

There were issues with some computations   A: x90   B: x90   C: x90

There were issues with some computations   A: x91   B: x90   C: x90

There were issues with some computations   A: x92   B: x90   C: x90

There were issues with some computations   A: x93   B: x90   C: x90

There were issues with some computations   A: x94   B: x90   C: x90

There were issues with some computations   A: x95   B: x90   C: x90

There were issues with some computations   A: x95   B: x91   C: x90

There were issues with some computations   A: x95   B: x92   C: x90

There were issues with some computations   A: x95   B: x93   C: x90

There were issues with some computations   A: x95   B: x94   C: x90

There were issues with some computations   A: x95   B: x95   C: x90

There were issues with some computations   A: x95   B: x95   C: x91

There were issues with some computations   A: x95   B: x95   C: x92

There were issues with some computations   A: x95   B: x95   C: x93

There were issues with some computations   A: x95   B: x95   C: x94

There were issues with some computations   A: x95   B: x95   C: x95

There were issues with some computations   A: x96   B: x95   C: x95

There were issues with some computations   A: x97   B: x95   C: x95

There were issues with some computations   A: x98   B: x95   C: x95

There were issues with some computations   A: x99   B: x95   C: x95

There were issues with some computations   A: x100   B: x95   C: x95

There were issues with some computations   A: x100   B: x96   C: x95

There were issues with some computations   A: x100   B: x97   C: x95

There were issues with some computations   A: x100   B: x98   C: x95

There were issues with some computations   A: x100   B: x99   C: x95

There were issues with some computations   A: x100   B: x100   C: x95

There were issues with some computations   A: x100   B: x100   C: x96

There were issues with some computations   A: x100   B: x100   C: x97

There were issues with some computations   A: x100   B: x100   C: x98

There were issues with some computations   A: x100   B: x100   C: x99

There were issues with some computations   A: x100   B: x100   C: x100

There were issues with some computations   A: x101   B: x100   C: x100

There were issues with some computations   A: x102   B: x100   C: x100

There were issues with some computations   A: x103   B: x100   C: x100

There were issues with some computations   A: x104   B: x100   C: x100

There were issues with some computations   A: x105   B: x100   C: x100

There were issues with some computations   A: x105   B: x101   C: x100

There were issues with some computations   A: x105   B: x102   C: x100

There were issues with some computations   A: x105   B: x103   C: x100

There were issues with some computations   A: x105   B: x104   C: x100

There were issues with some computations   A: x105   B: x105   C: x100

There were issues with some computations   A: x105   B: x105   C: x101

There were issues with some computations   A: x105   B: x105   C: x102

There were issues with some computations   A: x105   B: x105   C: x103

There were issues with some computations   A: x105   B: x105   C: x104

There were issues with some computations   A: x105   B: x105   C: x105

There were issues with some computations   A: x106   B: x105   C: x105

There were issues with some computations   A: x107   B: x105   C: x105

There were issues with some computations   A: x108   B: x105   C: x105

There were issues with some computations   A: x109   B: x105   C: x105

There were issues with some computations   A: x110   B: x105   C: x105

There were issues with some computations   A: x110   B: x106   C: x105

There were issues with some computations   A: x110   B: x107   C: x105

There were issues with some computations   A: x110   B: x108   C: x105

There were issues with some computations   A: x110   B: x109   C: x105

There were issues with some computations   A: x110   B: x110   C: x105

There were issues with some computations   A: x110   B: x110   C: x106

There were issues with some computations   A: x110   B: x110   C: x107

There were issues with some computations   A: x110   B: x110   C: x108

There were issues with some computations   A: x110   B: x110   C: x109

There were issues with some computations   A: x110   B: x110   C: x110

There were issues with some computations   A: x111   B: x110   C: x110

There were issues with some computations   A: x112   B: x110   C: x110

There were issues with some computations   A: x113   B: x110   C: x110

There were issues with some computations   A: x114   B: x110   C: x110

There were issues with some computations   A: x115   B: x110   C: x110

There were issues with some computations   A: x115   B: x111   C: x110

There were issues with some computations   A: x115   B: x112   C: x110

There were issues with some computations   A: x115   B: x113   C: x110

There were issues with some computations   A: x115   B: x114   C: x110

There were issues with some computations   A: x115   B: x115   C: x110

There were issues with some computations   A: x115   B: x115   C: x111

There were issues with some computations   A: x115   B: x115   C: x112

There were issues with some computations   A: x115   B: x115   C: x113

There were issues with some computations   A: x115   B: x115   C: x114

There were issues with some computations   A: x115   B: x115   C: x115

There were issues with some computations   A: x116   B: x115   C: x115

There were issues with some computations   A: x117   B: x115   C: x115

There were issues with some computations   A: x118   B: x115   C: x115

There were issues with some computations   A: x119   B: x115   C: x115

There were issues with some computations   A: x120   B: x115   C: x115

There were issues with some computations   A: x120   B: x116   C: x115

There were issues with some computations   A: x120   B: x117   C: x115

There were issues with some computations   A: x120   B: x118   C: x115

There were issues with some computations   A: x120   B: x119   C: x115

There were issues with some computations   A: x120   B: x120   C: x115

There were issues with some computations   A: x120   B: x120   C: x116

There were issues with some computations   A: x120   B: x120   C: x117

There were issues with some computations   A: x120   B: x120   C: x118

There were issues with some computations   A: x120   B: x120   C: x119

There were issues with some computations   A: x120   B: x120   C: x120

There were issues with some computations   A: x121   B: x120   C: x120

There were issues with some computations   A: x122   B: x120   C: x120

There were issues with some computations   A: x123   B: x120   C: x120

There were issues with some computations   A: x124   B: x120   C: x120

There were issues with some computations   A: x125   B: x120   C: x120

There were issues with some computations   A: x125   B: x121   C: x120

There were issues with some computations   A: x125   B: x122   C: x120

There were issues with some computations   A: x125   B: x123   C: x120

There were issues with some computations   A: x125   B: x124   C: x120

There were issues with some computations   A: x125   B: x125   C: x120

There were issues with some computations   A: x125   B: x125   C: x121

There were issues with some computations   A: x125   B: x125   C: x122

There were issues with some computations   A: x125   B: x125   C: x123

There were issues with some computations   A: x125   B: x125   C: x124

There were issues with some computations   A: x125   B: x125   C: x125

There were issues with some computations   A: x125   B: x125   C: x125
show_best(rf_results, metric = "roc_auc")
## # A tibble: 5 × 9
##    mtry trees min_n .metric .estimator  mean     n std_err .config              
##   <int> <int> <int> <chr>   <chr>      <dbl> <int>   <dbl> <chr>                
## 1     2   612    20 roc_auc binary     0.844     5 0.0103  Preprocessor1_Model1…
## 2     2   800    20 roc_auc binary     0.843     5 0.0103  Preprocessor1_Model1…
## 3     2   425    15 roc_auc binary     0.843     5 0.00984 Preprocessor1_Model0…
## 4     2   425    20 roc_auc binary     0.843     5 0.0103  Preprocessor1_Model1…
## 5     2   237    20 roc_auc binary     0.843     5 0.0107  Preprocessor1_Model1…

With hyperparameter tuning, we get the roc_auc to .8435

  1. Use the hyperparameter values that provide the best results in #2 to finalize your workflow. Train this finalized workflow on the entire spam training data and identify the top 20 most influential predictors.
# get optimal hyperparameters
rf_best_hyperparameters <- select_best(rf_results, metric = "roc_auc")
# create final workflow object
final_rf_wf <- workflow() %>%
  add_recipe(rf_recipe) %>%
  add_model(rf_mod) %>%
  finalize_workflow(rf_best_hyperparameters)
# fit final workflow object
rf_final_fit <- final_rf_wf %>%
  fit(data = rf_train)
# plot feature importance
rf_final_fit %>%
  extract_fit_parsnip() %>%
  vip(num_features = 20)

With our random forest model, we find the most important features to be tenure, total charges, and contract

rf_final_fit %>%
   predict(rf_test) %>%
   bind_cols(rf_test %>% select(Status)) %>%
   conf_mat(truth = Status, estimate = .pred_class)
##           Truth
## Prediction Current Left
##    Current    1393  276
##    Left        147  281