funcml

funcml provides a machine learning framework for R. The package also includes native interpretability helpers for permutation importance, partial dependence, ICE, ALE, local surrogate explanations, SHAP, interaction strength, greedy breakdown profiles, and global surrogate models.

It also exposes native ensemble learners through model = "stacking" and model = "superlearner".

The package is intentionally opinionated. It is not designed to compete feature for feature with broader frameworks such as tidymodels, mlr3, or caret. Instead, funcml focuses on a compact and explicit framework for users who want to fit, compare, tune, interpret, and estimate models through one coherent interface, with formula syntax as the main model-specification surface.

This design comes with a deliberate tradeoff:

Users who need broader preprocessing orchestration or specialized resampling designs should use a more complete framework.

Learner coverage currently includes:

fit_obj <- fit(mpg ~ wt + hp, data = mtcars, model = "ranger")

permute_obj <- interpret(fit_obj, mtcars, method = "permute", nsim = 5)
pdp_obj <- interpret(fit_obj, mtcars, method = "pdp", features = "wt")
ale_obj <- interpret(fit_obj, mtcars, method = "ale", features = "wt")
local_obj <- interpret(fit_obj, mtcars, method = "local_model", newdata = mtcars[1, , drop = FALSE], k = 2)
shap_obj <- interpret(fit_obj, mtcars, method = "shap", newdata = mtcars[1, , drop = FALSE], nsim = 20)
profile_obj <- interpret(fit_obj, mtcars, method = "profile", newdata = mtcars[1, , drop = FALSE])
surrogate_obj <- interpret(fit_obj, mtcars, method = "surrogate")
eval_obj <- evaluate(mpg ~ wt + hp, data = mtcars, model = "glm", resampling = cv(5))
eval_obj
#> <funcml_eval> model: glm | task: regression
#>   metric      mean         sd n  std_error conf_level    conf_low  conf_high
#> 1   rmse 2.5072909 1.17395274 5 0.52500763       0.95  1.04963609  3.9649458
#> 2    mae 2.0942185 1.10813336 5 0.49557230       0.95  0.71828916  3.4701478
#> 3    mse 7.3890399 6.58309554 5 2.94404983       0.95 -0.78495283 15.5630326
#> 4  medae 1.9405515 1.17285891 5 0.52451845       0.95  0.48425480  3.3968482
#> 5   mape 0.1097179 0.04988504 5 0.02230927       0.95  0.04777744  0.1716584
#> 6    rsq 0.6452327 0.35317099 5 0.15794287       0.95  0.20671298  1.0837524
tune_grid <- expand.grid(intercept = c(TRUE, FALSE))

tune_obj <- tune(mpg ~ wt + hp, data = mtcars, model = "glm", grid = tune_grid, search = "random", n_evals = 1, resampling = cv(v = 3, seed = 1), seed = 1)

tune_obj
#> <funcml_tune> metric=rmse direction=min search=random
#> Best:
#>   intercept     mean        sd n std_error conf_level  conf_low conf_high
#> 1      TRUE 2.772583 0.9774437 3 0.5643274       0.95 0.3444783  5.200688

Nested CV is available through outer_resampling. The inner resampling argument still selects the best configuration, and the outer resampling loop provides an unbiased estimate of tuned model-selection performance.

nested_tune_obj <- tune(
  mpg ~ wt + hp,
  data = mtcars,
  model = "glm",
  grid = tune_grid,
  resampling = cv(v = 3, seed = 1),
  outer_resampling = cv(v = 4, seed = 2),
  metric = "rmse",
  seed = 1
)
nested_tune_obj
#> <funcml_tune> metric=rmse direction=min search=grid
#> Best:
#>   intercept     mean        sd n std_error conf_level  conf_low conf_high
#> 1      TRUE 2.772583 0.9774437 3 0.5643274       0.95 0.3444783  5.200688
#> Nested resampling:
#>   metric     mean      sd n std_error conf_level conf_low conf_high
#> 1   rmse 2.886158 1.08508 4 0.5425399       0.95 1.159553  4.612762
interaction_obj <- interpret(fit_obj, mtcars, method = "interaction")
plot(interaction_obj)
learners()
#>  [1] "glm"          "rpart"        "glmnet"       "ranger"       "nnet"        
#>  [6] "mlp"          "e1071_svm"    "randomForest" "gbm"          "C50"         
#> [11] "kknn"         "earth"        "gam"          "naivebayes"   "fda"         
#> [16] "adaboost"     "pls"          "ctree"        "cforest"      "lda"         
#> [21] "qda"          "lightgbm"     "bart"         "xgboost"      "stacking"    
#> [26] "superlearner"
plot(permute_obj)

plot(pdp_obj)

plot(ale_obj)

plot(local_obj)

plot(shap_obj, kind = "waterfall")

plot(profile_obj)

plot(surrogate_obj)