TL;DR: Pass the svm()
function used to fit your svm model to tune()
, not the model itself. Also, make sure you didn't overshadow the svm()
function by assigning your model or any other object to the svm
variable. If you do this, tune()
will not recognize svm
as the original svm()
function, which it expects.
Here is a first post for any future person who googles this problem.
You have generated an svm model model
using the svm()
function from the e1071 library, like so:
data(iris)
model <- svm(Species ~ ., data = iris)
Now you want to tune your model
. You decide to do it by passing it to the tune
function, like so:
tuning_result <- tune(model, Species ~ ., data = iris, ranges = list(epsilon = seq(0,1,0.1), cost = 2^(2:9)))
You run the command, and R spits out the following error:
Error in do.call(method, c(list(train.x, data = data, subset = train.ind[[sample]]), :
'what' must be a function or character string
The manual for the tune
function (accessed via ?tune
) reveals that the first argument passed to tune
should be the function you want to tune, not the model itself.
You re-run your code, like so:
tuning_result <- tune(svm, Species ~ ., data = iris,ranges = list(epsilon = seq(0,1,0.1), cost = 2^(2:9)))
And this time around it should work.
If tune(svm, Species ~ ., data = iris,ranges = list(epsilon = seq(0,1,0.1), cost = 2^(2:9)))
still throws the same error, then check in your code or workspace history, that you didn't accidentally assign a different object to the variable svm
.
svm()
function, and assign it to the variable svm
, the function tune()
will get confused, as it sees your model assigned to svm
, instead of the svm()
function it expects:
We fit a model using the svm()
function and assign it to the variable svm
, and the try to tune svm
the same way as in the previous working example.
svm <- svm(Species ~ ., data = iris)
tuning_result <- tune(svm, Species ~ ., data = iris,ranges = list(epsilon = seq(0,1,0.1), cost = 2^(2:9)))
Again, we'll get the same error as before, even though we passed svm
to the tune()
function:
Error in do.call(method, c(list(train.x, data = data, subset = train.ind[[sample]]), :
'what' must be a function or character string
If you overshadow the svm()
function this way, tune()
will not recognize svm
as the svm()
function.
To fix this, assign the contents of svm
to a different variable, and run rm(svm)
, or be more explicit about which svm
you're referring to, by specifying that you want to use the svm()
function from the e1071
package, like so:
# This should work:
tuning_result <- tune(e1071::svm, Species ~ ., data = iris,ranges = list(epsilon = seq(0,1,0.1), cost = 2^(2:9)))
2017-01-13 Edit: Fixed an error in the text (thanks to Morris for pointing it out in the comment section), and edited the text for clarity and less resignation.
2018-07-18 Edit: I rewrote the post to make it more reproducible (since y'all are still googling this), and added an example of things going wrong if you overshadow the svm()
function.