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.
Este paso se detalla en el primer documento: https://rpubs.com/Moki-chan/rpart-parcial-breast-mama
2.1. Información inicial de la data
data <- read.csv("https://raw.githubusercontent.com/cnahuina/data-mineria/master/dataCancerFinal2.csv")
data <- data[,2:8]
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" ...
data$Diagnosis <- as.factor(data$Diagnosis)
2.2. Información inicial de la data
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)
set.seed(2018)
tr.id <- createDataPartition(data$Diagnosis, p = 0.7, list=F)
dim(data[-tr.id,])
## [1] 170 7
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:
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
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.
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.
acc <- (105+63)/170
acc
## [1] 0.9882353
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
##