Hi All,
Thanking everyone in advance for any available help.
I have been trying to figure out how to add a new model to {parsnip}. {neuralnet} felt like a pretty straight forward model to build so I figured to give it a go.
Fitting and predicting with {neuralnet} is very straight forward, yay.
library(neuralnet)
fit <- neuralnet(Species ~., data = iris, hidden = 3)
predict(fit, newdata = iris)
After running the script below, I managed to fit my new "neural_net" {parsnip} model with no problems but running predict generates an "Error: $ operator is invalid for atomic vectors" error. I tried messing around with the encoding and prediction sections but can't seem to find a way to predict on new data. Does anyone have pointers as to what I am doing wrong?
Any help will be greatly appreciated.
library(tidymodels)
library(neuralnet)
# Register model and arguments
parsnip::set_new_model("neural_net")
parsnip::set_model_mode(model = "neural_net", mode = "classification")
parsnip::set_model_engine("neural_net", mode = "classification", eng = "neuralnet")
parsnip::set_dependency("neuralnet", eng = "neuralnet", pkg = "neuralnet")
# Arguments = hidden
parsnip::set_model_arg(
model = "neural_net",
eng = "neuralnet",
parsnip = "hidden",
original = "hidden",
func = list(pkg = "dials", fun = "hidden_units"),
has_submodel = FALSE
)
# Encoding
parsnip::set_encoding(
model = "neural_net",
eng = "neuralnet",
mode = "classification",
options = list(
predictor_indicators = "traditional",
compute_intercept = TRUE,
remove_intercept = TRUE,
allow_sparse_x = FALSE
)
)
# Fit
parsnip::set_fit(
model = "neural_net",
eng = "neuralnet",
mode = "classification",
value = list(
interface = "formula",
protect = c("formula", "data"),
func = c(pkg = "neuralnet", fun = "neuralnet"),
defaults = list()
)
)
# Predict
parsnip::set_pred(
model = "neural_net",
eng = "neuralnet",
mode = "classification",
type = "class",
value = list(
pre = NULL,
post = NULL,
func = c(fun = "predict"),
args = list(
object = quote(object$fit),
newdata = quote(new_data)
)
)
)
# Model function
neural_net <- function(mode = "classification", hidden = 1) {
# Check correct mode
if(mode != "classification") {
stop("`mode` should be 'classification'", call. = FALSE)
}
# Capture arguments
args <- list(
hidden = rlang::enquo(hidden)
)
# Model specs / slots
parsnip::new_model_spec(
"neural_net",
args = args,
mode = mode,
eng_args = NULL,
method = NULL,
engine = NULL
)
}
#Try it out
nn_spec <- neural_net(hidden = 3) %>%
set_engine("neuralnet")
nn_fit <- nn_spec %>%
fit(Species ~ ., data = iris)
predict(nn_fit, new_data = iris)