# Redes Neurales y Maquinas de Soporte Vectoriales
# Fuente Brett-Lantz Machine Learning with R
# Traducido y adpatado por Luis A. George
# Capitulo 7
# Introduccion:Entendiendo las redes neurales
# Modelos basados en Una Red Neural Artificial (ANN)
# las relaciones entre un conjunto de entrada
# de señales y un conjunto de señales de salida usando
# un modelo derivado de nuestro entendimiento sobre como
# los cerebros biologicos responden a stimulos provenientes
# de sensores de entrada.Tal y como un cerebro usa una red
# de celulas interconectadas llamadas neuronas para crear
# un masivo procesador, ANN usa una red de neuronas
# artificiales o nodos para resolver problemas de aprendizaje.
# Las redes ANNs son muy versatiles
# y pueden aplicarse a casi cualquier
# tarea de aprendizaje de maquina: clasificacion,
# prediccion numerica,y hasta reconocimiento de
# patrones de manera no supervisada
# ANNs se aplican muy bien donde la data de entrada
# como la data de salida estan bien definidas
# o al menos son mas o menos simples, sin embargo
# el proceso que relaciona las entradas y las salidas
# es extremadamente complejo
# El modelo presentado trata de simular la fortaleza
# del concreto
# En el campo de la ingenieria es muy importante
# tener estimados precisos del rendimiento de los
# materiales de construccion.
# Paso 1 – recogiendo la data
# la misma fue donada por: UCI Machine Learning
# Data Repository (http://archive.ics.uci.edu/ml)
# # Establecemos nuestro directorio de trabajo
setwd("C:\\Users\\Luis\\Desktop\\Brett-Lantz")
# Paso 2 – explorando y preparando la data
concrete <- read.csv("C:\\Users\\Luis\\Desktop\\Brett-Lantz\\chapter_7\\concrete.csv")
str(concrete)
## 'data.frame': 1030 obs. of 9 variables:
## $ cement : num 141 169 250 266 155 ...
## $ slag : num 212 42.2 0 114 183.4 ...
## $ ash : num 0 124.3 95.7 0 0 ...
## $ water : num 204 158 187 228 193 ...
## $ superplastic: num 0 10.8 5.5 0 9.1 0 0 6.4 0 9 ...
## $ coarseagg : num 972 1081 957 932 1047 ...
## $ fineagg : num 748 796 861 670 697 ...
## $ age : int 28 14 28 28 28 90 7 56 28 28 ...
## $ strength : num 29.9 23.5 29.2 45.9 18.3 ...
# Nueve de las variables de la data frame corresponden
# a ocho caracteristicas y una de ellas contiene el resultado,
# sin embargo a primera vista un problema en la data
# aparece. Las redes neurales
# funcionan mejor cuando la data de entrada esta en un
# rango estrecho alrededor de cero, y en este caso,
# vemos valores con un rango que va desde cero
# a mas de mil.
# Es por lo tanto necesario escalar la data, para lo cual
# en este caso es mas recomendable normalizar la misma
# creamos una funcion para ejecutar la normalizacion:
normalize <- function(x){
return((x-min(x))/(max(x)-min(x)))
}
# una vez ejecutado el codigo de la funcion,
# la misma puede ser aplicada a cada columna
# de la data frame concrete, utilizando la
# funcion lapply(), veamos:
concrete_norm <- as.data.frame(lapply(concrete, normalize))
# Para confirmar que la funcion normalize ha sido
# aplicada correctamente:
str(concrete_norm)
## 'data.frame': 1030 obs. of 9 variables:
## $ cement : num 0.0897 0.1527 0.3379 0.3744 0.1205 ...
## $ slag : num 0.59 0.117 0 0.317 0.51 ...
## $ ash : num 0 0.621 0.478 0 0 ...
## $ water : num 0.653 0.292 0.524 0.848 0.571 ...
## $ superplastic: num 0 0.335 0.171 0 0.283 ...
## $ coarseagg : num 0.497 0.813 0.453 0.381 0.716 ...
## $ fineagg : num 0.388 0.507 0.67 0.191 0.258 ...
## $ age : num 0.0742 0.0357 0.0742 0.0742 0.0742 ...
## $ strength : num 0.343 0.264 0.335 0.542 0.199 ...
# los valores de la data se encuentran en el rango
# apropiado entre 0 y 1
# podemos comparar con la data que teniamos antes
# de ejecutar la funcion
str(concrete)
## 'data.frame': 1030 obs. of 9 variables:
## $ cement : num 141 169 250 266 155 ...
## $ slag : num 212 42.2 0 114 183.4 ...
## $ ash : num 0 124.3 95.7 0 0 ...
## $ water : num 204 158 187 228 193 ...
## $ superplastic: num 0 10.8 5.5 0 9.1 0 0 6.4 0 9 ...
## $ coarseagg : num 972 1081 957 932 1047 ...
## $ fineagg : num 748 796 861 670 697 ...
## $ age : int 28 14 28 28 28 90 7 56 28 28 ...
## $ strength : num 29.9 23.5 29.2 45.9 18.3 ...
# Siguiendo el precedente establecido por Yeh's
# en la publicacion original,
# haremos una particion de la data
# un set de entrenamiento 75 por ciento de los ejemplos
# y un set de prueba con 25 porciento.
# los archivos se encuentran en un orden aleatorio
# de tal manera que la division es simple
# en dos porciones:
concrete_train <-concrete_norm[1:773,]
concrete_test <- concrete_norm[774:1030,]
# Usaremos el set de entrenamiento (_train)para construir
# la red neural y el set de prueba (_test)
# para evaluar que tan bien el modelo generaliza
# resultados futuros
# Paso 3 – entrenando el modelo en la data
# Instalamos el paquete de R que contiene
# el algoritmo que usaremos "neuralnet"
library(neuralnet)
## Loading required package: grid
## Loading required package: MASS
# Empezaremos por entrenar la red mas simple
# o red de multiples capas con alimentacion
# hacia adelante con un solo nodo escondido:
concrete_model <- neuralnet(strength~cement+slag+ash+
water+superplastic+
coarseagg+fineagg+age,data=concrete_train)
# Podemos visualizar la topologia de la red neural
# usando la funcion plot() sobre el objeto modelo
# resultante;
plot(concrete_model)
# En este modelo sencillo, hay un solo nodo
# de entrada para cada una de las 8 variables,
# seguidas por un nodo oculto
# y un solo nodo de salida que predice
# la fortaleza del concreto.
# tambien se muestra los peso para c/u de la
# conexiones asi como los terminos bias
# (indicada por los nodes marcados con el
# numero 1). Los terminos bias son constantes
# numericas que permite que el valor indicado
# en los nodos pueda moverse hacia arriba
# o hacia abajo, muy parecido a lo que hace la
# intercepcion de y en una equacion linear.
# R tambien reporta la suma del cuadrado de
# los errores valor que entre mas pequeño
# mejor
# Paso 4 – evaluando el rendimiento del modelo
model_results <-compute(concrete_model,
concrete_test[1:8])
# La funcion compute() trabaja un tanto distinto
# a la funcion predict()
# que hemos utilizado antes. compute() devuelve una lista
# de 2 componentes: $neurons, la cual almacena las
# neuronas para cada capa en la red,
# y $net.result, la cual almacena los valores
# de las predicciones. Utlizaremos esta ultima:
predicted.strength <- model_results$net.result
# Debido a que este es un problema de prediccion
# numerica
# en vez de ser un problema de clasificacion
# no podemos usar la confussion matrix para
# examinar la precision del model. En vez de esto
# debemos usar la correlacion entre nuestro valor
# de prediccion de la fortaleza del concreto y los
# valores reales esto nos da una idea entre la
# asociacion linear de las variables.
cor(predicted.strength,concrete_test$strength)
## [,1]
## [1,] 0.8063425609
# Paso 5 – mejorando el rendimiento del modelo
# las redes con topologias mas complejas son
# capacez de aprender conceptos mas dificiles
# veamos que pasa cuando aumentamos
# el numero de nodos ocultos
# a cinco. usamos hidden = 5 parametros:
concrete_model2 <- neuralnet(strength~cement+
slag+ash+water+
superplastic+
coarseagg+
fineagg+age,
data = concrete_train,
hidden=5)
plot(concrete_model2)
model.results2 <-compute(concrete_model2,
concrete_test[1:8])
predicted.strength2 <- model.results2$net.result
cor(predicted.strength2,concrete_test$strength)
## [,1]
## [1,] 0.3904118871
# Es interesante mencionar que en su publicacion
# original Yeh un promedio de correlacion de 0.885
# usando una red neural muy similar a esta.