Brief history of neural networks

Binary classification using perceptron

The iris data set

old.par <- par()
pairs(
  x = iris[, 1:4],
  col = as.numeric(iris$Species),
  cex = 0.3,
  lower.panel = NULL,
  oma = c(15, 3, 3, 3)
)
par(xpd = TRUE)
legend(
  "bottom",
  legend = unique(iris$Species),
  col = as.numeric(iris$Species),
  horiz = TRUE,
  fill = unique(iris$Species),
  bty = "n"
)

par(old.par)

Preparing the data set

X <- iris[, 3:5]
X$f.class <- 1
X[X$Species == "setosa", ]$f.class <- -1
# The output
Y <- X$f.class
X <- X[, c(1, 2)]
colnames(X) <- c("length", "width")
n.samples <- 2*nrow(X)/3
trn <- sample.int(nrow(X), n.samples, replace = FALSE)
train.x <- X[trn, ]
train.y <- Y[trn]

test.x <- X[setdiff(1:nrow(X), trn), ]
test.y <- Y[setdiff(1:nrow(X), trn)]

Building the perceptron - 1

#'
#' Adjust weight using one case of training data. The data is passed as a vector
#' r. First two components of r are the inputs and the third one is the label.
adjust_wts <- function(r) {
  # Extract input and output.
  x <- as.numeric(r[1:2])
  y <- as.numeric(r[3])
  
  # Evaluate the output. In this case, it is just w[1] + x[1]w[2] + x[2]w[3].
  z <- x %*% w[2:length(w)] + w[1]
  y.pred <- ifelse(z < 0, -1, 1)
  
  # Update the global weights vector if the prediction is not correct.
  assign("w", w + c(eta * (y - y.pred)) * c(1, x), envir = .GlobalEnv)
}

Building the perceptron - 2

# Initial weights, all zeros.
w <- rep(0, dim(X)[2] + 1)
# Training rate.
eta <- 1

n.iter <- 1
ignore <- lapply(1:n.iter, function(n) apply(data.frame(X=X, Y=Y), 1, adjust_wts))

How good is our classifier?

perceptron.predict <- function(r) {
  x <- c(1, r)
  ifelse(w %*% x < 0, -1, 1)
}

test.pred <- apply(test.x, 1, perceptron.predict)
comparison <- data.frame(actual = test.y, predicted = test.pred)
cat(paste("Number of wrong classifications =", 
          nrow(comparison[comparison$actual != comparison$predicted,])))
## Number of wrong classifications = 20

Can we improve the classification by another iteration?

ignore <- lapply(1:n.iter, function(n) apply(data.frame(X=X, Y=Y), 1, adjust_wts))
test.pred <- apply(test.x, 1, perceptron.predict)
comparison <- data.frame(actual = test.y, predicted = test.pred)
cat(paste("Number of wrong classifications =", 
          nrow(comparison[comparison$actual != comparison$predicted, ])))
## Number of wrong classifications = 0

Closing remarks