4

This question ought to be real simple. But the documentation isn't helping.

I am using R. I must use the neuralnet package for a multinomial classification problem.

All examples are for binomial or linear output. I could do some one-vs-all implementation using binomial output. But I believe I should be able to do this by having 3 units as the output layer, where each is a binomial (ie. probability of that being the correct output). No?

This is what I would using nnet (which I believe is doing what I want):

data(iris)
library(nnet)
m1 <- nnet(Species ~ ., iris, size = 3)
table(predict(m1, iris, type = "class"), iris$Species)

This is what I am trying to do using neuralnet (the formula hack is because neuralnet does not seem to support the '.' notation in the formula):

data(iris)
library(neuralnet)
formula <- paste('Species ~', paste(names(iris)[-length(iris)], collapse='+'))
m2 <- neuralnet(formula, iris, hidden=3, linear.output=FALSE)
# fails !
B314005
  • 53
  • 9
Ricardo Magalhães Cruz
  • 3,504
  • 6
  • 33
  • 57
  • 1
    It seems that the 'neuralnet' package has been updated and supports this functionality now (since version 1.44.1). So the above code no longer fails, and also dots in formulas are not supported. – UBod Nov 25 '19 at 15:41

2 Answers2

8

You are right that the formula interface of neuralnet() does not support '.'.

However, the problem with your code above is rather that a factor is not accepted as target. You have to expand the factor Species to three binary variables first. Ironically, this works best with the function class.ind() from the nnet package (which wouldn't need such a function, since nnet() and multinom() work fine with factors):

trainData <- cbind(iris[, 1:4], class.ind(iris$Species))
neuralnet(setosa + versicolor + virginica ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width, trainData)

This works - at least for me.

B314005
  • 53
  • 9
UBod
  • 825
  • 7
  • 11
  • how would you do the above if your output layers were in the thousands and couldn't write it manually? – nak5120 Feb 23 '17 at 21:38
  • Suppose you have 1000 outputs names z1...z1000 and 2000 inputs named x1...x2000, then you can create a string with the formula and convert it to a formula as follows: as.formula(paste(paste0("z", 1:1000, collapse=" + "), "~", paste0("x", 1:2000, collapse=" + "))) – UBod Feb 28 '17 at 10:12
-1

Maybe you should have a look to http://cran.r-project.org/web/packages/nnet/nnet.pdf, the description of the package's content. You can see that there is a function called multinom, that helps you achieve this.

Basically, it will split the qualitative column species into quantitative columns (which is what class.ind does), and then try to predict the values for these new artificial columns.

nn <- multinom(species ~ ., iris)

I'm not sure if I answered your question because I have the feeling that you are trying to do with neuralnet something that does not work with nnet. If I'm wrong then... sorry ;)

batiste
  • 1
  • 1