10 Steps to Create a Model, Tune it, and Predict
The 10 general steps are:
1. Generating training and testing data with initial_split(), training(), testing().
set.seed(987)
Split80=MyData |>
initial_split(prop=0.8, strata=OUTCOME_VARIABLE, breaks=5)
DataTrain=training(Split80)
DataTest=testing(Split80)
2. Create recipe to determine predictor and outcome variables. Optionally add one or more step_X() commands.
Recipe=recipe(<OUTCOME VARIABLE>~<PREDICTOR VARIABLE(S)>,
data=DataTrain) |>
step_<NAME OFSTEP>(<ARGUMENT(S) OFSTEP>)
3. Create model design and mark parameters to be tune() ed. without fit()
ModelDesign=<NAME OFML-COMMAND>(<ARGUMENT(S) OFCOMMAND>) |>
set_engine("<PACKAGE NAME>") |>
set_mode("<MODE>")
4. Create workflow by add_recipe() and add_model()
TuneWFModel=workflow() |>
add_recipe(Recipe) |>
add_model(ModelDesign)
5. Create a hyper-parameter grid containing the hyper-parameter combinations to be validated.
ParGrid=data.frame(<HYPER-PAR1>=c(<LIST OFVALUES>),
<HYPER-PAR2>=c(<LIST OFVALUES>), <ETC>)
ParGrid=data.frame(neighbors=c(1,3,6))
6. Create cross validation datasets (aka resamples) containing the folds (use commands vfold()).
FoldsForTuning=vfold_cv(DataTrain, v=10, strata=<OUTCOME VARIABLE>)
7. Tune the machine learning model with tune_grid() and track specific metrics defined by metric_set(). Runs all hyper-parameter combinations for all folds.
TuneResults=tune_grid(TuneWFModel, resamples=FoldsForTuning,
grid=ParGrid, metrics=metric_set(<LIST OFMETRICS>)),
control_grid(verbose=TRUE))
8. Extract the best hyper-parameter combination from the tuning results based on selected metrics (use select_best())
BestHyperPar=select_best(TuneResults, "<METRIC>")
9. Finalize the model by training it with the full set of training data with the best hyper-parameter combination (see finalize_workflow() %>% fit()).
BestWFModel=TuneWFModel |>
finalize_workflow(BestHyperPar) |>
fit(DataTrain)
10. Assessing predictive quality of the final model by using the testing dataset to predict (see augment() %>% metrics()).
DataTestWithPredBestModel=augment(BestWFModel, DataTest)
metrics(DataTestWithPredBestModel, truth=<OUTCOME VARIABLE>,
estimate=.pred)
Project: Tuning a K-Nearest Neighbors Model
Project Description
In Lecture 4, you developed a k-Nearest Neighbor model to predict the species of a penguin. We arbitrarily set k=4 to consider the four nearest neighbors.
Start by loading the required libraries and read the data
# A tibble: 10 × 3
Species BillLengthMm BodyMassG
<fct> <dbl> <int>
1 Adelie 39.1 3750
2 Adelie 39.5 3800
3 Adelie 40.3 3250
4 Adelie 36.7 3450
5 Adelie 39.3 3650
6 Adelie 38.9 3625
7 Adelie 39.2 4675
8 Adelie 34.1 3475
9 Adelie 42 4250
10 Adelie 37.8 3300
Step 1 - Generating Training and Testing Data
As before, we will use the penguin dataset and split the data into training (DataTrain) and testing (DataTest).
We will use the same seed (876) so the random split will be identical to the one we had with the k=4 model.
# A tibble: 6 × 3
Species BillLengthMm BodyMassG
<fct> <dbl> <int>
1 Adelie 40.3 3250
2 Adelie 36.7 3450
3 Adelie 39.3 3650
4 Adelie 38.9 3625
5 Adelie 39.2 4675
6 Adelie 42 4250
Step 2 - Create a Recipe
This is the same recipe as before. We will be dropping NAs and normalizing all predictor variables.
Step 3 - Create a Model Design
Use the appropriate ML model “knn”. Remember that we will not specify the number of neighbors, but we will use tune() placeholder
K-Nearest Neighbor Model Specification (classification)
Main Arguments:
neighbors = tune()
weight_func = rectangular
Computational engine: kknn
Step 4 - Add the Recipe and the Model Design to a Workflow
══ Workflow ════════════════════════════════════════════════════════════════════
Preprocessor: Recipe
Model: nearest_neighbor()
── Preprocessor ────────────────────────────────────────────────────────────────
2 Recipe Steps
• step_naomit()
• step_normalize()
── Model ───────────────────────────────────────────────────────────────────────
K-Nearest Neighbor Model Specification (classification)
Main Arguments:
neighbors = tune()
weight_func = rectangular
Computational engine: kknn
Step 5 - Create a Hyper-Parameter Grid
Later, when tuning is executed in Step 7, values reaching from 1 ??? 15 for the hyper-parameter neighbors shall be tried out.
You need to provide these values in a data frame column that is named the same as the hyper-parameter.
neighbors
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
12 12
13 13
14 14
15 15
Step 6 - Creating Resamples for Cross-Validation
The values you have created above for k (hyper-parameter neighbors) will be evaluated later using five folds (resamples). Each fold contains the complete training data, but different sections are used for training and assessment in each fold.
# 5-fold cross-validation using stratification
# A tibble: 5 × 2
splits id
<list> <chr>
1 <split [189/49]> Fold1
2 <split [190/48]> Fold2
3 <split [191/47]> Fold3
4 <split [191/47]> Fold4
5 <split [191/47]> Fold5
Step 7 - Tune the Workflow and Train All Models
Now it is time to run the tuning procedure using the tune_grid() command. Be patient because it will take some time to fully execute. Since we have to try out 15 parameters and use five folds for each model, the tune_grid() command has to fit 75 models (15x 5=75)
Step 9 - Finalize and Train the Best Workflow Model
The finalize_workflow() command will use the value from BestHyperPar to substitute the tune() placeholder in the R object TuneWFModel (created in Steps 2 ??? 4). The hyper-parameter is now set to neighbors=6 completing the workflow.
use the command fit(DataTrain) to calibrate the workflow to the training data and save the result into WFModelBest.
══ Workflow [trained] ══════════════════════════════════════════════════════════
Preprocessor: Recipe
Model: nearest_neighbor()
── Preprocessor ────────────────────────────────────────────────────────────────
2 Recipe Steps
• step_naomit()
• step_normalize()
── Model ───────────────────────────────────────────────────────────────────────
Call:
kknn::train.kknn(formula = ..y ~ ., data = data, ks = min_rows(6L, data, 5), kernel = ~"rectangular")
Type of response variable: nominal
Minimal misclassification: 0.06302521
Best kernel: rectangular
Best k: 6
Step 10 - Assess Prediction Quality Based on the Testing Data
Since WFModelBest is a fitted model, you can use it for predictions. In this last step, you will use the augment() command to predict Species. The augment() command will then add the prediction results as column .pred to the testing data.
Use the conf_mat() command to compare the predictions in column .pred to the true values to create a confusion matrix.
Truth
Prediction Adelie Chinstrap Gentoo
Adelie 41 1 1
Chinstrap 2 19 0
Gentoo 3 1 36