Nothing
#' @title TrainLayer Class
#'
#' @description
#' This class implements a traning layer. A [TrainLayer] object can only exist as a component of a [Training] object.
#'
#' A training layer is structured as followed:
#'
#' * [TrainData]: Data to be used to train the learner.
#' * [Lrner]: Includes a learning function and the package implementing the function.
#' * [Model]: The result of training the learner on the training data.
#' * [VarSel]: Includes a variable selection function and the package implementing the function.
#'
#' A training layer can train its learner on its training data and store the resulting model. See the public function \code{Layer$train()} below.
#'
#' A training layer can make predictions for a new layer passed as argument to its predict function. See the public function \code{Layer$predict()} below.
#'
#' @export
#' @importFrom R6 R6Class
#' @seealso [Training], [Lrner], [TrainData], [TestData] and [Model]
TrainLayer <- R6Class("TrainLayer",
inherit = HashTable,
public = list(
#' @description
#' constructor
#'
#' @param id `character`\cr
#' Training layer id.
#' @param training `Training`\cr
#'
initialize = function (id, training) {
super$initialize(id = id)
private$training = training
if ("Training" %in% class(training)) {
training$add2HashTable(key = id,
value = self,
.class = "TrainLayer")
} else {
stop("A TrainLayer can only belong to a Training.")
}
private$status = FALSE
},
#' @description
#' Printer
#' @param ... `any`
#'
print = function (...){
if (!private$status) {
status = "Not trained"
} else {
status = "Trained"
}
cat(sprintf("TrainLayer : %s\n", private$id))
cat(sprintf("Status : %s\n", status))
stored_obj = self$getKeyClass()
if (!nrow(stored_obj)) {
cat("Empty layer.\n")
} else {
cat(sprintf("Nb. of objects stored : %s\n", nrow(stored_obj)))
cat("-----------------------\n")
print(stored_obj)
}
},
#' @description
#' Getter of the current training object.
#'
#' @return
#' The current training object is returned.
#'
getTraining = function () {
return(private$training)
},
#' @description
#' Getter of the target object.
#' @export
getTargetObj = function () {
return(private$training$getTargetObj())
},
#' @description
#' Trains the current layer.
#'
#' @param ind_subset `vector` \cr
#' ID subset of individuals to be used for training.
#' @param use_var_sel `boolean` \cr
#' If TRUE, variable selection is performed before training.
#' @param verbose `boolean` \cr
#' Warning messages will be displayed if set to TRUE.
#'
#' @return
#' The current layer is returned with the resulting model.
#' @export
#'
train = function (ind_subset = NULL,
use_var_sel = FALSE,
verbose = TRUE) {
layer_kc = self$getKeyClass()
# Stop if either learner of data is missing on this layer.
if (!("Lrner" %in% layer_kc[ , "class"])){
stop(sprintf("No learner on layer %s.", self$getId()))
} else {
if (!("TrainData" %in% layer_kc[ , "class"])) {
stop(sprintf("No data on layer %s.", self$getId()))
}
}
# The learner is trained on the current dataset
lrner_key = layer_kc[layer_kc$class == "Lrner" , "key"]
lrner = self$getFromHashTable(key = lrner_key[1L])
if (use_var_sel & (!self$checkVarSelExist())) {
if (verbose) {
warning(sprintf("No var. sel. on layer %s.", self$getId()))
}
use_var_sel = FALSE
}
if (verbose) {
message(sprintf("Training of base model on layer %s started.\n", self$getId()))
}
model = lrner$train(ind_subset = ind_subset,
use_var_sel = use_var_sel,
verbose = verbose)
if (verbose) {
message(sprintf("Training of base model on layer %s done.\n", self$getId()))
}
# Updating the training status.
if (!private$status) {
# The training layer has not been trained before.
private$training$increaseNbTrainedLayer()
private$status = TRUE
} else {
# The training layer has been trained before.
private$status = TRUE
}
return(model)
},
#' @description
#' Variable selection on the current layer.
#'
#' @param ind_subset `vector` \cr
#' ID subset of individuals to be used for variable selection.
#' @param verbose `boolean` \cr
#' Warning messages will be displayed if set to TRUE.
#'
#' @return
#' The current layer is returned with the resulting model.
#' @export
#'
varSelection = function (ind_subset = NULL,
verbose = TRUE) {
layer_kc = self$getKeyClass()
# Stop if either selector or data is missing on this layer.
if (!("VarSel" %in% layer_kc[ , "class"])) {
if (verbose) {
warning(sprintf("No var. sel. method on layer %s.", self$getId()))
}
return(NULL)
} else {
if (!("TrainData" %in% layer_kc[ , "class"])) {
stop(sprintf("No data on layer %s.", self$getId()))
}
}
# The learner is trained on the current dataset
varsel_key = layer_kc[layer_kc$class == "VarSel" , "key"]
varsel = self$getFromHashTable(key = varsel_key[1L])
if (verbose) {
message(sprintf("Variable selection on layer %s started.\n", self$getId()))
}
selected = varsel$varSelection(ind_subset = ind_subset)
if (verbose) {
message(sprintf("Variable selection on layer %s done.\n", self$getId()))
}
return(selected)
},
#' @description
#' Predicts values for the new layer taking as argument.
#'
#' @param new_layer `TrainLayer` \cr
#' @param use_var_sel `boolean` \cr
#' If TRUE, selected variables available at each layer are used.
#' @param ind_subset `vector` \cr
#'
#' @return
#' A new [PredictLayer] object with the predicted data is returned.
#' @export
#'
predict = function (new_layer,
use_var_sel,
ind_subset = NULL) {
k = self$getId()
# Layer IDs must match together.
if (k == new_layer$getId()) {
m_layer = self$getModel()
} else {
stop("The new layer ID does not match with the current layer ID.")
}
testing_data = new_layer$getTestData()
# Predicting: Data and model exist on this layer.
model = self$getModel()
pred_data = model$predict(testing_data = testing_data,
use_var_sel,
ind_subset = ind_subset)
# Initialize a predicted layer to store predictions
pred_layer = PredictLayer$new(
id = private$id
)
pred_data$setPredictLayer(pred_layer)
return(pred_layer)
},
#' @description
#' Getter of the training dataset stored on the current layer.
#'
#' @return
#' The stored [TrainData] object is returned.
#' @export
#'
getTrainData = function () {
layer_kc = self$getKeyClass()
if ("TrainData" %in% layer_kc[ , "class"]) {
train_data_key = layer_kc[layer_kc$class == "TrainData" ,
"key"]
train_data = self$getFromHashTable(key = train_data_key[1L])
} else {
stop(sprintf("No train data on layer %s.", self$getId()))
}
return(train_data)
},
#' @description
#' Getter of target values from the current layer.
#'
#' @return
#' A \code{data.frame} containing individuals IDs and corresponding target values.
#' @export
#'
getTargetValues = function () {
layer_kc = self$getKeyClass()
# Stop if training data is missing on this layer.
if (("TrainData" %in% layer_kc[ , "class"])) {
# Searching for layer specific training dataset
train_data_key = layer_kc[layer_kc$class == "TrainData" ,
"key"]
train_data = self$getTrainData()
train_data_frame = train_data$getDataFrame()
target_data = train_data_frame[ , c(train_data$getIndCol(),
train_data$getTargetName())]
return(target_data)
} else {
stop(sprintf("No data on layer %s.", self$getId()))
}
},
#' @description
#' Getter of IDS from the current layer.
#'
#' @return
#' A \code{data.frame} containing individuals IDs values.
#' @export
#'
getIndIDs = function () {
layer_kc = self$getKeyClass()
# Stop if training data is missing on this layer.
if (("TrainData" %in% layer_kc[ , "class"])) {
# Searching for layer specific new dataset
data_key = layer_kc[layer_kc$class == "TrainData" ,
"key"]
current_data = self$getTestData()
} else {
stop(sprintf("No data on layer %s.", self$getId()))
}
current_data_frame = current_data$getDataFrame()
ids_data = current_data_frame[ , current_data$getIndCol(), drop = FALSE]
return(ids_data)
},
#' @description
#' Getter of the new data.
#'
#' @return
#' The stored [TestData] object is returned.
# A TrainLayer plays the role of TestLayer when creating meta modality-specific prediction data.
getTestData = function () {
layer_kc = self$getKeyClass()
if (any(c("TestData", "TrainData") %in% layer_kc[ , "class"])) {
if ("TestData" %in% layer_kc[ , "class"]) {
# nocov start
# TODO: This part of the code will never be executed. Check it and maybe remove it
testing_data_key = layer_kc[layer_kc$class == "TestData" ,
"key"]
testing_data = self$getFromHashTable(key = testing_data_key[1L])
# nocov end
} else {
testing_data = self$getTrainData()
}
} else {
stop(sprintf("No new data on layer %s.", self$getId()))
}
return(testing_data)
},
#' @description
#' Getter of the learner.
#'
#' @return
#' The stored [Lrner] object is returned.
#' @export
getLrner = function () {
layer_kc = self$getKeyClass()
if (!("Lrner" %in% layer_kc[ , "class"])) {
stop(sprintf("No Lrner on layer %s.", self$getId()))
} else {
lrner_key = layer_kc[layer_kc$class == "Lrner" ,
"key"]
lrner = self$getFromHashTable(key = lrner_key[1L])
}
return(lrner)
},
#' @description
#' Getter of the variable selector.
#'
#' @return
#' The stored [VarSel] object is returned.
#' @export
getVarSel = function () {
layer_kc = self$getKeyClass()
if (!("VarSel" %in% layer_kc[ , "class"])) {
stop(sprintf("No VarSel on layer %s.", self$getId()))
} else {
varsel_key = layer_kc[layer_kc$class == "VarSel" ,
"key"]
varsel = self$getFromHashTable(key = varsel_key[1L])
}
return(varsel)
},
#' @description
#' Getter of the model.
#'
#' @return
#' The stored [Model] object is returned.
#' @export
#'
getModel = function () {
layer_kc = self$getKeyClass()
if (!("Model" %in% layer_kc[ , "class"])) {
stop(sprintf("No Model on layer %s.", self$getId()))
} else {
model_key = layer_kc[layer_kc$class == "Model" ,
"key"]
model = self$getFromHashTable(key = model_key[1L])
}
return(model)
},
#' @description
#' Check whether a learner has been already stored.
#'
#' @return
#' Boolean value
#'
checkLrnerExist = function () {
return(super$checkClassExist(.class = "Lrner"))
},
#' @description
#' Check whether a model has been already stored.
#'
#' @return
#' Boolean value
#'
checkModelExist = function () {
return(super$checkClassExist(.class = "Model"))
},
#' @description
#' Check whether a variable selection tool has been already stored.
#'
#' @return
#' Boolean value
#'
checkVarSelExist = function () {
return(super$checkClassExist(.class = "VarSel"))
},
#' @description
#' Check whether a training data has been already stored.
#'
#' @return
#' Boolean value
#'
checkTrainDataExist = function () {
return(super$checkClassExist(.class = "TrainData"))
},
#' @description
#' Generate summary.
#'
#' @export
#'
summary = function () {
cat(sprintf(" Layer %s\n", self$getId()))
cat(" ----------------\n")
if (!private$status) {
status = "Not trained"
} else {
status = "Trained"
}
cat(sprintf(" TrainLayer : %s\n", private$id))
cat(sprintf(" Status : %s\n", status))
stored_obj = self$getKeyClass()
if (!nrow(stored_obj)) {
cat(" Empty layer.\n")
} else {
cat(sprintf(" Nb. of objects stored : %s\n", nrow(stored_obj)))
}
cat(" ----------------\n")
layer_kc = self$getKeyClass()
cat(sprintf(" Object(s) on layer %s\n\n", self$getId()))
if (!nrow(layer_kc)) {
cat(" Empty layer\n")
}
for (k in layer_kc[layer_kc$class != "Model" , "key"]) {
cat(" ----------------\n")
current_obj = self$getFromHashTable(key = k)
current_obj$summary()
cat(" ----------------\n")
cat("\n")
}
}
),
private = list(
training = NULL,
status = FALSE
),
# TODO: define a deep_clone function for this class.
cloneable = FALSE
)
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.