Neual networks are modeled after biological neural networks and attempt to allow computers to learn in a similar manner to humans - reinforrment learning.
Use cases: Pattern Recognition Time Series Predictions Signal Processing Anomaly Detaction *Control
Human brains: dendrites(receiving input), axons(producing electrical signal output)
Neural Networks attemp to solve problems that would normally be easy for humans but hard for computers!
A perceptron consists of one or more inputs, a processor and a single output.
A perceptron follows the “feed-forward” model, meaning input are sent into the neuron, are processed, and result in an output.
A perceptron process follows 4 main steps: Receive inputs Weight inputs Sum inputs Generate outputs
#install.packages'Mass')
library(MASS)
head(Boston)
## crim zn indus chas nox rm age dis rad tax ptratio black
## 1 0.00632 18 2.31 0 0.538 6.575 65.2 4.0900 1 296 15.3 396.90
## 2 0.02731 0 7.07 0 0.469 6.421 78.9 4.9671 2 242 17.8 396.90
## 3 0.02729 0 7.07 0 0.469 7.185 61.1 4.9671 2 242 17.8 392.83
## 4 0.03237 0 2.18 0 0.458 6.998 45.8 6.0622 3 222 18.7 394.63
## 5 0.06905 0 2.18 0 0.458 7.147 54.2 6.0622 3 222 18.7 396.90
## 6 0.02985 0 2.18 0 0.458 6.430 58.7 6.0622 3 222 18.7 394.12
## lstat medv
## 1 4.98 24.0
## 2 9.14 21.6
## 3 4.03 34.7
## 4 2.94 33.4
## 5 5.33 36.2
## 6 5.21 28.7
str(Boston)
## 'data.frame': 506 obs. of 14 variables:
## $ crim : num 0.00632 0.02731 0.02729 0.03237 0.06905 ...
## $ zn : num 18 0 0 0 0 0 12.5 12.5 12.5 12.5 ...
## $ indus : num 2.31 7.07 7.07 2.18 2.18 2.18 7.87 7.87 7.87 7.87 ...
## $ chas : int 0 0 0 0 0 0 0 0 0 0 ...
## $ nox : num 0.538 0.469 0.469 0.458 0.458 0.458 0.524 0.524 0.524 0.524 ...
## $ rm : num 6.58 6.42 7.18 7 7.15 ...
## $ age : num 65.2 78.9 61.1 45.8 54.2 58.7 66.6 96.1 100 85.9 ...
## $ dis : num 4.09 4.97 4.97 6.06 6.06 ...
## $ rad : int 1 2 2 3 3 3 5 5 5 5 ...
## $ tax : num 296 242 242 222 222 222 311 311 311 311 ...
## $ ptratio: num 15.3 17.8 17.8 18.7 18.7 18.7 15.2 15.2 15.2 15.2 ...
## $ black : num 397 397 393 395 397 ...
## $ lstat : num 4.98 9.14 4.03 2.94 5.33 ...
## $ medv : num 24 21.6 34.7 33.4 36.2 28.7 22.9 27.1 16.5 18.9 ...
any(is.na(Boston))
## [1] FALSE
data <- Boston
# scaling and normalizeing data
maxs <- apply(data, 2, max)
maxs
## crim zn indus chas nox rm age dis
## 88.9762 100.0000 27.7400 1.0000 0.8710 8.7800 100.0000 12.1265
## rad tax ptratio black lstat medv
## 24.0000 711.0000 22.0000 396.9000 37.9700 50.0000
mins <- apply(data, 2, min)
mins
## crim zn indus chas nox rm age
## 0.00632 0.00000 0.46000 0.00000 0.38500 3.56100 2.90000
## dis rad tax ptratio black lstat medv
## 1.12960 1.00000 187.00000 12.60000 0.32000 1.73000 5.00000
help(‘scale’)
scaled.data <-scale(data, center=mins, scale = maxs - mins)
scaled <- as.data.frame(scaled.data)
head(scaled)
## crim zn indus chas nox rm age
## 1 0.0000000000 0.18 0.06781525 0 0.3148148 0.5775053 0.6416066
## 2 0.0002359225 0.00 0.24230205 0 0.1728395 0.5479977 0.7826982
## 3 0.0002356977 0.00 0.24230205 0 0.1728395 0.6943859 0.5993821
## 4 0.0002927957 0.00 0.06304985 0 0.1502058 0.6585553 0.4418126
## 5 0.0007050701 0.00 0.06304985 0 0.1502058 0.6871048 0.5283213
## 6 0.0002644715 0.00 0.06304985 0 0.1502058 0.5497222 0.5746653
## dis rad tax ptratio black lstat medv
## 1 0.2692031 0.00000000 0.20801527 0.2872340 1.0000000 0.08967991 0.4222222
## 2 0.3489620 0.04347826 0.10496183 0.5531915 1.0000000 0.20447020 0.3688889
## 3 0.3489620 0.04347826 0.10496183 0.5531915 0.9897373 0.06346578 0.6600000
## 4 0.4485446 0.08695652 0.06679389 0.6489362 0.9942761 0.03338852 0.6311111
## 5 0.4485446 0.08695652 0.06679389 0.6489362 1.0000000 0.09933775 0.6933333
## 6 0.4485446 0.08695652 0.06679389 0.6489362 0.9929901 0.09602649 0.5266667
head(Boston)
## crim zn indus chas nox rm age dis rad tax ptratio black
## 1 0.00632 18 2.31 0 0.538 6.575 65.2 4.0900 1 296 15.3 396.90
## 2 0.02731 0 7.07 0 0.469 6.421 78.9 4.9671 2 242 17.8 396.90
## 3 0.02729 0 7.07 0 0.469 7.185 61.1 4.9671 2 242 17.8 392.83
## 4 0.03237 0 2.18 0 0.458 6.998 45.8 6.0622 3 222 18.7 394.63
## 5 0.06905 0 2.18 0 0.458 7.147 54.2 6.0622 3 222 18.7 396.90
## 6 0.02985 0 2.18 0 0.458 6.430 58.7 6.0622 3 222 18.7 394.12
## lstat medv
## 1 4.98 24.0
## 2 9.14 21.6
## 3 4.03 34.7
## 4 2.94 33.4
## 5 5.33 36.2
## 6 5.21 28.7
library(caTools)
split <- sample.split(scaled$medv, SplitRatio = 0.7)
train <- subset(scaled, split == T)
test <- subset(scaled, split == F)
head(train)
## crim zn indus chas nox rm age
## 1 0.0000000000 0.180 0.06781525 0 0.3148148 0.5775053 0.6416066
## 3 0.0002356977 0.000 0.24230205 0 0.1728395 0.6943859 0.5993821
## 4 0.0002927957 0.000 0.06304985 0 0.1502058 0.6585553 0.4418126
## 5 0.0007050701 0.000 0.06304985 0 0.1502058 0.6871048 0.5283213
## 6 0.0002644715 0.000 0.06304985 0 0.1502058 0.5497222 0.5746653
## 7 0.0009213230 0.125 0.27162757 0 0.2860082 0.4696302 0.6560247
## dis rad tax ptratio black lstat medv
## 1 0.2692031 0.00000000 0.20801527 0.2872340 1.0000000 0.08967991 0.4222222
## 3 0.3489620 0.04347826 0.10496183 0.5531915 0.9897373 0.06346578 0.6600000
## 4 0.4485446 0.08695652 0.06679389 0.6489362 0.9942761 0.03338852 0.6311111
## 5 0.4485446 0.08695652 0.06679389 0.6489362 1.0000000 0.09933775 0.6933333
## 6 0.4485446 0.08695652 0.06679389 0.6489362 0.9929901 0.09602649 0.5266667
## 7 0.4029226 0.17391304 0.23664122 0.2765957 0.9967220 0.29525386 0.3977778
# install.packages('neuralnet')
library(neuralnet)
n <- names(train)
n
## [1] "crim" "zn" "indus" "chas" "nox" "rm" "age"
## [8] "dis" "rad" "tax" "ptratio" "black" "lstat" "medv"
# this is just so you don't have to copy paste all the column names
f <- as.formula(paste('medv ~', paste(n[!n %in% "medv"], collapse = '+')))
# Train
nn <- neuralnet(f, data=train, hidden = c(5, 3), linear.output = T)
# Plot (it's like a black box)
plot(nn)
predicted.nn.value <- compute(nn, test[1:13])
str(predicted.nn.value)
## List of 2
## $ neurons :List of 3
## ..$ : num [1:139, 1:14] 1 1 1 1 1 1 1 1 1 1 ...
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr [1:139] "2" "8" "11" "12" ...
## .. .. ..$ : chr [1:14] "" "crim" "zn" "indus" ...
## ..$ : num [1:139, 1:6] 1 1 1 1 1 1 1 1 1 1 ...
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr [1:139] "2" "8" "11" "12" ...
## .. .. ..$ : NULL
## ..$ : num [1:139, 1:4] 1 1 1 1 1 1 1 1 1 1 ...
## .. ..- attr(*, "dimnames")=List of 2
## .. .. ..$ : chr [1:139] "2" "8" "11" "12" ...
## .. .. ..$ : NULL
## $ net.result: num [1:139, 1] 0.449 0.314 0.324 0.325 0.299 ...
## ..- attr(*, "dimnames")=List of 2
## .. ..$ : chr [1:139] "2" "8" "11" "12" ...
## .. ..$ : NULL
# Because we scaled our data, we have to try to use the real data
# This will unscale your data
true.predictions <- predicted.nn.value$net.result*(max(data$medv)-min(data$medv)) + min(data$medv)
# convert the test data
test.r <- (test$medv) * (max(data$medv)-min(data$medv)) +min(data$medv)
MSE.nn <- sum((test.r - true.predictions)^2)/nrow(test)
MSE.nn
## [1] 16.90704
error.df <- data.frame(test.r, true.predictions)
head(error.df)
## test.r true.predictions
## 2 21.6 25.22378
## 8 27.1 19.12695
## 11 15.0 19.57734
## 12 18.9 19.60570
## 15 18.2 18.44388
## 16 19.9 18.95035
# Visualize prediction
library(ggplot2)
ggplot(error.df, aes(x=test.r, y=true.predictions)) + geom_point() + stat_smooth()
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'