library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(tidyquant)
## Loading required package: PerformanceAnalytics
## Loading required package: xts
## Loading required package: zoo
##
## Attaching package: 'zoo'
##
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
##
##
## ######################### Warning from 'xts' package ##########################
## # #
## # The dplyr lag() function breaks how base R's lag() function is supposed to #
## # work, which breaks lag(my_xts). Calls to lag(my_xts) that you type or #
## # source() into this session won't work correctly. #
## # #
## # Use stats::lag() to make sure you're not using dplyr::lag(), or you can add #
## # conflictRules('dplyr', exclude = 'lag') to your .Rprofile to stop #
## # dplyr from breaking base R's lag() function. #
## # #
## # Code in packages is not affected. It's protected by R's namespace mechanism #
## # Set `options(xts.warn_dplyr_breaks_lag = FALSE)` to suppress this warning. #
## # #
## ###############################################################################
##
## Attaching package: 'xts'
##
## The following objects are masked from 'package:dplyr':
##
## first, last
##
##
## Attaching package: 'PerformanceAnalytics'
##
## The following object is masked from 'package:graphics':
##
## legend
##
## Loading required package: quantmod
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
library(correlationfunnel)
## ══ correlationfunnel Tip #2 ════════════════════════════════════════════════════
## Clean your NA's prior to using `binarize()`.
## Missing values and cleaning data are critical to getting great correlations. :)
departures <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2021/2021-04-27/departures.csv')
## Rows: 9423 Columns: 19
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (8): coname, exec_fullname, interim_coceo, still_there, notes, sources...
## dbl (10): dismissal_dataset_id, gvkey, fyear, co_per_rol, departure_code, c...
## dttm (1): leftofc
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
departures %>% skimr::skim()
Name | Piped data |
Number of rows | 9423 |
Number of columns | 19 |
_______________________ | |
Column type frequency: | |
character | 8 |
numeric | 10 |
POSIXct | 1 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
coname | 0 | 1.00 | 2 | 30 | 0 | 3860 | 0 |
exec_fullname | 0 | 1.00 | 5 | 790 | 0 | 8701 | 0 |
interim_coceo | 9105 | 0.03 | 6 | 7 | 0 | 6 | 0 |
still_there | 7311 | 0.22 | 3 | 10 | 0 | 77 | 0 |
notes | 1644 | 0.83 | 5 | 3117 | 0 | 7755 | 0 |
sources | 1475 | 0.84 | 18 | 1843 | 0 | 7915 | 0 |
eight_ks | 4499 | 0.52 | 69 | 3884 | 0 | 4914 | 0 |
_merge | 0 | 1.00 | 11 | 11 | 0 | 1 | 0 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
dismissal_dataset_id | 0 | 1.00 | 5684.10 | 25005.46 | 1 | 2305.5 | 4593 | 6812.5 | 559044 | ▇▁▁▁▁ |
gvkey | 0 | 1.00 | 40132.48 | 53921.34 | 1004 | 7337.0 | 14385 | 60900.5 | 328795 | ▇▁▁▁▁ |
fyear | 0 | 1.00 | 2007.74 | 8.19 | 1987 | 2000.0 | 2008 | 2016.0 | 2020 | ▁▆▅▅▇ |
co_per_rol | 0 | 1.00 | 25580.22 | 18202.38 | -1 | 8555.5 | 22980 | 39275.5 | 64602 | ▇▆▅▃▃ |
departure_code | 1667 | 0.82 | 5.20 | 1.53 | 1 | 5.0 | 5 | 7.0 | 9 | ▁▃▇▅▁ |
ceo_dismissal | 1813 | 0.81 | 0.20 | 0.40 | 0 | 0.0 | 0 | 0.0 | 1 | ▇▁▁▁▂ |
tenure_no_ceodb | 0 | 1.00 | 1.03 | 0.17 | 0 | 1.0 | 1 | 1.0 | 3 | ▁▇▁▁▁ |
max_tenure_ceodb | 0 | 1.00 | 1.05 | 0.24 | 1 | 1.0 | 1 | 1.0 | 4 | ▇▁▁▁▁ |
fyear_gone | 1802 | 0.81 | 2006.64 | 13.63 | 1980 | 2000.0 | 2007 | 2013.0 | 2997 | ▇▁▁▁▁ |
cik | 245 | 0.97 | 741469.17 | 486551.43 | 1750 | 106413.0 | 857323 | 1050375.8 | 1808065 | ▆▁▇▂▁ |
Variable type: POSIXct
skim_variable | n_missing | complete_rate | min | max | median | n_unique |
---|---|---|---|---|---|---|
leftofc | 1802 | 0.81 | 1981-01-01 | 2998-04-27 | 2006-12-31 | 3627 |
Goal: to find reasons for CEO departure in S&P 1500 firms from 2000 through 2018 with the use of classification model.
data <- departures %>%
# Clean ceo_dismissal
filter(!is.na(ceo_dismissal)) %>%
mutate(ceo_dismissal = if_else(ceo_dismissal == 1, "dismissed", "not dismissed")) %>%
# Drop variables with too many missing values
select(-interim_coceo, - still_there, - eight_ks) %>%
# Treat dismissal_dataset_id
mutate(dismissal_dataset_id = as.character(dismissal_dataset_id)) %>%
distinct(dismissal_dataset_id, .keep_all = TRUE) %>%
# Delete year of 2997 in fyear_geon
filter(fyear_gone < 2023) %>%
# Drop redundant variables
select(-departure_code, -fyear, -gvkey, - co_per_rol, - leftofc, - cik, - sources, - `_merge`) %>%
# Drop high cardinality predictors
select(-exec_fullname) %>%
#Convert to factor the variables with a few unique values
#mutate(across(tenure_no_ceodb:fyear_gone, factor)) %>%
# Convert to factor all character variables, except the string variable - notes
mutate(across(where(is.character), factor)) %>%
# Keep notes as character
mutate(notes = as.character(notes)) %>%
filter(!is.na(notes))
skimr::skim(data)
Name | data |
Number of rows | 7458 |
Number of columns | 7 |
_______________________ | |
Column type frequency: | |
character | 1 |
factor | 3 |
numeric | 3 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
notes | 0 | 1 | 5 | 3117 | 0 | 7448 | 0 |
Variable type: factor
skim_variable | n_missing | complete_rate | ordered | n_unique | top_counts |
---|---|---|---|---|---|
dismissal_dataset_id | 0 | 1 | FALSE | 7458 | 1: 1, 10: 1, 100: 1, 100: 1 |
coname | 0 | 1 | FALSE | 3427 | BAR: 8, CLA: 8, FED: 8, NTN: 8 |
ceo_dismissal | 0 | 1 | FALSE | 2 | not: 5976, dis: 1482 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
tenure_no_ceodb | 0 | 1 | 1.03 | 0.16 | 1 | 1 | 1 | 1 | 3 | ▇▁▁▁▁ |
max_tenure_ceodb | 0 | 1 | 1.05 | 0.23 | 1 | 1 | 1 | 1 | 4 | ▇▁▁▁▁ |
fyear_gone | 0 | 1 | 2006.40 | 7.50 | 1980 | 2000 | 2006 | 2013 | 2021 | ▁▂▇▇▆ |
factors_vec <- data %>% select(dismissal_dataset_id, ceo_dismissal, tenure_no_ceodb, max_tenure_ceodb, fyear_gone) %>% names()
data_clean <- data %>%
mutate(across(all_of(factors_vec), as.factor))
data_clean %>% count(dismissal_dataset_id, ceo_dismissal, tenure_no_ceodb, max_tenure_ceodb, fyear_gone)
## # A tibble: 7,458 × 6
## dismissal_dataset_id ceo_dismissal tenure_no_ceodb max_tenure_ceodb
## <fct> <fct> <fct> <fct>
## 1 1 not dismissed 1 1
## 2 10 not dismissed 1 1
## 3 100 dismissed 1 1
## 4 1000 not dismissed 1 1
## 5 1001 not dismissed 1 1
## 6 1002 not dismissed 1 1
## 7 1004 not dismissed 1 1
## 8 1005 not dismissed 1 1
## 9 1007 not dismissed 1 1
## 10 1008 dismissed 1 1
## # ℹ 7,448 more rows
## # ℹ 2 more variables: fyear_gone <fct>, n <int>
data_clean %>%
ggplot(aes(ceo_dismissal)) +
geom_bar()
data %>%
ggplot(aes(tenure_no_ceodb, fill = ceo_dismissal)) +
geom_bar(position = "fill") +
coord_flip() +
scale_fill_tq() +
labs(title = "Proportion of Dismissed CEOs by Tenure Number",
x = NULL, y = "Proportion", fill = NULL)
data %>%
ggplot(aes(max_tenure_ceodb, fill = ceo_dismissal)) +
geom_bar(position = "fill") +
coord_flip() +
scale_fill_tq() +
labs(title = "Proportion of Dismissed CEOs by Max Tenure Number",
x = NULL, y = "Proportion", fill = NULL)
data %>%
ggplot(aes(fyear_gone, fill = ceo_dismissal)) +
geom_bar(position = "fill") +
coord_flip() +
scale_fill_tq() +
labs(title = "Proportion of Dismissed CEOs by Companies",
x = NULL, y = "Proportion", fill = NULL)
data_binarized_tbl <- data_clean %>%
select(- dismissal_dataset_id, - notes) %>%
binarize()
data_binarized_tbl %>% glimpse()
## Rows: 7,458
## Columns: 38
## $ coname__BARRICK_GOLD_CORP <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ `coname__-OTHER` <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ ceo_dismissal__dismissed <dbl> 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,…
## $ ceo_dismissal__not_dismissed <dbl> 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1,…
## $ tenure_no_ceodb__1 <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ tenure_no_ceodb__2 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ `tenure_no_ceodb__-OTHER` <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ max_tenure_ceodb__1 <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ max_tenure_ceodb__2 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ `max_tenure_ceodb__-OTHER` <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__1993 <dbl> 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0,…
## $ fyear_gone__1994 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__1995 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,…
## $ fyear_gone__1996 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__1997 <dbl> 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__1998 <dbl> 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__1999 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2000 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2001 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1,…
## $ fyear_gone__2002 <dbl> 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2003 <dbl> 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2004 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2005 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2006 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2007 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,…
## $ fyear_gone__2008 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2009 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2010 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2011 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2012 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2013 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2014 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2015 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2016 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2017 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2018 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ fyear_gone__2019 <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ `fyear_gone__-OTHER` <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
# Step 2: Correlate
data_corr_tbl <- data_binarized_tbl %>%
correlate(ceo_dismissal__dismissed)
data_corr_tbl
## # A tibble: 38 × 3
## feature bin correlation
## <fct> <chr> <dbl>
## 1 ceo_dismissal dismissed 1
## 2 ceo_dismissal not_dismissed -1
## 3 max_tenure_ceodb 1 0.0577
## 4 max_tenure_ceodb 2 -0.0533
## 5 fyear_gone 1999 -0.0390
## 6 fyear_gone 2002 0.0378
## 7 fyear_gone 2003 0.0303
## 8 fyear_gone 2009 0.0292
## 9 fyear_gone 2008 0.0261
## 10 fyear_gone 1997 -0.0255
## # ℹ 28 more rows
# Step 3: Plot
data_corr_tbl %>%
plot_correlation_funnel()
## Warning: ggrepel: 28 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
library(tidymodels)
## ── Attaching packages ────────────────────────────────────── tidymodels 1.2.0 ──
## ✔ broom 1.0.6 ✔ rsample 1.2.1
## ✔ dials 1.3.0 ✔ tune 1.2.1
## ✔ infer 1.0.7 ✔ workflows 1.1.4
## ✔ modeldata 1.4.0 ✔ workflowsets 1.1.0
## ✔ parsnip 1.2.1 ✔ yardstick 1.3.1
## ✔ recipes 1.0.10
## ── Conflicts ───────────────────────────────────────── tidymodels_conflicts() ──
## ✖ scales::discard() masks purrr::discard()
## ✖ dplyr::filter() masks stats::filter()
## ✖ xts::first() masks dplyr::first()
## ✖ recipes::fixed() masks stringr::fixed()
## ✖ dplyr::lag() masks stats::lag()
## ✖ xts::last() masks dplyr::last()
## ✖ dials::momentum() masks TTR::momentum()
## ✖ yardstick::spec() masks readr::spec()
## ✖ recipes::step() masks stats::step()
## • Use suppressPackageStartupMessages() to eliminate package startup messages
set.seed(1234)
data_clean <- data_clean %>% sample_n(100)
departure_split <- initial_split(data, strata = ceo_dismissal)
departure_train <- training(departure_split)
departure_test <- testing(departure_split)
set.seed(2345)
departure_folds <- vfold_cv(departure_train, strata = ceo_dismissal)
departure_folds
## # 10-fold cross-validation using stratification
## # A tibble: 10 × 2
## splits id
## <list> <chr>
## 1 <split [5032/561]> Fold01
## 2 <split [5033/560]> Fold02
## 3 <split [5034/559]> Fold03
## 4 <split [5034/559]> Fold04
## 5 <split [5034/559]> Fold05
## 6 <split [5034/559]> Fold06
## 7 <split [5034/559]> Fold07
## 8 <split [5034/559]> Fold08
## 9 <split [5034/559]> Fold09
## 10 <split [5034/559]> Fold10
library(embed)
library(textrecipes)
departures_rec <-
recipe(ceo_dismissal ~ ., data = departure_train) %>%
update_role(dismissal_dataset_id, new_role = "id") %>%
step_tokenize(notes) %>%
step_tokenfilter(notes, max_tokens = 100) %>%
step_tfidf(notes) %>%
step_other(coname) %>%
step_dummy(all_nominal_predictors()) %>%
step_normalize(all_numeric_predictors())
departures_rec %>% prep() %>% juice() %>% glimpse()
## Rows: 5,593
## Columns: 106
## $ dismissal_dataset_id <fct> 85, 119, 198, 243, 244, 263, 280, 346, 348, 36…
## $ tenure_no_ceodb <dbl> -0.1548142, -0.1548142, -0.1548142, -0.1548142…
## $ max_tenure_ceodb <dbl> -0.2094581, -0.2094581, -0.2094581, -0.2094581…
## $ fyear_gone <dbl> -1.12184755, -1.38925691, -1.12184755, -1.7903…
## $ ceo_dismissal <fct> dismissed, dismissed, dismissed, dismissed, di…
## $ tfidf_notes_1 <dbl> -0.2950765, -0.2950765, -0.2950765, -0.2950765…
## $ tfidf_notes_1997 <dbl> 6.516187, -0.201052, -0.201052, -0.201052, -0.…
## $ tfidf_notes_1998 <dbl> 6.7479775, -0.2043864, -0.2043864, -0.2043864,…
## $ tfidf_notes_1999 <dbl> -0.2136374, -0.2136374, -0.2136374, -0.2136374…
## $ tfidf_notes_a <dbl> 0.72883491, -0.75969150, 0.01115253, -0.759691…
## $ tfidf_notes_acquisition <dbl> -0.2065473, -0.2065473, -0.2065473, -0.2065473…
## $ tfidf_notes_after <dbl> -0.331960658, -0.331960658, -0.331960658, -0.3…
## $ tfidf_notes_agreement <dbl> -0.2331309, -0.2331309, -0.2331309, -0.2331309…
## $ tfidf_notes_also <dbl> -0.2788685, -0.2788685, 3.4235436, -0.2788685,…
## $ tfidf_notes_an <dbl> -0.352248, -0.352248, -0.352248, -0.352248, -0…
## $ tfidf_notes_and <dbl> 2.5622769, 1.1387855, -0.4189976, -0.1074410, …
## $ tfidf_notes_announced <dbl> -0.4369369, -0.4369369, -0.4369369, -0.4369369…
## $ tfidf_notes_april <dbl> -0.2129577, -0.2129577, -0.2129577, -0.2129577…
## $ tfidf_notes_as <dbl> 0.86786744, -0.90923362, 0.01105086, 0.3791646…
## $ tfidf_notes_at <dbl> -0.3534639, -0.3534639, -0.3534639, -0.3534639…
## $ tfidf_notes_based <dbl> -0.2398946, -0.2398946, -0.2398946, -0.2398946…
## $ tfidf_notes_be <dbl> -0.3088754, -0.3088754, -0.3088754, -0.3088754…
## $ tfidf_notes_been <dbl> -0.3336100, 2.3193863, -0.3336100, -0.3336100,…
## $ tfidf_notes_billion <dbl> -0.2349982, -0.2349982, -0.2349982, -0.2349982…
## $ tfidf_notes_board <dbl> -0.6448506, -0.6448506, 0.7543015, 1.3139623, …
## $ tfidf_notes_business <dbl> -0.1951818, -0.1951818, -0.1951818, -0.1951818…
## $ tfidf_notes_but <dbl> 2.4489029, -0.2346642, -0.2346642, -0.2346642,…
## $ tfidf_notes_by <dbl> 0.9123051, -0.3493111, 0.9573628, 1.4800323, 1…
## $ tfidf_notes_ceo <dbl> 0.28400019, 0.31643114, 0.31643114, -0.6240664…
## $ tfidf_notes_chairman <dbl> 0.48549130, -0.67386705, 1.72766097, -0.673867…
## $ tfidf_notes_chief <dbl> -0.71538569, 0.66198325, 0.66198325, 1.2129308…
## $ tfidf_notes_co <dbl> -0.2443545, -0.2443545, -0.2443545, -0.2443545…
## $ tfidf_notes_company <dbl> 0.16692423, -0.73064103, 0.19898013, -0.730641…
## $ `tfidf_notes_company's` <dbl> -0.2872096, -0.2872096, -0.2872096, -0.2872096…
## $ tfidf_notes_corp <dbl> -0.2696092, -0.2696092, -0.2696092, -0.2696092…
## $ tfidf_notes_corporation <dbl> -0.2761885, -0.2761885, -0.2761885, -0.2761885…
## $ tfidf_notes_december <dbl> -0.2231103, -0.2231103, -0.2231103, -0.2231103…
## $ tfidf_notes_director <dbl> -0.2867851, -0.2867851, -0.2867851, -0.2867851…
## $ tfidf_notes_directors <dbl> -0.4256755, -0.4256755, -0.4256755, -0.4256755…
## $ tfidf_notes_down <dbl> -0.3217453, -0.3217453, -0.3217453, -0.3217453…
## $ tfidf_notes_effective <dbl> -0.3512119, -0.3512119, -0.3512119, -0.3512119…
## $ tfidf_notes_executive <dbl> -0.7594792, 0.5492902, 0.5492902, 1.0727980, -…
## $ tfidf_notes_financial <dbl> -0.2100234, -0.2100234, -0.2100234, -0.2100234…
## $ tfidf_notes_for <dbl> -0.4940311, 0.6318143, -0.4940311, 1.0821525, …
## $ tfidf_notes_from <dbl> -0.5094769, -0.5094769, 0.6420242, -0.5094769,…
## $ tfidf_notes_group <dbl> -0.1939352, -0.1939352, -0.1939352, -0.1939352…
## $ tfidf_notes_had <dbl> -0.3068995, 2.3130662, -0.3068995, -0.3068995,…
## $ tfidf_notes_has <dbl> -0.4899052, -0.4899052, -0.4899052, -0.4899052…
## $ tfidf_notes_have <dbl> -0.215825, -0.215825, -0.215825, 5.682400, -0.…
## $ tfidf_notes_he <dbl> -0.55561285, 0.44534401, -0.55561285, 0.845726…
## $ tfidf_notes_his <dbl> -0.5094355, -0.5094355, -0.5094355, 1.2057966,…
## $ tfidf_notes_in <dbl> -0.034599664, -0.008215556, -0.773354696, 1.36…
## $ tfidf_notes_inc <dbl> 0.97875511, -0.48128939, -0.48128939, -0.48128…
## $ tfidf_notes_into <dbl> -0.2073987, -0.2073987, -0.2073987, -0.2073987…
## $ tfidf_notes_is <dbl> -0.4026739, -0.4026739, 1.2314764, -0.4026739,…
## $ tfidf_notes_it <dbl> -0.3720018, -0.3720018, -0.3720018, -0.3720018…
## $ tfidf_notes_its <dbl> 1.4310791, -0.4171896, 1.4970887, 2.2628000, -…
## $ tfidf_notes_january <dbl> 3.0373057, -0.2464586, -0.2464586, -0.2464586,…
## $ tfidf_notes_july <dbl> -0.2307749, -0.2307749, -0.2307749, -0.2307749…
## $ tfidf_notes_june <dbl> -0.1958329, -0.1958329, -0.1958329, -0.1958329…
## $ tfidf_notes_march <dbl> -0.2169344, 3.0273821, -0.2169344, -0.2169344,…
## $ tfidf_notes_may <dbl> -0.2493137, -0.2493137, -0.2493137, -0.2493137…
## $ tfidf_notes_member <dbl> -0.2313919, -0.2313919, -0.2313919, -0.2313919…
## $ tfidf_notes_merger <dbl> -0.2149803, -0.2149803, 1.8601565, -0.2149803,…
## $ tfidf_notes_million <dbl> -0.2686936, 4.7614203, -0.2686936, -0.2686936,…
## $ tfidf_notes_more <dbl> -0.2123602, -0.2123602, -0.2123602, -0.2123602…
## $ tfidf_notes_mr <dbl> -0.5045803, -0.5045803, -0.5045803, -0.5045803…
## $ tfidf_notes_named <dbl> -0.2162119, -0.2162119, 2.9053015, -0.2162119,…
## $ tfidf_notes_new <dbl> 2.1897731, -0.2973036, -0.2973036, -0.2973036,…
## $ tfidf_notes_not <dbl> -0.1851140, -0.1851140, -0.1851140, -0.1851140…
## $ tfidf_notes_of <dbl> -1.23970661, 0.64360373, -1.23970661, -1.23970…
## $ tfidf_notes_officer <dbl> -0.6319247, 0.8700193, -0.6319247, -0.6319247,…
## $ tfidf_notes_on <dbl> 0.6306030, 1.8497044, -0.5072250, -0.5072250, …
## $ tfidf_notes_operating <dbl> -0.2381417, -0.2381417, -0.2381417, -0.2381417…
## $ tfidf_notes_over <dbl> -0.1667148, -0.1667148, -0.1667148, -0.1667148…
## $ tfidf_notes_position <dbl> -0.2937833, -0.2937833, -0.2937833, -0.2937833…
## $ tfidf_notes_president <dbl> 0.8420980, 2.3999264, -0.6118752, -0.6118752, …
## $ tfidf_notes_resigned <dbl> -0.2608318, 1.5432959, -0.2608318, -0.2608318,…
## $ tfidf_notes_retire <dbl> -0.2764948, -0.2764948, -0.2764948, -0.2764948…
## $ tfidf_notes_retired <dbl> -0.2671846, -0.2671846, -0.2671846, -0.2671846…
## $ tfidf_notes_retirement <dbl> -0.2066755, -0.2066755, -0.2066755, -0.2066755…
## $ tfidf_notes_role <dbl> -0.2586828, -0.2586828, -0.2586828, -0.2586828…
## $ tfidf_notes_said <dbl> -0.329281, -0.329281, 2.204141, -0.329281, -0.…
## $ tfidf_notes_served <dbl> -0.3114722, -0.3114722, -0.3114722, -0.3114722…
## $ tfidf_notes_share <dbl> -0.2007568, -0.2007568, -0.2007568, -0.2007568…
## $ tfidf_notes_since <dbl> -0.3457923, 4.8290118, -0.3457923, -0.3457923,…
## $ tfidf_notes_stepped <dbl> -0.2053318, -0.2053318, -0.2053318, -0.2053318…
## $ tfidf_notes_stock <dbl> -0.2519306, -0.2519306, -0.2519306, -0.2519306…
## $ tfidf_notes_that <dbl> -0.5640468, -0.5640468, -0.5640468, 3.4892569,…
## $ tfidf_notes_the <dbl> -0.990959727, -0.971061238, 0.760107288, 0.875…
## $ tfidf_notes_this <dbl> -0.2591261, -0.2591261, -0.2591261, -0.2591261…
## $ tfidf_notes_time <dbl> -0.2593110, -0.2593110, -0.2593110, -0.2593110…
## $ tfidf_notes_to <dbl> 0.49119169, -0.80877209, -0.80877209, 0.133701…
## $ tfidf_notes_today <dbl> -0.3032347, -0.3032347, -0.3032347, -0.3032347…
## $ tfidf_notes_until <dbl> -0.3043194, -0.3043194, -0.3043194, -0.3043194…
## $ tfidf_notes_vice <dbl> -0.2383916, -0.2383916, 3.6132587, -0.2383916,…
## $ tfidf_notes_was <dbl> -0.5861012, -0.5861012, 1.0919530, 0.5885367, …
## $ tfidf_notes_when <dbl> -0.2647481, -0.2647481, -0.2647481, -0.2647481…
## $ tfidf_notes_which <dbl> -0.2871059, 2.8594839, -0.2871059, -0.2871059,…
## $ tfidf_notes_who <dbl> -0.2989841, -0.2989841, 2.0182935, -0.2989841,…
## $ tfidf_notes_will <dbl> -0.4906758, -0.4906758, 0.8880736, -0.4906758,…
## $ tfidf_notes_with <dbl> -0.42325915, 0.79543980, 0.79543980, -0.423259…
## $ tfidf_notes_would <dbl> -0.2073076, -0.2073076, -0.2073076, -0.2073076…
## $ tfidf_notes_year <dbl> -0.3219871, -0.3219871, -0.3219871, -0.3219871…
## $ tfidf_notes_years <dbl> 1.1705187, -0.2904182, -0.2904182, -0.2904182,…
## $ coname_other <dbl> 0.03784379, 0.03784379, 0.03784379, 0.03784379…
library(usemodels)
usemodels::use_xgboost(ceo_dismissal ~ ., data = departure_train)
## xgboost_recipe <-
## recipe(formula = ceo_dismissal ~ ., data = departure_train) %>%
## step_zv(all_predictors())
##
## xgboost_spec <-
## boost_tree(trees = tune(), min_n = tune(), tree_depth = tune(), learn_rate = tune(),
## loss_reduction = tune(), sample_size = tune()) %>%
## set_mode("classification") %>%
## set_engine("xgboost")
##
## xgboost_workflow <-
## workflow() %>%
## add_recipe(xgboost_recipe) %>%
## add_model(xgboost_spec)
##
## set.seed(44593)
## xgboost_tune <-
## tune_grid(xgboost_workflow, resamples = stop("add your rsample object"), grid = stop("add number of candidate points"))
xgboost_recipe <-
recipe(formula = ceo_dismissal ~ ., data = departure_train) %>%
step_tokenfilter(ceo_dismissal, max_tokens = 100) %>%
step_zv(all_predictors())
xgboost_spec <-
boost_tree(trees = tune(), min_n = tune(), tree_depth = tune(), learn_rate = tune(),
loss_reduction = tune(), sample_size = tune()) %>%
set_mode("classification") %>%
set_engine("xgboost")
xgboost_workflow <-
workflow() %>%
add_recipe(xgboost_recipe) %>%
add_model(xgboost_spec)
prep(departures_rec) %>%
tidy(number = 1)
## # A tibble: 1 × 3
## terms value id
## <chr> <chr> <chr>
## 1 notes words tokenize_YToSK
xgb_spec <-
boost_tree(
trees = tune(),
min_n = tune(),
mtry = tune(),
learn_rate = 0.01
) %>%
set_engine("xgboost") %>%
set_mode("classification")
xgb_wf <- workflow(departures_rec, xgb_spec)
library(finetune)
tree_grid <- grid_regular(trees(),
tree_depth(),
levels = 5)
doParallel::registerDoParallel()
set.seed(94354)
xgb_rs <- tune_grid(
xgb_wf,
resamples = departure_folds,
grid = 5,
control = control_grid(verbose = TRUE, save_pred = TRUE)
)
## i Creating pre-processing data to finalize unknown parameter: mtry
xgb_rs
## # Tuning results
## # 10-fold cross-validation using stratification
## # A tibble: 10 × 5
## splits id .metrics .notes .predictions
## <list> <chr> <list> <list> <list>
## 1 <split [5032/561]> Fold01 <tibble [15 × 7]> <tibble [0 × 3]> <tibble>
## 2 <split [5033/560]> Fold02 <tibble [15 × 7]> <tibble [0 × 3]> <tibble>
## 3 <split [5034/559]> Fold03 <tibble [15 × 7]> <tibble [0 × 3]> <tibble>
## 4 <split [5034/559]> Fold04 <tibble [15 × 7]> <tibble [0 × 3]> <tibble>
## 5 <split [5034/559]> Fold05 <tibble [15 × 7]> <tibble [0 × 3]> <tibble>
## 6 <split [5034/559]> Fold06 <tibble [15 × 7]> <tibble [0 × 3]> <tibble>
## 7 <split [5034/559]> Fold07 <tibble [15 × 7]> <tibble [0 × 3]> <tibble>
## 8 <split [5034/559]> Fold08 <tibble [15 × 7]> <tibble [0 × 3]> <tibble>
## 9 <split [5034/559]> Fold09 <tibble [15 × 7]> <tibble [0 × 3]> <tibble>
## 10 <split [5034/559]> Fold10 <tibble [15 × 7]> <tibble [0 × 3]> <tibble>
collect_metrics(xgb_rs)
## # A tibble: 15 × 9
## mtry trees min_n .metric .estimator mean n std_err .config
## <int> <int> <int> <chr> <chr> <dbl> <int> <dbl> <chr>
## 1 18 1266 16 accuracy binary 0.846 10 0.00159 Preprocessor1_…
## 2 18 1266 16 brier_class binary 0.110 10 0.000893 Preprocessor1_…
## 3 18 1266 16 roc_auc binary 0.861 10 0.00376 Preprocessor1_…
## 4 32 637 32 accuracy binary 0.832 10 0.00153 Preprocessor1_…
## 5 32 637 32 brier_class binary 0.115 10 0.000949 Preprocessor1_…
## 6 32 637 32 roc_auc binary 0.851 10 0.00468 Preprocessor1_…
## 7 59 1023 23 accuracy binary 0.841 10 0.00196 Preprocessor1_…
## 8 59 1023 23 brier_class binary 0.112 10 0.000924 Preprocessor1_…
## 9 59 1023 23 roc_auc binary 0.859 10 0.00418 Preprocessor1_…
## 10 71 1885 8 accuracy binary 0.845 10 0.00235 Preprocessor1_…
## 11 71 1885 8 brier_class binary 0.109 10 0.00101 Preprocessor1_…
## 12 71 1885 8 roc_auc binary 0.862 10 0.00358 Preprocessor1_…
## 13 91 242 36 accuracy binary 0.815 10 0.00192 Preprocessor1_…
## 14 91 242 36 brier_class binary 0.128 10 0.000886 Preprocessor1_…
## 15 91 242 36 roc_auc binary 0.825 10 0.00560 Preprocessor1_…
xgb_last <- xgb_wf %>%
finalize_workflow(select_best(xgb_rs, metric = "accuracy")) %>%
last_fit(departure_split)
xgb_last
## # Resampling results
## # Manual resampling
## # A tibble: 1 × 6
## splits id .metrics .notes .predictions .workflow
## <list> <chr> <list> <list> <list> <list>
## 1 <split [5593/1865]> train/test split <tibble> <tibble> <tibble> <workflow>
collect_metrics(xgb_last)
## # A tibble: 3 × 4
## .metric .estimator .estimate .config
## <chr> <chr> <dbl> <chr>
## 1 accuracy binary 0.839 Preprocessor1_Model1
## 2 roc_auc binary 0.851 Preprocessor1_Model1
## 3 brier_class binary 0.114 Preprocessor1_Model1
collect_predictions(xgb_last) %>%
conf_mat(ceo_dismissal, .pred_class) %>%
autoplot()
library(vip)
##
## Attaching package: 'vip'
## The following object is masked from 'package:utils':
##
## vi
xgb_last %>%
extract_fit_engine() %>%
vip()
The previous model had an accuracy of 0.839 and a AUC of 0.851
Feature Transformation: normalize numeric data. It resulted in : NO IMPROVEMENT
Feature Transformation: NO IMPROVEMENT
Feature Transformation: NO IMPROVEMENT