Nothing
      #' @include FamiliarS4Generics.R
#' @include FamiliarS4Classes.R
NULL
# familiarSVM ------------------------------------------------------------------
setClass(
  "familiarSVM",
  contains = "familiarModel"
)
setClass("familiarSVMC", contains = "familiarSVM")
setClass("familiarSVMNu", contains = "familiarSVM")
setClass("familiarSVMEps", contains = "familiarSVM")
# initialize -------------------------------------------------------------------
setMethod(
  "initialize",
  signature(.Object = "familiarSVM"),
  function(.Object, ...) {
    # Update with parent class first.
    .Object <- callNextMethod()
    # Set required package
    .Object@package <- "e1071"
    return(.Object)
  }
)
# is_available -----------------------------------------------------------------
setMethod(
  "is_available",
  signature(object = "familiarSVM"),
  function(object, ...) {
    # Extract outcome type.
    outcome_type <- object@outcome_type
    if (
      outcome_type %in% c("continuous", "count") &&
      (is(object, "familiarSVMNu") || is(object, "familiarSVMEps"))) {
      
      if (outcome_type == "count") ..deprecation_count()
      return(TRUE)
      
    } else if (
      outcome_type %in% c("binomial", "multinomial") && 
      (is(object, "familiarSVMNu") || is(object, "familiarSVMC"))) {
      return(TRUE)
      
    } else {
      return(FALSE)
    }
  }
)
# get_default_hyperparameters --------------------------------------------------
setMethod(
  "get_default_hyperparameters",
  signature(object = "familiarSVM"),
  function(object, data = NULL, ...) {
    # Find kernel type.
    svm_kernel <- ..find_kernel_type(learner = object@learner)
    # Initialise list and declare hyperparameter entries Note that some
    # hyperparameters may not be required, dependent on the kernel and type of
    # svm.
    param <- list()
    param$sign_size <- list()
    param$kernel <- list()
    param$c <- list()
    # Type-specific parameters.
    if (is(object, "familiarSVMNu") || is(object, "familiarSVMEps")) {
      param$epsilon <- list()
    }
    if (is(object, "familiarSVMNu")) {
      param$nu <- list()
    }
    # Kernel-specific parameters.
    if (svm_kernel %in% c("radial")) {
      param$gamma <- list()
    } else if (svm_kernel %in% c("polynomial")) {
      param$degree <- param$gamma <- param$offset <- list()
    } else if (svm_kernel %in% c("sigmoid")) {
      param$gamma <- param$offset <- list()
    }
    # If the data object is explicitly NULL, return the list with hyperparameter
    # names only.
    if (is.null(data)) return(param)
    # signature size -----------------------------------------------------------
    param$sign_size <- .get_default_sign_size(data = data)
    # svm kernel ---------------------------------------------------------------
    # A default kernel has been set earlier. Convert the svm_kernel to the
    # internal naming used by e1071::svm.
    # Set the svm kernel.
    param$kernel <- .set_hyperparameter(
      default = svm_kernel,
      type = "factor",
      range = svm_kernel,
      randomise = FALSE)
    # constraints violation cost C ---------------------------------------------
    # This parameter defines the cost for constraint violations. It is expressed
    # on a log10 scale.
    param$c <- .set_hyperparameter(
      default = c(-3, -1, -0, 1, 3),
      type = "numeric",
      range = c(-5, 3),
      valid_range = c(-Inf, Inf),
      randomise = TRUE)
    # error tolerance epsilon --------------------------------------------------
    if (is(object, "familiarSVMNu") || is(object, "familiarSVMEps")) {
      # This parameter defines the error tolerance for regression SVM. It is
      # expressed on a log10 scale.
      param$epsilon <- .set_hyperparameter(
        default = c(-5, -3, -1, 0, 1),
        type = "numeric",
        range = c(-5, 1),
        valid_range = c(-Inf, Inf),
        randomise = TRUE)
    }
    # error bounds parameter nu ------------------------------------------------
    if (is(object, "familiarSVMNu")) {
      # nu is expressed on a log10 scale.
      param$nu <- .set_hyperparameter(
        default = c(-5, -3, -1, 0, 1),
        type = "numeric",
        range = c(-5, 1),
        valid_range = c(-Inf, Inf),
        randomise = TRUE)
    }
    # inverse kernel width gamma -----------------------------------------------
    if (svm_kernel %in% c("radial", "polynomial", "sigmoid")) {
      # sigma is expressed on a log10 scale
      param$gamma <- .set_hyperparameter(
        default = c(-7, -5, -3, -1, 1),
        type = "numeric",
        range = c(-9, 3),
        valid_range = c(-Inf, Inf),
        randomise = TRUE)
    }
    # polynomial degree --------------------------------------------------------
    if (svm_kernel %in% c("polynomial")) {
      param$degree <- .set_hyperparameter(
        default = c(1, 2, 3, 4, 5),
        type = "integer",
        range = c(1, 5),
        valid_range = c(1, Inf),
        randomise = TRUE)
    }
    # kernel offset parameter --------------------------------------------------
    if (svm_kernel %in% c("polynomial", "sigmoid")) {
      # As feature data is rescaled internally by svm, we should not expect
      # offsets outside the [0, 1] range. Also, negative values are not allowed
      # for either kernel.
      param$offset <- .set_hyperparameter(
        default = c(0.0, 0.2, 0.5, 1.0),
        type = "numeric",
        range = c(0, 1),
        valid_range = c(0, Inf),
        randomise = TRUE)
    }
    return(param)
  }
)
# ..train ----------------------------------------------------------------------
setMethod(
  "..train",
  signature(
    object = "familiarSVM",
    data = "dataObject"),
  function(object, data, ...) {
    # Check if training data is ok.
    if (reason <- has_bad_training_data(object = object, data = data)) {
      return(callNextMethod(object = .why_bad_training_data(
        object = object,
        reason = reason)))
    }
    # Check if hyperparameters are set.
    if (is.null(object@hyperparameters)) {
      return(callNextMethod(object = ..update_errors(
        object = object,
        ..error_message_no_optimised_hyperparameters_available())))
    }
    # Check that required packages are loaded and installed.
    require_package(object, "train")
    # Find feature columns in data table
    feature_columns <- get_feature_columns(x = data)
    # Parse the formula.
    formula <- stats::reformulate(
      termlabels = feature_columns,
      response = quote(outcome))
    # Derive fitting parameters for fitting class probabilities.
    fit_probability <- object@outcome_type %in% c("binomial", "multinomial")
    # Derive svm type from object
    if (is(object, "familiarSVMC")) {
      svm_type <- "C-classification"
    } else if (
      is(object, "familiarSVMNu") &&
      object@outcome_type %in% c("binomial", "multinomial")) {
      svm_type <- "nu-classification"
    } else if (
      is(object, "familiarSVMNu") &&
      object@outcome_type %in% c("count", "continuous")) {
      svm_type <- "nu-regression"
    } else if (is(object, "familiarSVMEps")) {
      svm_type <- "eps-regression"
    } else {
      ..error_reached_unreachable_code("..train,familiarSVM: can not set the type of SVM.")
    }
    # Set svm-related parameters.
    svm_parameter_list <- list(
      "kernel" = as.character(object@hyperparameters$kernel),
      "cost" = 10^(object@hyperparameters$c))
    # Set nu-parameter (which not all svm types use).
    if (is(object, "familiarSVMNu")) {
      svm_parameter_list$nu <- 10^(object@hyperparameters$nu)
    }
    # Set epsilon parameter (which not all svm types use).
    if (is(object, "familiarSVMNu") || is(object, "familiarSVMEps")) {
      svm_parameter_list$epsilon <- 10^(object@hyperparameters$epsilon)
    }
    if (!is.null(object@hyperparameters$gamma)) {
      svm_parameter_list$gamma <- 10^object@hyperparameters$gamma
    }
    if (!is.null(object@hyperparameters$degree)) {
      svm_parameter_list$degree <- object@hyperparameters$degree
    }
    if (!is.null(object@hyperparameters$offset)) {
      svm_parameter_list$coef0 <- object@hyperparameters$offset
    }
    if (object@outcome_type %in% c("binomial", "multinomial")) {
      svm_parameter_list$class.weights <- "inverse"
    }
    # Train the model.
    model <- do.call_with_handlers(
      e1071::svm,
      args = c(
        list(formula,
          "data" = data@data,
          "type" = svm_type,
          "probability" = fit_probability,
          "fitted" = FALSE,
          "cross" = 0L),
        svm_parameter_list))
    # Extract values.
    object <- ..update_warnings(object = object, model$warning)
    object <- ..update_errors(object = object, model$error)
    model <- model$value
    # Check if the model trained at all.
    if (!is.null(object@messages$error)) return(callNextMethod(object = object))
    
    if (is.null(model)) {
      return(callNextMethod(object = ..update_errors(
        object = object,
        "SVM model returned as NULL.")))
    }
    # Add model
    object@model <- model
    # Set learner version
    object <- set_package_version(object)
    return(object)
  }
)
# ..train_naive ----------------------------------------------------------------
setMethod(
  "..train_naive",
  signature(
    object = "familiarSVM",
    data = "dataObject"),
  function(object, data, ...) {
    if (object@outcome_type %in% c("count", "continuous", "binomial", "multinomial")) {
      # Turn into a naive model.
      object <- methods::new("familiarNaiveModel", object)
    }
    return(..train(
      object = object,
      data = data,
      ...))
  }
)
# ..predict --------------------------------------------------------------------
setMethod(
  "..predict",
  signature(
    object = "familiarSVM",
    data = "dataObject"),
  function(object, data, type = "default", ...) {
    # Check that required packages are loaded and installed.
    require_package(object, "predict")
    if (type == "default") {
      # Default method ---------------------------------------------------------
      # Check if the model was trained.
      if (!model_is_trained(object)) return(callNextMethod())
      # Check if the data is empty.
      if (is_empty(data)) return(callNextMethod())
      # Get an empty prediction table.
      prediction_table <- get_placeholder_prediction_table(
        object = object,
        data = data,
        type = type)
      # Make predictions using the model.
      model_predictions <- tryCatch(
        predict(
          object = object@model,
          newdata = data@data,
          probability = object@outcome_type %in% c("binomial", "multinomial")),
        error = identity)
      # Check if the model trained at all.
      if (inherits(model_predictions, "error")) return(callNextMethod())
      if (object@outcome_type %in% c("binomial", "multinomial")) {
        # categorical outcomes -------------------------------------------------
        # Isolate probabilities.
        model_predictions <- attr(model_predictions, "probabilities")
        # Obtain class levels from the object.
        class_levels <- get_outcome_class_levels(x = object)
        # Add class probabilities to the prediction table.
        class_probability_columns <- get_class_probability_name(x = object)
        
        for (ii in seq_along(class_probability_columns)) {
          if (is.matrix(model_predictions)) {
            # Check if model_predictions is a matrix.
            prediction_table[, (class_probability_columns[ii]) := model_predictions[, class_levels[ii]]]
          } else {
            # Or not.
            prediction_table[, (class_probability_columns[ii]) := model_predictions[class_levels[ii]]]
          }
        }
        # Update predicted class based on provided probabilities.
        class_predictions <- class_levels[
          apply(prediction_table[, mget(class_probability_columns)], 1, which.max)]
        
        class_predictions <- factor(
          x = class_predictions,
          levels = class_levels)
        
        prediction_table[, "predicted_class" := class_predictions]
        
      } else if (object@outcome_type %in% c("continuous", "count")) {
        # numerical outcomes ---------------------------------------------------
        # Extract predicted regression values.
        prediction_table[, "predicted_outcome" := model_predictions]
        
      } else {
        ..error_outcome_type_not_implemented(object@outcome_type)
      }
      return(prediction_table)
    }
  }
)
# ..vimp -----------------------------------------------------------------------
# SVM does not have an associated variable importance method.
# .trim_model-------------------------------------------------------------------
setMethod(
  ".trim_model",
  signature(object = "familiarSVM"),
  function(object, ...) {
    # Update model by removing the call.
    object@model$call <- call("trimmed")
    # Add show.
    object <- .capture_show(object)
    # Remove .Environment.
    object@model$terms <- .replace_environment(object@model$terms)
    # Set is_trimmed to TRUE.
    object@is_trimmed <- TRUE
    # Default method for models that lack a more specific method.
    return(object)
  }
)
.get_available_svm_c_learners <- function(show_general = TRUE) {
  return(c("svm_c", paste("svm_c", ..get_available_svm_kernels(), sep = "_")))
}
.get_available_svm_nu_learners <- function(show_general = TRUE) {
  return(c("svm_nu", paste("svm_nu", ..get_available_svm_kernels(), sep = "_")))
}
.get_available_svm_eps_learners <- function(show_general = TRUE) {
  return(c("svm_eps", paste("svm_eps", ..get_available_svm_kernels(), sep = "_")))
}
..get_available_svm_kernels <- function() {
  return(c("linear", "radial", "polynomial", "sigmoid"))
}
..find_kernel_type <- function(learner) {
  # Find all available svm kernels.
  svm_kernels <- ..get_available_svm_kernels()
  
  # Find matches with end of learner string.
  kernel_matches <- sapply(svm_kernels, function(suffix, x) (endsWith(x = x, suffix = suffix)), x = learner)
  
  # If all are missing (e.g. "svm_eps), use default RBF kernel.
  if (all(!kernel_matches)) {
    return("radial")
  }
  
  # Else, return selected kernel.
  return(svm_kernels[kernel_matches])
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.