Support vector machines, using kernlab

Function Works
tidypredict_fit(), tidypredict_sql(), parse_model()
tidypredict_to_column()
tidypredict_test()
tidypredict_interval(), tidypredict_sql_interval()
parsnip

How it works

Only linear (vanilladot) kernels are supported. With a linear kernel the decision function collapses to a weighted sum of the predictors, which is exactly the shape tidypredict can write out.

library(kernlab)
library(dplyr)
library(tidypredict)

model <- ksvm(
  mpg ~ wt + hp + disp,
  data = mtcars,
  kernel = "vanilladot",
  type = "eps-svr"
)
#>  Setting default kernel parameters

Under the hood

The parser multiplies the support vectors by their coefficients to recover one weight per predictor, undoes the scaling ksvm() applied while fitting, and adds the bias term.

pm <- parse_model(model)
str(pm, 2)
#> List of 2
#>  $ general:List of 4
#>   ..$ model  : chr "ksvm"
#>   ..$ version: num 2
#>   ..$ type   : chr "regression"
#>   ..$ is_glm : num 0
#>  $ terms  :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>   ..$ :List of 4
#>  - attr(*, "class")= chr [1:3] "parsed_model" "pm_regression" "list"

The parsed model is transformed into a dplyr, a.k.a. Tidy Eval, formula.

tidypredict_fit(model)
#> 35.9868850984331 + (wt * -3.52132505992066) + (hp * -0.0344671444570161) + 
#>     (disp * 0.000700491865519295)

From there, the Tidy Eval formula can be used anywhere it can be evaluated. tidypredict provides three paths:

mtcars %>%
  tidypredict_to_column(model) %>%
  glimpse()
#> Rows: 32
#> Columns: 12
#> $ mpg  <dbl> 21.0, 21.0, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22.8, 19.2, 17.8,…
#> $ cyl  <dbl> 6, 6, 4, 6, 8, 6, 8, 4, 4, 6, 6, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 8,…
#> $ disp <dbl> 160.0, 160.0, 108.0, 258.0, 360.0, 225.0, 360.0, 146.7, 140.8, 16…
#> $ hp   <dbl> 110, 110, 93, 110, 175, 105, 245, 62, 95, 123, 123, 180, 180, 180…
#> $ drat <dbl> 3.90, 3.90, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.92, 3.92,…
#> $ wt   <dbl> 2.620, 2.875, 2.320, 3.215, 3.440, 3.460, 3.570, 3.190, 3.150, 3.…
#> $ qsec <dbl> 16.46, 17.02, 18.61, 19.44, 17.02, 20.22, 15.84, 20.00, 22.90, 18…
#> $ vs   <dbl> 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,…
#> $ am   <dbl> 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,…
#> $ gear <dbl> 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3,…
#> $ carb <dbl> 4, 4, 1, 1, 2, 1, 4, 2, 2, 4, 4, 3, 3, 3, 4, 4, 4, 1, 2, 1, 1, 2,…
#> $ fit  <dbl> 23.081706, 22.183768, 24.687620, 21.055166, 18.093954, 20.341661,…
tidypredict_sql(model, dbplyr::simulate_mssql())
#> <SQL> ((35.9868850984331 + ([wt] * -3.52132505992066)) + ([hp] * -0.0344671444570161)) + ([disp] * 0.000700491865519295)

How it performs

tidypredict_test(model, mtcars)
#> tidypredict test results
#> Difference threshold: 1e-12
#> 
#>  All results are within the difference threshold

Classification

Binary classification models are supported, and return the probability of the second outcome level. ksvm() turns its decision values into probabilities with a fitted sigmoid, so the model has to be fitted with prob.model = TRUE for that sigmoid to exist.

df <- mtcars
df$vs <- factor(df$vs)

model_class <- ksvm(
  vs ~ wt + mpg,
  data = df,
  kernel = "vanilladot",
  type = "C-svc",
  prob.model = TRUE
)
#>  Setting default kernel parameters

tidypredict_fit(model_class)
#> 1/(1 + exp(-(-2.97721401151508 + (wt * -0.368454175940519) + 
#>     (mpg * 0.200709025600128))))

parsnip

tidypredict also supports ksvm model objects fitted via the parsnip package, using svm_linear() with the "kernlab" engine.

library(parsnip)

parsnip_model <- svm_linear(mode = "regression") |>
  set_engine("kernlab") |>
  fit(mpg ~ wt + hp, data = mtcars)

tidypredict_fit(parsnip_model)
#> 35.8783013722882 + (wt * -3.4369288942599) + (hp * -0.0345944994000946)

Limitations