Neural networks with R: Classify species of flowers

Posted on February 14, 2016 by


There are many variations of neural networks, in this guide we are going to focus on using a supervised feedforward neural network.

This guide will apply neural networks to classify species of flowers in the iris dataset based on their petal length, petal width, sepal length and sepal width. The data is included in R and can be called by typing in iris. In the iris dataset there are 50 rows of data for each species of flower (setosa, versicolor and virginica) meaning there are 150 rows altogether. We will take a random sample of 50 rows to train the neural network then test the neural network on the remaining data.

First we need to create the training dataset with 50 rows selected randomly. To do this we can use the sample() function:

itrain <- iris[sample(1:150, 50),]

Now when you call back itrain, there will be 50 random rows from the original iris dataset.

Next we need to change the categorical output of itrain$Species (names of the flower species) to columns with Boolean (true/false) values. To do this, we can add three columns to the data frame:

itrain$setosa <- c(itrain$Species == ‘setosa’)

itrain$versicolor <- c(itrain$Species == ‘versicolor’)

itrain$virginica <- c(itrain$Species == ‘virginica’)

If you now call back itrain the data should look like:


Assuming the three columns of Boolean values match the Species column, we can remove the Species column using:  itrain$Species <- NULL

Now that we have our training set ready we can go on to train the neural network with the neuralnet() function in the neuralnet package.

First install the package with install.packages(“neuralnet”) then add it to your R library with library(neuralnet)

You can train the neural network using the following code:

inet <- neuralnet(setosa + versicolor + virginica ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width, itrain, hidden=3, lifesign=”full”)

This will use setosa, versicolor and virginica as output nodes and Sepal Length, Sepal Width, Petal Length and Petal Width as input nodes. The algorithm will use 3 hidden nodes, print information to you during the iterations and save the results to inet.

Once the algorithm reaches the threshold of 0.01 (finishes) you can plot the result using: plot(inet, rep=”best”)

You can also plot the neural network without the bias nodes: plot(inet, rep=”best”, intercept=FALSE)

Your plot should resemble this (although the weights, error and iterations will most likely differ):


Now we can predict outputs for the whole iris dataset (150 rows) using the compute() function:

predict <- compute(inet, iris[1:4])

Calling back predict$net.result shows the predictions for the neural network. You will notice that for most rows one column contains a value close to 1 and the other two have values close to 0. The column with the value close to 1 (i.e. the largest value) indicates TRUE while a value near 0 indicates FALSE.

We can use the which.max() function on each row to workout which column has the largest value. For example which.max(predict$net.result[1,]) returns the column number with the highest value for the first row.

To do this we can create a variable called result and then insert which column has the maximum value for each row using a for loop:


for (i in 1:150) { result[i] <- which.max(predict$net.result[i,]) }

If you call back result, it will list the columns with the maximum value. Now we can change the column numbers to reflect the name of the species using:

for (i in 1:150) { if (result[i]==1) {result[i] = “setosa”} }

for (i in 1:150) { if (result[i]==2) {result[i] = “versicolor”} }

for (i in 1:150) { if (result[i]==3) {result[i] = “virginica”} }

Finally, we can combine the actual data with the predicted data using:

comparison <- iris

comparison$Predicted <- result

You can call back comparison to show the results of the actual species and the predicted species using the neural network.

As you will hopefully see, the neural network was able to correctly predict the majority of species using only the initial training set of 50 rows.