{"metadata":{"kernelspec":{"name":"ir","display_name":"R","language":"R"},"language_info":{"name":"R","codemirror_mode":"r","pygments_lexer":"r","mimetype":"text/x-r-source","file_extension":".r","version":"4.0.5"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Basic Logit with Tidymodels\n\nA Tidymodels version of https://www.kaggle.com/code/igjit1/amex-basic-logit-with-feather-data .\n\nOriginal is https://www.kaggle.com/code/dkraynak/amex-basic-logit-with-feather-data by [@dkraynak](https://www.kaggle.com/dkraynak).","metadata":{}},{"cell_type":"code","source":"library(tidyverse)\nlibrary(tidymodels)\nlibrary(arrow)\nlibrary(tictoc)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:32:45.971842Z","iopub.execute_input":"2022-08-02T15:32:45.973849Z","iopub.status.idle":"2022-08-02T15:32:49.279716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Installation\n\nSet options to install binary packages. See https://docs.rstudio.com/rspm/admin/serving-binaries/","metadata":{}},{"cell_type":"code","source":"options(repos = \"https://packagemanager.rstudio.com/cran/__linux__/focal/latest\")\noptions(HTTPUserAgent = sprintf(\"R/%s R (%s)\", getRversion(), paste(getRversion(), R.version$platform, R.version$arch, R.version$os)))","metadata":{"_uuid":"051d70d956493feee0c6d64651c6a088724dca2a","_execution_state":"idle","execution":{"iopub.status.busy":"2022-08-02T15:32:49.282058Z","iopub.execute_input":"2022-08-02T15:32:49.330419Z","iopub.status.idle":"2022-08-02T15:32:49.345767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Install packages.","metadata":{}},{"cell_type":"code","source":"install.packages(\"duckdb\")","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:32:49.348020Z","iopub.execute_input":"2022-08-02T15:32:49.349366Z","iopub.status.idle":"2022-08-02T15:33:25.823400Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"remotes::install_github(\"igjit/amexmetric\", quiet = TRUE)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:33:25.825867Z","iopub.execute_input":"2022-08-02T15:33:25.827451Z","iopub.status.idle":"2022-08-02T15:33:45.228114Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Process and feature engineer","metadata":{}},{"cell_type":"code","source":"train_tbl <- arrow::read_parquet(\"../input/amex-data-integer-dtypes-parquet-format/train.parquet\", as_data_frame = FALSE)\ntrain_labels <- arrow::read_csv_arrow(\"../input/amex-default-prediction/train_labels.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:33:45.233290Z","iopub.execute_input":"2022-08-02T15:33:45.235475Z","iopub.status.idle":"2022-08-02T15:33:54.723454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I use DuckDB to make data processing fast.\nSee https://www.kaggle.com/code/igjit1/fast-and-less-memory-data-processing-with-duckdb","metadata":{}},{"cell_type":"code","source":"process_and_feature_engineer <- function(tbl) {\n  tbl %>%\n    to_duckdb %>%\n    select(1:10) %>%\n    group_by(customer_ID) %>%\n    slice_max(S_2) %>%\n    ungroup %>%\n    collect\n}","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:33:54.728146Z","iopub.execute_input":"2022-08-02T15:33:54.730158Z","iopub.status.idle":"2022-08-02T15:33:54.746507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tic()\n\ntrain_X <-\n  train_tbl %>%\n  process_and_feature_engineer\n\ntoc()","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:33:54.751122Z","iopub.execute_input":"2022-08-02T15:33:54.753152Z","iopub.status.idle":"2022-08-02T15:34:26.741028Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data <-\n  train_X %>%\n  left_join(train_labels, by = \"customer_ID\") %>%\n  mutate(target = relevel(as.factor(target), \"1\"))","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:34:26.744512Z","iopub.execute_input":"2022-08-02T15:34:26.746298Z","iopub.status.idle":"2022-08-02T15:34:28.998813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Make sure that first level of target is \"1\".\nFirst level of factor is the default objective of tidymodels.\nSee https://yardstick.tidymodels.org/dev/reference/roc_auc.html#relevant-level","metadata":{}},{"cell_type":"code","source":"train_data %>% pull(target) %>% levels","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:34:29.003138Z","iopub.execute_input":"2022-08-02T15:34:29.004938Z","iopub.status.idle":"2022-08-02T15:34:29.024148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"🚮","metadata":{}},{"cell_type":"code","source":"rm(train_tbl, train_labels, train_X)\ngc() %>% invisible","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:34:29.027096Z","iopub.execute_input":"2022-08-02T15:34:29.028535Z","iopub.status.idle":"2022-08-02T15:34:29.596798Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Build a model","metadata":{}},{"cell_type":"code","source":"logistic_spec <-\n  logistic_reg()","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:34:29.599336Z","iopub.execute_input":"2022-08-02T15:34:29.600746Z","iopub.status.idle":"2022-08-02T15:34:29.663929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"logistic_spec %>% translate","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:34:29.666523Z","iopub.execute_input":"2022-08-02T15:34:29.667925Z","iopub.status.idle":"2022-08-02T15:34:29.766774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preprocess data with recipes","metadata":{}},{"cell_type":"code","source":"logistic_recipe <-\n  recipe(target ~ P_2 + B_1 + B_2 + R_1 + D_39 + S_3, data = train_data) %>%\n  step_impute_median(all_numeric_predictors()) %>%\n  step_zv(all_predictors())","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:34:29.769149Z","iopub.execute_input":"2022-08-02T15:34:29.770544Z","iopub.status.idle":"2022-08-02T15:34:29.797774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"logistic_recipe %>% summary","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:34:29.800231Z","iopub.execute_input":"2022-08-02T15:34:29.801641Z","iopub.status.idle":"2022-08-02T15:34:29.826681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"logistic_workflow <-\n  workflow() %>%\n  add_recipe(logistic_recipe) %>%\n  add_model(logistic_spec)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:34:29.829231Z","iopub.execute_input":"2022-08-02T15:34:29.830715Z","iopub.status.idle":"2022-08-02T15:34:29.845270Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Evaluate model with resampling","metadata":{}},{"cell_type":"code","source":"set.seed(42)\nfolds <- vfold_cv(train_data, v = 5)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:34:29.847710Z","iopub.execute_input":"2022-08-02T15:34:29.849268Z","iopub.status.idle":"2022-08-02T15:34:30.161484Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"control <- control_resamples(verbose = TRUE, save_pred = TRUE)\n\ntic()\n\nfit_rs <- logistic_workflow %>%\n  fit_resamples(folds, control = control)\n\ntoc()","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:35:26.018837Z","iopub.execute_input":"2022-08-02T15:35:26.020404Z","iopub.status.idle":"2022-08-02T15:36:15.972140Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_amex <- function(df) amexmetric::amex_metric(df$target == \"1\", df$.pred_1)\n\namex_metrics <-\n  fit_rs %>%\n  mutate(amex = map_dbl(.predictions, df_amex)) %>%\n  select(id, amex)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:36:43.813989Z","iopub.execute_input":"2022-08-02T15:36:43.815896Z","iopub.status.idle":"2022-08-02T15:36:45.154994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"amex_metrics","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:36:51.041506Z","iopub.execute_input":"2022-08-02T15:36:51.043347Z","iopub.status.idle":"2022-08-02T15:36:51.065961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"amex_metrics %>% summarise(mean(amex))","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:37:01.319816Z","iopub.execute_input":"2022-08-02T15:37:01.321574Z","iopub.status.idle":"2022-08-02T15:37:01.343480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Fit","metadata":{}},{"cell_type":"code","source":"logistic_fit <-\n  logistic_workflow %>%\n  fit(train_data)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:38:12.256060Z","iopub.execute_input":"2022-08-02T15:38:12.258298Z","iopub.status.idle":"2022-08-02T15:38:23.520169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"logistic_fit %>% tidy","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:38:27.166719Z","iopub.execute_input":"2022-08-02T15:38:27.168240Z","iopub.status.idle":"2022-08-02T15:38:27.319571Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Prediction","metadata":{}},{"cell_type":"code","source":"test_tbl <- arrow::read_parquet(\"../input/amex-data-integer-dtypes-parquet-format/test.parquet\", as_data_frame = FALSE)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:38:48.844607Z","iopub.execute_input":"2022-08-02T15:38:48.846196Z","iopub.status.idle":"2022-08-02T15:39:08.556109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_data <-\n  test_tbl %>%\n  process_and_feature_engineer","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:39:10.410610Z","iopub.execute_input":"2022-08-02T15:39:10.412150Z","iopub.status.idle":"2022-08-02T15:40:10.049705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prediction <-\n  predict(logistic_fit, test_data, type = \"prob\") %>%\n  mutate(customer_ID = pull(test_data, customer_ID)) %>%\n  select(customer_ID, prediction = .pred_1)","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:40:28.889158Z","iopub.execute_input":"2022-08-02T15:40:28.890735Z","iopub.status.idle":"2022-08-02T15:40:29.789200Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prediction %>% head","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:40:44.495129Z","iopub.execute_input":"2022-08-02T15:40:44.496774Z","iopub.status.idle":"2022-08-02T15:40:45.274284Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prediction %>%\n  ggplot() +\n  aes(prediction) +\n  geom_histogram()","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:41:01.068815Z","iopub.execute_input":"2022-08-02T15:41:01.070706Z","iopub.status.idle":"2022-08-02T15:41:03.348885Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data.table::fwrite(prediction, \"submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-08-02T15:41:53.264523Z","iopub.execute_input":"2022-08-02T15:41:53.266196Z","iopub.status.idle":"2022-08-02T15:41:53.571543Z"},"trusted":true},"execution_count":null,"outputs":[]}]}