--- title: "An End-to-End MFF Workflow" author: "Nihat Tak and Sadık Çoban" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{An End-to-End MFF Workflow} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 7, fig.height = 4 ) ``` ## Overview The MFF package combines candidate regression predictions using weights obtained from clustering the candidates' validation prediction profiles. Candidate models may be fitted with `model.train()`, generated by bootstrap resampling with `boot.train()`, or trained externally. In every case, MFF needs: * a validation prediction matrix, with observations in rows and candidate models in columns; * the validation response vector; * a test prediction matrix whose columns represent the same candidates in the same order; and * the test response only for final, unbiased performance reporting. This vignette illustrates the complete bootstrap workflow. It deliberately selects the MFF configuration and cluster using validation data before inspecting test performance. ## Generate candidate predictions We use the Boston housing data only as a compact reproducible illustration. `boot.train()` splits the data into training, validation, and test subsets, fits one linear regression to each bootstrap sample of the training subset, and predicts the same validation and test observations with every fitted model. ```{r bootstrap} library(MFF) set.seed(123) boot_fit <- boot.train( target = "medv", data = MASS::Boston, ntest = 50, nvalid = 50, B = 20, seed = 123, parallel = FALSE ) dim(boot_fit$pred_matrix_valid) dim(boot_fit$pred_matrix_test) boot_fit$metadata ``` Each column is now a candidate learner. The two matrices are aligned: column `j` contains predictions from the same bootstrap model in both matrices. ## Select an MFF on validation data `tune.mff()` searches over candidate numbers of clusters. Here k-means is used for a fast example; `"fcm"`, `"pfcm"`, and `"gk"` provide the alternative membership-generation geometries. The `eval.method` value determines which validation loss is minimized. ```{r tune} tuned <- tune.mff( x = boot_fit$pred_matrix_valid, y = boot_fit$y_valid, max_c = 4, mff.method = "kmeans", eval.method = "RMSE", nstart = 20, seed = 123, parallel = FALSE, logging = FALSE ) tuned$best_params tuned$best_cluster tuned$best_scores ``` The value in `best_cluster` is determined exclusively from validation responses. Consequently, the selected cluster is fixed before test responses or test error metrics are examined. The fact that a particular cluster later gives the best test result must not be used retrospectively to choose that cluster. ## Predict and evaluate once on the test set The validation-selected weights are transferred unchanged to the aligned test prediction matrix. ```{r predict} test_prediction <- predict( tuned, pred_matrix = boot_fit$pred_matrix_test, type = "best" ) head(test_prediction$mff_preds) test_prediction$mff_weights ``` Only after selection is complete do we use `y_test` for final evaluation. ```{r evaluate} evaluate(test_prediction$mff_preds, boot_fit$y_test) ``` The `evaluate()` helper is optional. Predictions can instead be assessed with other R packages or user-defined metrics, provided that model selection remains confined to the validation data. ## Supplying predictions from other R workflows Neither `boot.train()` nor `model.train()` is required. Learners may be trained with packages such as `tidymodels`, `caret`, `mlr3`, or forecasting packages. For externally generated inputs, users must ensure that: 1. validation predictions are genuinely out of sample for model selection; 2. validation and test matrices have the same candidate columns in the same order; 3. rows align exactly with the corresponding response vectors; and 4. for forecasting applications, train-validation-test splits respect temporal order and do not leak future information. Once these conditions are met, the downstream interface is unchanged: ```{r external-inputs, eval = FALSE} tuned <- tune.mff( x = validation_predictions, y = validation_response, max_c = 4, mff.method = "gk", eval.method = "RMSE" ) final_prediction <- predict( tuned, pred_matrix = test_predictions, type = "best" ) ``` Thus MFF can combine heterogeneous regression or forecasting candidates without requiring those candidates to have been trained inside the package.