Constructs a decision tree where each internal node uses a Support Vector Machine (SVM) to determine the split. Supports dynamic feature selection, feature penalization, scaling, and class weighting.

svm_split(
  data,
  response,
  depth = 1,
  max_depth = 10,
  min_samples = 5,
  max_features = NULL,
  feature_method = c("random", "mutual", "cor"),
  impurity_measure = c("entropy", "gini"),
  max_features_strategy = c("constant", "random", "decrease"),
  max_features_decrease_rate = 0.8,
  max_features_random_range = c(0.3, 1),
  penalize_used_features = FALSE,
  feature_penalty_weight = 0.5,
  n_subsets = 1,
  used_features = character(0),
  class_weights = c("none", "balanced", "custom"),
  custom_class_weights = NULL,
  min_impurity_decrease = 0.001,
  verbose = FALSE,
  all_classes = NULL,
  ...
)

Arguments

data

A data frame containing predictors and the response variable.

response

Character string specifying the response column in `data`. All other columns are treated as predictors.

depth

Integer indicating the current recursion depth (used internally; default is 1).

max_depth

Maximum depth of the tree.

min_samples

Minimum number of samples required to attempt a split.

max_features

Maximum number of features to consider at each split.

feature_method

Feature selection method at each node. One of:

  • `"random"`: randomly select features,

  • `"mutual"`: select based on mutual information with the response,

  • `"cor"`: select based on correlation with the response.

impurity_measure

Information Gain evaluation criteria

  • `"gini"`: use Gini ratio

  • `"entropy"`: use Shannon entropy

max_features_strategy

Strategy to adjust the number of features per node:

  • `"constant"`: keep `max_features` constant,

  • `"decrease"`: reduce features with depth,

  • `"random"`: randomly vary number of features within a range.

max_features_decrease_rate

Numeric fraction for decreasing features if `max_features_strategy = "decrease"`.

max_features_random_range

Numeric vector of length 2 specifying min and max fraction of features if `max_features_strategy = "random"`.

penalize_used_features

Logical; if TRUE, features used in ancestor nodes are penalized to encourage diversity.

feature_penalty_weight

Numeric (0<U+2013>1) weight for penalizing previously used features.

n_subsets

Number of Evaluated Random Feature combinations at each node when `feature_method = "random`

used_features

Character vector of features already used in ancestor nodes (used internally).

class_weights

Character string specifying how to handle class imbalance. One of:

  • `"none"`: no weighting,

  • `"balanced"`: weight classes inversely proportional to their frequency,

  • `"custom"`: use `custom_class_weights`.

custom_class_weights

Optional named numeric vector specifying custom weights per class.

min_impurity_decrease

Required decrease in impurity by a split to be considered valid

verbose

Logical; if TRUE, prints information about each node during tree construction.

all_classes

Optional character vector of all possible response classes (used internally).

...

Additional arguments passed to the underlying SVM fitting function.

Value

A nested list representing the decision tree. Each node contains:

is_leaf

Logical; TRUE if the node is a leaf.

model

Fitted SVM model at this node (for internal nodes).

features

Vector of features selected for this node.

scaler

Scaling information used at this node.

left

Left child node (decision value > 0).

right

Right child node (decision value <U+2264> 0).

depth

Depth of this node in the tree.

n

Number of samples at this node.

max_features_used

Number of features considered at this node.

penalty_applied

Logical; TRUE if feature penalization was applied.

class_weights_used

Class weights applied at this node.

Details

This function recursively splits the dataset using an SVM at each node. Splitting stops when maximum depth is reached, the node contains fewer than `min_samples`, or all samples belong to the same class. Features are scaled and selected dynamically at each node, and previously used features can be penalized to promote diversity. Class weighting schemes support handling imbalanced datasets. This approach allows construction of an **oblique decision tree**, where splits are linear hyperplanes rather than axis-aligned.

Examples

# \donttest{
data(wdbc)
tree <- svm_split(
  data = wdbc,
  response = "diagnosis",
  max_depth = 3,
  min_samples = 5,
  feature_method = "random",
  verbose = TRUE
)
#> 
#> --- Node at depth 1 ---
#> Samples: 569 
#> Class distribution:
#> 
#>   B   M 
#> 357 212 
#> Number of classes at node: 2 
#> Selected features: radius_mean, texture_mean, perimeter_mean, area_mean, smoothness_mean, compactness_mean, concavity_mean, concave.points_mean, symmetry_mean, fractal_dimension_mean, radius_se, texture_se, perimeter_se, area_se, smoothness_se, compactness_se, concavity_se, concave.points_se, symmetry_se, fractal_dimension_se, radius_worst, texture_worst, perimeter_worst, area_worst, smoothness_worst, compactness_worst, concavity_worst, concave.points_worst, symmetry_worst, fractal_dimension_worst 
#> Binary classification case
#> Classes at node      : B, M 
#> Class counts         : 357, 212 
#> Class weights: none (equal weights)
#> 
#> --- Node at depth 2 ---
#> Samples: 209 
#> Class distribution:
#> 
#>   B   M 
#>   2 207 
#> Number of classes at node: 2 
#> Selected features: radius_mean, texture_mean, perimeter_mean, area_mean, smoothness_mean, compactness_mean, concavity_mean, concave.points_mean, symmetry_mean, fractal_dimension_mean, radius_se, texture_se, perimeter_se, area_se, smoothness_se, compactness_se, concavity_se, concave.points_se, symmetry_se, fractal_dimension_se, radius_worst, texture_worst, perimeter_worst, area_worst, smoothness_worst, compactness_worst, concavity_worst, concave.points_worst, symmetry_worst, fractal_dimension_worst 
#> Binary classification case
#> Classes at node      : B, M 
#> Class counts         : 2, 207 
#> Class weights: none (equal weights)
#> Right child too small, creating left child and right leaf
#> 
#> --- Node at depth 3 ---
#> Samples: 207 
#> Class distribution:
#> 
#>   B   M 
#>   0 207 
#> Creating leaf node
#> 
#> --- Node at depth 2 ---
#> Samples: 360 
#> Class distribution:
#> 
#>   B   M 
#> 355   5 
#> Number of classes at node: 2 
#> Selected features: radius_mean, texture_mean, perimeter_mean, area_mean, smoothness_mean, compactness_mean, concavity_mean, concave.points_mean, symmetry_mean, fractal_dimension_mean, radius_se, texture_se, perimeter_se, area_se, smoothness_se, compactness_se, concavity_se, concave.points_se, symmetry_se, fractal_dimension_se, radius_worst, texture_worst, perimeter_worst, area_worst, smoothness_worst, compactness_worst, concavity_worst, concave.points_worst, symmetry_worst, fractal_dimension_worst 
#> Binary classification case
#> Classes at node      : B, M 
#> Class counts         : 355, 5 
#> Class weights: none (equal weights)
# }