| Function | Works |
|---|---|
tidypredict_fit(), tidypredict_sql(),
parse_model() |
|
tidypredict_to_column() |
|
tidypredict_test() |
|
parsnip |
Here is a simple C5.0() classification model using the
mtcars dataset:
C5.0 stores its fitted tree as text in the tree element
of the model object. tidypredict parses that text directly,
so the model can be translated even when it was fitted through the x/y
interface (as parsnip does).
The tree is transformed into a dplyr, a.k.a Tidy Eval,
formula. The decision tree becomes a nested
dplyr::case_when() statement.
tidypredict_fit(model)
#> case_when(cyl <= 6 ~ case_when(cyl <= 4 ~ "1", .default = case_when(wt <=
#> 2.875 ~ "0", .default = "1")), .default = "0")From there, the Tidy Eval formula can be used anywhere where it can
be operated. tidypredict provides three paths:
dplyr,
mutate(mtcars2, !! tidypredict_fit(model))tidypredict_to_column(model) to a piped command
settidypredict_sql(model) to retrieve the SQL
statementC5.0 handles categorical predictors natively. The
generated formula uses %in% for categorical splits, and
multi-way splits become nested case_when() branches:
tidypredict also supports C5.0 model
objects fitted via the parsnip package, both as a
decision_tree() and as a boosted
boost_tree().
C5.0 can boost several trees together, which
parsnip exposes through boost_tree(). Each
trial casts a confidence-weighted vote, and the class with the greatest
total vote is predicted. tidypredict reproduces this by
summing the per-trial votes and picking the winning class:
boosted_model <- boost_tree(mode = "classification", trees = 5) |>
set_engine("C5.0") |>
fit(Species ~ ., data = iris)
tidypredict_fit(boosted_model)
#> case_when(case_when(Petal.Length <= 1.9 ~ 0.980769230769231,
#> .default = case_when(Petal.Width <= 1.7 ~ case_when(Petal.Length <=
#> 4.9000001 ~ 0, .default = 0), .default = 0)) + case_when(Petal.Length <=
#> 1.9 ~ 0.974901173370145, .default = case_when(Petal.Width <=
#> 1.8 ~ case_when(Sepal.Length <= 4.9000001 ~ 0, .default = case_when(Petal.Length <=
#> 5.3000002 ~ 0, .default = 0)), .default = 0)) + case_when(Petal.Length <=
#> 1.9 ~ 0.967511159916569, .default = case_when(Petal.Width <=
#> 1.7 ~ 0, .default = 0)) + case_when(Petal.Length <= 1.9 ~
#> 0.960182840396897, .default = case_when(Petal.Width <= 1.3 ~
#> 0, .default = case_when(Petal.Length <= 5.0999999 ~ case_when(Sepal.Width <=
#> 3 ~ case_when(Sepal.Length <= 6.4000001 ~ 0, .default = 0),
#> .default = 0), .default = 0))) + case_when(Petal.Length <=
#> 1.9 ~ 0.949491633289054, .default = case_when(Petal.Length <=
#> 4.8000002 ~ case_when(Petal.Width <= 1.6 ~ 0, .default = 0),
#> .default = 0)) >= case_when(Petal.Length <= 1.9 ~ 0, .default = case_when(Petal.Width <=
#> 1.7 ~ case_when(Petal.Length <= 4.9000001 ~ 0.96, .default = 0),
#> .default = 0)) + case_when(Petal.Length <= 1.9 ~ 0, .default = case_when(Petal.Width <=
#> 1.8 ~ case_when(Sepal.Length <= 4.9000001 ~ 0, .default = case_when(Petal.Length <=
#> 5.3000002 ~ 0.912209071754808, .default = 0)), .default = 0)) +
#> case_when(Petal.Length <= 1.9 ~ 0, .default = case_when(Petal.Width <=
#> 1.7 ~ 0.706144609436937, .default = 0)) + case_when(Petal.Length <=
#> 1.9 ~ 0, .default = case_when(Petal.Width <= 1.3 ~ 0.946093678405667,
#> .default = case_when(Petal.Length <= 5.0999999 ~ case_when(Sepal.Width <=
#> 3 ~ case_when(Sepal.Length <= 6.4000001 ~ 0, .default = 0.893828235319099),
#> .default = 0.891442575444509), .default = 0))) + case_when(Petal.Length <=
#> 1.9 ~ 0, .default = case_when(Petal.Length <= 4.8000002 ~
#> case_when(Petal.Width <= 1.6 ~ 0.976712070366808, .default = 0),
#> .default = 0)) & case_when(Petal.Length <= 1.9 ~ 0.980769230769231,
#> .default = case_when(Petal.Width <= 1.7 ~ case_when(Petal.Length <=
#> 4.9000001 ~ 0, .default = 0), .default = 0)) + case_when(Petal.Length <=
#> 1.9 ~ 0.974901173370145, .default = case_when(Petal.Width <=
#> 1.8 ~ case_when(Sepal.Length <= 4.9000001 ~ 0, .default = case_when(Petal.Length <=
#> 5.3000002 ~ 0, .default = 0)), .default = 0)) + case_when(Petal.Length <=
#> 1.9 ~ 0.967511159916569, .default = case_when(Petal.Width <=
#> 1.7 ~ 0, .default = 0)) + case_when(Petal.Length <= 1.9 ~
#> 0.960182840396897, .default = case_when(Petal.Width <= 1.3 ~
#> 0, .default = case_when(Petal.Length <= 5.0999999 ~ case_when(Sepal.Width <=
#> 3 ~ case_when(Sepal.Length <= 6.4000001 ~ 0, .default = 0),
#> .default = 0), .default = 0))) + case_when(Petal.Length <=
#> 1.9 ~ 0.949491633289054, .default = case_when(Petal.Length <=
#> 4.8000002 ~ case_when(Petal.Width <= 1.6 ~ 0, .default = 0),
#> .default = 0)) >= case_when(Petal.Length <= 1.9 ~ 0, .default = case_when(Petal.Width <=
#> 1.7 ~ case_when(Petal.Length <= 4.9000001 ~ 0, .default = 0.625),
#> .default = 0.958333333333333)) + case_when(Petal.Length <=
#> 1.9 ~ 0, .default = case_when(Petal.Width <= 1.8 ~ case_when(Sepal.Length <=
#> 4.9000001 ~ 0.860919094267197, .default = case_when(Petal.Length <=
#> 5.3000002 ~ 0, .default = 0.875850270460186)), .default = 0.963941744282062)) +
#> case_when(Petal.Length <= 1.9 ~ 0, .default = case_when(Petal.Width <=
#> 1.7 ~ 0, .default = 0.852928413186945)) + case_when(Petal.Length <=
#> 1.9 ~ 0, .default = case_when(Petal.Width <= 1.3 ~ 0, .default = case_when(Petal.Length <=
#> 5.0999999 ~ case_when(Sepal.Width <= 3 ~ case_when(Sepal.Length <=
#> 6.4000001 ~ 0.828141362462419, .default = 0), .default = 0),
#> .default = 0.961628192534381))) + case_when(Petal.Length <=
#> 1.9 ~ 0, .default = case_when(Petal.Length <= 4.8000002 ~
#> case_when(Petal.Width <= 1.6 ~ 0, .default = 0.62012436534794),
#> .default = 0.742434886685921)) ~ "setosa", case_when(Petal.Length <=
#> 1.9 ~ 0, .default = case_when(Petal.Width <= 1.7 ~ case_when(Petal.Length <=
#> 4.9000001 ~ 0.96, .default = 0), .default = 0)) + case_when(Petal.Length <=
#> 1.9 ~ 0, .default = case_when(Petal.Width <= 1.8 ~ case_when(Sepal.Length <=
#> 4.9000001 ~ 0, .default = case_when(Petal.Length <= 5.3000002 ~
#> 0.912209071754808, .default = 0)), .default = 0)) + case_when(Petal.Length <=
#> 1.9 ~ 0, .default = case_when(Petal.Width <= 1.7 ~ 0.706144609436937,
#> .default = 0)) + case_when(Petal.Length <= 1.9 ~ 0, .default = case_when(Petal.Width <=
#> 1.3 ~ 0.946093678405667, .default = case_when(Petal.Length <=
#> 5.0999999 ~ case_when(Sepal.Width <= 3 ~ case_when(Sepal.Length <=
#> 6.4000001 ~ 0, .default = 0.893828235319099), .default = 0.891442575444509),
#> .default = 0))) + case_when(Petal.Length <= 1.9 ~ 0, .default = case_when(Petal.Length <=
#> 4.8000002 ~ case_when(Petal.Width <= 1.6 ~ 0.976712070366808,
#> .default = 0), .default = 0)) >= case_when(Petal.Length <=
#> 1.9 ~ 0, .default = case_when(Petal.Width <= 1.7 ~ case_when(Petal.Length <=
#> 4.9000001 ~ 0, .default = 0.625), .default = 0.958333333333333)) +
#> case_when(Petal.Length <= 1.9 ~ 0, .default = case_when(Petal.Width <=
#> 1.8 ~ case_when(Sepal.Length <= 4.9000001 ~ 0.860919094267197,
#> .default = case_when(Petal.Length <= 5.3000002 ~ 0, .default = 0.875850270460186)),
#> .default = 0.963941744282062)) + case_when(Petal.Length <=
#> 1.9 ~ 0, .default = case_when(Petal.Width <= 1.7 ~ 0, .default = 0.852928413186945)) +
#> case_when(Petal.Length <= 1.9 ~ 0, .default = case_when(Petal.Width <=
#> 1.3 ~ 0, .default = case_when(Petal.Length <= 5.0999999 ~
#> case_when(Sepal.Width <= 3 ~ case_when(Sepal.Length <=
#> 6.4000001 ~ 0.828141362462419, .default = 0), .default = 0),
#> .default = 0.961628192534381))) + case_when(Petal.Length <=
#> 1.9 ~ 0, .default = case_when(Petal.Length <= 4.8000002 ~
#> case_when(Petal.Width <= 1.6 ~ 0, .default = 0.62012436534794),
#> .default = 0.742434886685921)) ~ "versicolor", .default = "virginica")Instead of a tree, C5.0 can produce an ordered set of
rules (rules = TRUE), which parsnip exposes
through C5_rules(). Each rule that a case satisfies casts a
confidence-weighted vote for its class, and the class with the greatest
total vote is predicted (the default class wins ties and cases matched
by no rule). tidypredict reproduces this by summing the
per-rule votes and picking the winning class:
rule_model <- C5.0(iris[, 1:4], iris$Species, rules = TRUE)
tidypredict_fit(rule_model)
#> case_when(dplyr::if_else(Petal.Length <= 1.9, 0.9807692, 0) >=
#> dplyr::if_else(Petal.Length > 1.9 & Petal.Length <= 4.9000001 &
#> Petal.Width <= 1.7, 0.96, 0) & dplyr::if_else(Petal.Length <=
#> 1.9, 0.9807692, 0) >= dplyr::if_else(Petal.Width > 1.7, 0.9583333,
#> 0) + dplyr::if_else(Petal.Length > 4.9000001, 0.9375, 0) ~
#> "setosa", dplyr::if_else(Petal.Length > 1.9 & Petal.Length <=
#> 4.9000001 & Petal.Width <= 1.7, 0.96, 0) >= dplyr::if_else(Petal.Width >
#> 1.7, 0.9583333, 0) + dplyr::if_else(Petal.Length > 4.9000001,
#> 0.9375, 0) ~ "versicolor", .default = "virginica")Some options change how C5.0 predicts in ways that cannot be
expressed as a hard-split case_when(), so they raise an
error: fuzzy thresholds (fuzzyThreshold = TRUE), models
fitted with a cost matrix (costs), and boosted rule-based
models (rules = TRUE with trials > 1).