Skip to content

Instantly share code, notes, and snippets.

@knbknb
Last active August 16, 2018 09:47
Show Gist options
  • Save knbknb/1d17caecd9b800d5148a30d537013668 to your computer and use it in GitHub Desktop.
Save knbknb/1d17caecd9b800d5148a30d537013668 to your computer and use it in GitHub Desktop.
Rosenblatt's perceptron - this R code is from 2013, based on a forum post by a chinese user. Online course "learning from data", instructor Prof Yaser Abu-Mostafa # http://work.caltech.edu/telecourse.html
# https://gist.github.com/knbknb/1d17caecd9b800d5148a30d537013668
# Thu Aug 16 11:24:05 2018 ------------------------------
# Rosenblatt's perceptron
# this is from 2013, based on a forum post by a chinese user (don't remember his name)
# "learning from data" course, Prof Yaser Abu-Mostafa
# http://work.caltech.edu/telecourse.html
# create a xy-plot and an animated gif visualizing the training process
data(iris)
# simplify dataset 2 features, 2 classes
dd <- iris[iris$Species != "versicolor", -(3:4)]
# this point (in lower left of plot) breaks linear separation (at least w/o intercept).
# leave it in and the algorithm needs 275 steps to find a decision boundary,
# comment it out and it needs only 18.
# dd <- dd[-42, ]
dm <- data.matrix(dd[, 1:2])
dm <- cbind(dm, 1) # to add intercept to the separating plane
# binary classification, vector of class attribute is numeric
# setosa 1
# virginica -1
dc <- rep(1, nrow(dm))
dc[dd$Species == "virginica"] <- -1
trainPerceptron <- function(dm, dc) {
result <- list()
oldW <- c()
w <- rep(0, ncol(dm))
while (!identical(w, oldW)) {
oldW <- w
for (i in 1:nrow(dm)) {
# # the perceptron learning rule
pred <- sign(dm[i,] %*% w)
w = w + (dc[i] - pred) * dm[i, ]
}
# cat(w, "\n")
result <- c(result, list(w))
}
result
}
plotPerceptronSteps <- function(pcResult, dm, dc, steps) {
for (s in steps) {
w <- pcResult[[s]]
plot(dm[,1:2], main=paste("step", s), col=ifelse(dc > 0, 1, 2),
sub=paste(c("weights: ", w), collapse=' '))
abline(-w[3] / w[2], -w[1] / w[2])
}
}
pc <- trainPerceptron(dm, dc)
# how many iterations, how many frames in the animated GIF
nsteps <- length(pc)
# test: plot a single png
# plotPerceptronSteps(pc, dm, dc, nsteps)
# png("perceptron-biased--iris-2D-2class.png", width=600, height=600)
# par(mfrow=c(3,3))
steps <- seq(1,nsteps, by=1)
# Requires Imagemagick
animation::saveGIF(
{
plotPerceptronSteps(pc, dm, dc, steps)
},
movie.name = sprintf("perceptron-%s-steps--without-point42.gif", max(steps)),
interval = .1, # 10 ms frame delay
loop=1,
outdir = getwd()
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment