Neuronal Network [nnet]

Las redes neuronales o también llamadas sistemas anexionistas son un modelo de algorítmico que se basa en un gran conjunto de unidades neuronales simples, llamadas neuronas artificiales de forma que es muy similar al comportamiento de los axones de las neuronas que tenemos, cualquier organismo biológico. Cada unidad neuronal, se conecta con muchas otras y los enlaces entre ellas pueden incrementar o inhibir el estado de las neuronas que están adyacentes a la misma.

Cada unidad neuronal de forma individual opera empleando operaciones de suma. Puede existir una función limitadora, una función umbral en cada una de las conexiones en la propia unidad, de modo que la señal pueda sobrepasar un límite antes de propagarse a otra neurona.

Paso 1: Entendimiento del negocio

Este paso se detalla en el primer documento: https://rpubs.com/Moki-chan/rpart-parcial-breast-mama

Paso 2: Entendimiento de la data

2.1. Información inicial de la data

  • Carga de datos formato csv.
data <- read.csv("https://raw.githubusercontent.com/cnahuina/data-mineria/master/dataCancerFinal2.csv")
data <- data[,2:8]
  • Verificamos la carga, visualizando la estructura inical de las variables de manera general.
str(data)
## 'data.frame':    569 obs. of  7 variables:
##  $ PC1      : num  -9.29 -2.84 -6.79 -5.49 -4.93 ...
##  $ PC2      : num  -1.97 4.31 1.3 -7.33 2.08 ...
##  $ PC3      : num  1.355 0.628 0.266 1.655 -1.465 ...
##  $ PC4      : num  -3.546 -1.179 -1.153 0.371 -3.635 ...
##  $ PC5      : num  -1.5285 0.0643 -0.6834 0.1112 0.1196 ...
##  $ PC6      : num  -1.5151 0.0216 -0.6836 -1.2302 1.563 ...
##  $ Diagnosis: chr  "M" "M" "M" "M" ...
  • Cambio de la variable data.diagnosis como factor
data$Diagnosis <- as.factor(data$Diagnosis)

2.2. Información inicial de la data

  • Realizamos el resumen de la data total, de la siguente manera:

En el cual podemos visualizar lo siguiente:

Variables:

Esto se visualiza en el primer documento: https://rpubs.com/Moki-chan/breast-mama-rpart

3.3. Construir data

Detallamos las librerías que haremos uso

# install.packages("caret")
library(caret)
# install.packages("nnet")
library(nnet)
# install.packages("ROCR")
library(ROCR)
  • Establecemos una semilla
set.seed(2018)
  • Hacemos las particiones respectivas, la partición del entrenamiento.
tr.id <- createDataPartition(data$Diagnosis, p = 0.7, list=F)

dim(data[-tr.id,])
## [1] 170   7

Paso 4: Modelamiento

En este caso usaremos redes neuronales del paquete nnet, el cual tiene el mismo nombre de la funición. Que se encarga de realizar un algoritmo de clasificación.

  • diagnosis~. => varable dependiente~enfunción de todas las variables

  • data = data[tr.id,] => se detalla la data de entrenamiento de la data original

  • size = 3 => es un argumento que especifica el número de unidades de la capa más interna que la propia red neuronal debe utilizar por defecto de una red neuronal

  • maxit = 10000 => especifica el número de iteraciones máximas que debe tratar de llevar a cabo para intentar converger. El algoritmo separará si converge antes y si no ha encontrado convergencia del número máximo

  • decay = .001 => se utiliza para controlar el overfinting para no tener problemas de que la red neuronal se ajuste demasiado a nuestros datos originales a nuestro dataset entrenamiento.

  • rang = 6.04871320 => especificar el rango de pesos, iniciales que hay que asignar a la red neuronal, entre menor rango y rango.

Lo que se busca es lo siguiente:

  • rang* max(|variables|) = 1

Buscamos el máximo valor absoluto de las variables, de la siguiente manera:

 apply(data,2,max)
##            PC1            PC2            PC3            PC4            PC5 
## "  6.04871320"  " 5.93937460" " 3.795939104" " 3.934400913" " 4.920131784" 
##            PC6      Diagnosis 
## " 2.828250274"            "M"

Obtenemos que el máximo es 6.04871320 de la variable PC1

rang = 1/max(|variables|)

r <- 1/6.04871320
r
## [1] 0.1653244
  • na.action = na.omit => Omitirá los NA’s, para no tener problema alguno con el modelo.

  • skip=TRUE => Añadirá una capa adicional, apra intentar separar los nodos de entrada de los nodos de salida.

mod <- nnet(Diagnosis ~ ., data = data[tr.id,],
            size=3, maxit=10000,
            decay = .001, rang = r,
            na.action = na.omit, skip=TRUE) 
## # weights:  31
## initial  value 256.169781 
## iter  10 value 38.150320
## iter  20 value 27.805833
## iter  30 value 17.561629
## iter  40 value 13.613027
## iter  50 value 11.900100
## iter  60 value 11.538879
## iter  70 value 11.369800
## iter  80 value 11.320824
## iter  90 value 11.294046
## iter 100 value 11.279842
## iter 110 value 11.270495
## iter 120 value 11.265378
## iter 130 value 11.245969
## iter 140 value 11.200957
## iter 150 value 11.171266
## iter 160 value 11.166066
## final  value 11.165956 
## converged
mod
## a 6-3-1 network with 31 weights
## inputs: PC1 PC2 PC3 PC4 PC5 PC6 
## output(s): Diagnosis 
## options were - skip-layer connections  entropy fitting  decay=0.001
  • Graficamos la red neuronal

Para ello hacemos uso de lo siguiente:

require(neuralnet)
nn=neuralnet(Diagnosis~.,data=data[tr.id,], hidden = 3, act.fct = "logistic",
             linear.output = FALSE)
plot(nn)

Los nodos de la izquierda (es decir, los nodos de entrada) son las variables de datos en bruto. Las flechas en negro (y los números asociados) son los pesos en los que se puede pensar como cuánto contribuye esa variable al siguiente nodo. Las líneas azules son los pesos de sesgo. Los nodos del medio (es decir, cualquier cosa entre los nodos de entrada y salida) son sus nodos ocultos. Aquí es donde la analogía de la imagen ayuda. Cada uno de estos nodos constituye un componente que la red está aprendiendo a reconocer. El nodo de la extrema derecha (nodo(s) de salida) es la salida final de la red neuronal.

Paso 5: Evaluación

pred <- predict(mod, newdata = data[-tr.id,],
                type="class")
table <- table(data[-tr.id,]$Diagnosis,pred,dnn = c("Actual", "Predicho"))

table
##       Predicho
## Actual   B   M
##      B 105   2
##      M   0  63
  • Evaluamos que tan bueno es el modelo. En el caso de que el árbol no haya sido podado.

    1. Hallamos el accuracy.
acc <- (105+63)/170
acc
## [1] 0.9882353
  1. Evaluamos que tan bueno es el modelo. Para ello hacemos lo siguiente para poder hallar el error del modelo.
error_rate <- 1 - acc
error_rate
## [1] 0.01176471

Evaluamos demás cosas con la función confusionMatrix()

 medida <- confusionMatrix(table)
 
 medida
## Confusion Matrix and Statistics
## 
##       Predicho
## Actual   B   M
##      B 105   2
##      M   0  63
##                                           
##                Accuracy : 0.9882          
##                  95% CI : (0.9581, 0.9986)
##     No Information Rate : 0.6176          
##     P-Value [Acc > NIR] : <2e-16          
##                                           
##                   Kappa : 0.9749          
##                                           
##  Mcnemar's Test P-Value : 0.4795          
##                                           
##             Sensitivity : 1.0000          
##             Specificity : 0.9692          
##          Pos Pred Value : 0.9813          
##          Neg Pred Value : 1.0000          
##              Prevalence : 0.6176          
##          Detection Rate : 0.6176          
##    Detection Prevalence : 0.6294          
##       Balanced Accuracy : 0.9846          
##                                           
##        'Positive' Class : B               
##