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/randomForest-parcial-cancer-breast
2.1. Información inicial de la data
data <- read.csv("https://raw.githubusercontent.com/cnahuina/data-mineria/master/breast-cancer.csv")
De acuerdo a ello se visualiza lo siguiente:
Se tiene 569 datos de 33 variables.
En el cual se rescatar que el identificador es de tipo int, el cual debe cambiar a factor, por lo mismo que es un identificador, también se puede rescatar la columna “X” con valores de “NA”
str(data)
## 'data.frame': 569 obs. of 33 variables:
## $ id : int 842302 842517 84300903 84348301 84358402 843786 844359 84458202 844981 84501001 ...
## $ diagnosis : Factor w/ 2 levels "B","M": 2 2 2 2 2 2 2 2 2 2 ...
## $ radius_mean : num 18 20.6 19.7 11.4 20.3 ...
## $ texture_mean : num 10.4 17.8 21.2 20.4 14.3 ...
## $ perimeter_mean : num 122.8 132.9 130 77.6 135.1 ...
## $ area_mean : num 1001 1326 1203 386 1297 ...
## $ smoothness_mean : num 0.1184 0.0847 0.1096 0.1425 0.1003 ...
## $ compactness_mean : num 0.2776 0.0786 0.1599 0.2839 0.1328 ...
## $ concavity_mean : num 0.3001 0.0869 0.1974 0.2414 0.198 ...
## $ concave.points_mean : num 0.1471 0.0702 0.1279 0.1052 0.1043 ...
## $ symmetry_mean : num 0.242 0.181 0.207 0.26 0.181 ...
## $ fractal_dimension_mean : num 0.0787 0.0567 0.06 0.0974 0.0588 ...
## $ radius_se : num 1.095 0.543 0.746 0.496 0.757 ...
## $ texture_se : num 0.905 0.734 0.787 1.156 0.781 ...
## $ perimeter_se : num 8.59 3.4 4.58 3.44 5.44 ...
## $ area_se : num 153.4 74.1 94 27.2 94.4 ...
## $ smoothness_se : num 0.0064 0.00522 0.00615 0.00911 0.01149 ...
## $ compactness_se : num 0.049 0.0131 0.0401 0.0746 0.0246 ...
## $ concavity_se : num 0.0537 0.0186 0.0383 0.0566 0.0569 ...
## $ concave.points_se : num 0.0159 0.0134 0.0206 0.0187 0.0188 ...
## $ symmetry_se : num 0.03 0.0139 0.0225 0.0596 0.0176 ...
## $ fractal_dimension_se : num 0.00619 0.00353 0.00457 0.00921 0.00511 ...
## $ radius_worst : num 25.4 25 23.6 14.9 22.5 ...
## $ texture_worst : num 17.3 23.4 25.5 26.5 16.7 ...
## $ perimeter_worst : num 184.6 158.8 152.5 98.9 152.2 ...
## $ area_worst : num 2019 1956 1709 568 1575 ...
## $ smoothness_worst : num 0.162 0.124 0.144 0.21 0.137 ...
## $ compactness_worst : num 0.666 0.187 0.424 0.866 0.205 ...
## $ concavity_worst : num 0.712 0.242 0.45 0.687 0.4 ...
## $ concave.points_worst : num 0.265 0.186 0.243 0.258 0.163 ...
## $ symmetry_worst : num 0.46 0.275 0.361 0.664 0.236 ...
## $ fractal_dimension_worst: num 0.1189 0.089 0.0876 0.173 0.0768 ...
## $ X : logi NA NA NA NA NA NA ...
data$id <- as.factor(data$id)
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/randomForest-parcial-cancer-breast
summary(data)
## id diagnosis radius_mean texture_mean perimeter_mean
## 8670 : 1 B:357 Min. : 6.981 Min. : 9.71 Min. : 43.79
## 8913 : 1 M:212 1st Qu.:11.700 1st Qu.:16.17 1st Qu.: 75.17
## 8915 : 1 Median :13.370 Median :18.84 Median : 86.24
## 9047 : 1 Mean :14.127 Mean :19.29 Mean : 91.97
## 85715 : 1 3rd Qu.:15.780 3rd Qu.:21.80 3rd Qu.:104.10
## 86208 : 1 Max. :28.110 Max. :39.28 Max. :188.50
## (Other):563
## area_mean smoothness_mean compactness_mean concavity_mean
## Min. : 143.5 Min. :0.05263 Min. :0.01938 Min. :0.00000
## 1st Qu.: 420.3 1st Qu.:0.08637 1st Qu.:0.06492 1st Qu.:0.02956
## Median : 551.1 Median :0.09587 Median :0.09263 Median :0.06154
## Mean : 654.9 Mean :0.09636 Mean :0.10434 Mean :0.08880
## 3rd Qu.: 782.7 3rd Qu.:0.10530 3rd Qu.:0.13040 3rd Qu.:0.13070
## Max. :2501.0 Max. :0.16340 Max. :0.34540 Max. :0.42680
##
## concave.points_mean symmetry_mean fractal_dimension_mean radius_se
## Min. :0.00000 Min. :0.1060 Min. :0.04996 Min. :0.1115
## 1st Qu.:0.02031 1st Qu.:0.1619 1st Qu.:0.05770 1st Qu.:0.2324
## Median :0.03350 Median :0.1792 Median :0.06154 Median :0.3242
## Mean :0.04892 Mean :0.1812 Mean :0.06280 Mean :0.4052
## 3rd Qu.:0.07400 3rd Qu.:0.1957 3rd Qu.:0.06612 3rd Qu.:0.4789
## Max. :0.20120 Max. :0.3040 Max. :0.09744 Max. :2.8730
##
## texture_se perimeter_se area_se smoothness_se
## Min. :0.3602 Min. : 0.757 Min. : 6.802 Min. :0.001713
## 1st Qu.:0.8339 1st Qu.: 1.606 1st Qu.: 17.850 1st Qu.:0.005169
## Median :1.1080 Median : 2.287 Median : 24.530 Median :0.006380
## Mean :1.2169 Mean : 2.866 Mean : 40.337 Mean :0.007041
## 3rd Qu.:1.4740 3rd Qu.: 3.357 3rd Qu.: 45.190 3rd Qu.:0.008146
## Max. :4.8850 Max. :21.980 Max. :542.200 Max. :0.031130
##
## compactness_se concavity_se concave.points_se symmetry_se
## Min. :0.002252 Min. :0.00000 Min. :0.000000 Min. :0.007882
## 1st Qu.:0.013080 1st Qu.:0.01509 1st Qu.:0.007638 1st Qu.:0.015160
## Median :0.020450 Median :0.02589 Median :0.010930 Median :0.018730
## Mean :0.025478 Mean :0.03189 Mean :0.011796 Mean :0.020542
## 3rd Qu.:0.032450 3rd Qu.:0.04205 3rd Qu.:0.014710 3rd Qu.:0.023480
## Max. :0.135400 Max. :0.39600 Max. :0.052790 Max. :0.078950
##
## fractal_dimension_se radius_worst texture_worst perimeter_worst
## Min. :0.0008948 Min. : 7.93 Min. :12.02 Min. : 50.41
## 1st Qu.:0.0022480 1st Qu.:13.01 1st Qu.:21.08 1st Qu.: 84.11
## Median :0.0031870 Median :14.97 Median :25.41 Median : 97.66
## Mean :0.0037949 Mean :16.27 Mean :25.68 Mean :107.26
## 3rd Qu.:0.0045580 3rd Qu.:18.79 3rd Qu.:29.72 3rd Qu.:125.40
## Max. :0.0298400 Max. :36.04 Max. :49.54 Max. :251.20
##
## area_worst smoothness_worst compactness_worst concavity_worst
## Min. : 185.2 Min. :0.07117 Min. :0.02729 Min. :0.0000
## 1st Qu.: 515.3 1st Qu.:0.11660 1st Qu.:0.14720 1st Qu.:0.1145
## Median : 686.5 Median :0.13130 Median :0.21190 Median :0.2267
## Mean : 880.6 Mean :0.13237 Mean :0.25427 Mean :0.2722
## 3rd Qu.:1084.0 3rd Qu.:0.14600 3rd Qu.:0.33910 3rd Qu.:0.3829
## Max. :4254.0 Max. :0.22260 Max. :1.05800 Max. :1.2520
##
## concave.points_worst symmetry_worst fractal_dimension_worst X
## Min. :0.00000 Min. :0.1565 Min. :0.05504 Mode:logical
## 1st Qu.:0.06493 1st Qu.:0.2504 1st Qu.:0.07146 NA's:569
## Median :0.09993 Median :0.2822 Median :0.08004
## Mean :0.11461 Mean :0.2901 Mean :0.08395
## 3rd Qu.:0.16140 3rd Qu.:0.3179 3rd Qu.:0.09208
## Max. :0.29100 Max. :0.6638 Max. :0.20750
##
2.3. Exploración de la data
Se analizan los valores outliers de la data en general.
Se refleja los outliers en la mayoría de las variables.
boxplot(data)
2.4 Verificación de la calidad de la data
Se realiza un gráfico en el cual nos permita visualizar el patrón de comportamiento de los NA’s
#install.packages("VIM")
library(VIM)
## Warning: package 'VIM' was built under R version 3.6.3
## Loading required package: colorspace
## Loading required package: grid
## Loading required package: data.table
## VIM is ready to use.
## Since version 4.0.0 the GUI is in its own package VIMGUI.
##
## Please use the package to use the new (and old) GUI.
## Suggestions and bug-reports can be submitted at: https://github.com/alexkowa/VIM/issues
##
## Attaching package: 'VIM'
## The following object is masked from 'package:datasets':
##
## sleep
miss <- aggr(data, col=c('green', 'red'),
ylab = c("Histograma de NAs", "Patrón"))
En el cuadro de proporcion de missings podemos observar que la variable X pasa del 5% , en consecuencia podría no tomarse en cuenta como variable de uso.
summary(miss)
##
## Missings per variable:
## Variable Count
## id 0
## diagnosis 0
## radius_mean 0
## texture_mean 0
## perimeter_mean 0
## area_mean 0
## smoothness_mean 0
## compactness_mean 0
## concavity_mean 0
## concave.points_mean 0
## symmetry_mean 0
## fractal_dimension_mean 0
## radius_se 0
## texture_se 0
## perimeter_se 0
## area_se 0
## smoothness_se 0
## compactness_se 0
## concavity_se 0
## concave.points_se 0
## symmetry_se 0
## fractal_dimension_se 0
## radius_worst 0
## texture_worst 0
## perimeter_worst 0
## area_worst 0
## smoothness_worst 0
## compactness_worst 0
## concavity_worst 0
## concave.points_worst 0
## symmetry_worst 0
## fractal_dimension_worst 0
## X 569
##
## Missings in combinations of variables:
## Combinations Count
## 0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:1 569
## Percent
## 100
3.1. Seleccionar la data
Como se mostró anteriormente, la última columna no se toma en cuenta y la otra variable a no tomar en cuenta es el identificador.
data <- data[,2:32]
3.2. Limpiar la data
Capar los valores extremos, es decir, localizar todo lo que cayera fuera del bigote más arriba o más abajo de 1,5 veces de el rango intercuartilico. Y decidir capar dichas obsevaciones sustituyendolas con el percentil número 5. En el caso de los que están debajo del bigote inferior y con el percentil 95 con los que están por encima del bigote superior.
replace_outliers <- function(x, removeNA = TRUE){
qrts <- quantile(x, probs = c(0.25, 0.75), na.rm = removeNA)
caps <- quantile(x, probs = c(.05, 0.95), na.rm = removeNA)
iqr <- qrts[2]-qrts[1]
h <- 1.5*iqr
x[x<qrts[1]-h] <- caps[1]
x[x>qrts[2]+h] <- caps[2]
x
}
data$radius_mean <- replace_outliers(data$radius_mean)
data$texture_mean <- replace_outliers(data$texture_mean)
data$perimeter_mean <- replace_outliers(data$perimeter_mean)
data$area_mean <- replace_outliers(data$area_mean)
data$smoothness_mean <- replace_outliers(data$smoothness_mean )
data$compactness_mean <- replace_outliers(data$compactness_mean)
data$concavity_mean <- replace_outliers(data$concavity_mean)
data$concave.points_mean <- replace_outliers(data$concave.points_mean)
data$symmetry_mean <- replace_outliers(data$symmetry_mean)
data$fractal_dimension_mean <- replace_outliers(data$fractal_dimension_mean)
data$radius_se <- replace_outliers(data$radius_se)
data$texture_se <- replace_outliers(data$texture_se )
data$perimeter_se <- replace_outliers(data$perimeter_se)
data$area_se <- replace_outliers(data$area_se)
data$smoothness_se <- replace_outliers(data$smoothness_se)
data$compactness_se <- replace_outliers(data$compactness_se)
data$concavity_se <- replace_outliers(data$concavity_se)
data$concave.points_se <- replace_outliers(data$concave.points_se)
data$symmetry_se <- replace_outliers(data$symmetry_se)
data$fractal_dimension_se <- replace_outliers(data$fractal_dimension_s)
data$radius_worst <- replace_outliers(data$radius_worst)
data$texture_worst <- replace_outliers(data$texture_worst )
data$perimeter_worst <- replace_outliers(data$perimeter_worst)
data$area_worst <- replace_outliers(data$area_worst)
data$smoothness_worst <- replace_outliers(data$smoothness_worst)
data$compactness_worst <- replace_outliers(data$compactness_worst)
data$concavity_worst <- replace_outliers(data$concavity_worst)
data$concave.points_worst <- replace_outliers(data$concave.points_worst)
data$symmetry_worst <- replace_outliers(data$symmetry_worst)
boxplot.stats(data$texture_mean)
## $stats
## [1] 9.71 16.17 18.84 21.80 29.97
##
## $n
## [1] 569
##
## $conf
## [1] 18.46709 19.21291
##
## $out
## numeric(0)
boxplot.stats(data$texture_mean)
## $stats
## [1] 9.71 16.17 18.84 21.80 29.97
##
## $n
## [1] 569
##
## $conf
## [1] 18.46709 19.21291
##
## $out
## numeric(0)
3.3. Construir data
Detallamos las librerías que haremos uso
# install.packages("caret")
library(caret)
## Warning: package 'caret' was built under R version 3.6.3
## Loading required package: lattice
## Loading required package: ggplot2
# install.packages("nnet")
library(nnet)
## Warning: package 'nnet' was built under R version 3.6.3
# install.packages("ROCR")
library(ROCR)
## Warning: package 'ROCR' was built under R version 3.6.3
## Loading required package: gplots
##
## Attaching package: 'gplots'
## The following object is masked from 'package:stats':
##
## lowess
set.seed(2018)
tr.id <- createDataPartition(data$diagnosis, p = 0.7, list=F)
dim(data[-tr.id,])
## [1] 170 31
3.4. Integración de data
3.5. Formato de data
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 = 0.0004976115 => 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)
## diagnosis radius_mean texture_mean
## "M" "21.750" "29.97"
## perimeter_mean area_mean smoothness_mean
## "147.30" "1326.0" "0.133500"
## compactness_mean concavity_mean concave.points_mean
## "0.22840" "0.2810000" "0.152000"
## symmetry_mean fractal_dimension_mean radius_se
## "0.24590" "0.07871" "0.95952"
## texture_se perimeter_se area_se
## "2.4260" "7.0416" "115.800"
## smoothness_se compactness_se concavity_se
## "0.012644" "0.060630" "0.0823200"
## concave.points_se symmetry_se fractal_dimension_se
## "0.025270" "0.035460" "0.0080150"
## radius_worst texture_worst perimeter_worst
## "27.320" "41.85" "186.80"
## area_worst smoothness_worst compactness_worst
## "2009.6" "0.188300" "0.62470"
## concavity_worst concave.points_worst symmetry_worst
## "0.772700" "0.291000" "0.41540"
## fractal_dimension_worst
## "0.20750"
Obtenemos que el máximo es 2009.6 de la variable area_worst
rang = 1/max(|variables|)
r <- 1/2009.6
r
## [1] 0.0004976115
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: 127
## initial value 276.586013
## iter 10 value 92.924969
## iter 20 value 32.248265
## iter 30 value 27.439984
## iter 40 value 26.888863
## iter 50 value 26.501218
## iter 60 value 26.382887
## iter 70 value 26.291030
## iter 80 value 26.244505
## iter 90 value 26.191529
## iter 100 value 26.142551
## iter 110 value 26.091683
## iter 120 value 25.999627
## iter 130 value 25.900472
## iter 140 value 25.825036
## iter 150 value 25.750867
## iter 160 value 25.305255
## iter 170 value 24.683780
## iter 180 value 24.073976
## iter 190 value 21.816202
## iter 200 value 20.994682
## iter 210 value 20.623561
## iter 220 value 20.576498
## iter 230 value 20.543924
## iter 240 value 20.533473
## iter 250 value 20.529129
## iter 260 value 20.527856
## iter 270 value 20.527620
## iter 280 value 20.527505
## iter 290 value 20.527460
## iter 300 value 20.527432
## final value 20.527422
## converged
mod
## a 30-3-1 network with 127 weights
## inputs: radius_mean texture_mean perimeter_mean area_mean smoothness_mean compactness_mean concavity_mean concave.points_mean symmetry_mean fractal_dimension_mean radius_se texture_se perimeter_se area_se smoothness_se compactness_se concavity_se concave.points_se symmetry_se fractal_dimension_se radius_worst texture_worst perimeter_worst area_worst smoothness_worst compactness_worst concavity_worst concave.points_worst symmetry_worst fractal_dimension_worst
## output(s): diagnosis
## options were - skip-layer connections entropy fitting decay=0.001
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 104 3
## M 0 63
Evaluamos que tan bueno es el modelo. En el caso de que el árbol no haya sido podado.
acc <- (104+63)/170
acc
## [1] 0.9823529
error_rate <- 1 - acc
error_rate
## [1] 0.01764706
Tenemos entonces una precisión de predicción del 95.45% y un error de predicción del 1.76%.
pred2 <- predict(mod, newdata = data[-tr.id,],
type = "raw")
perf <- performance(prediction(pred2, data[-tr.id, "diagnosis"]),
"tpr", "fpr")
plot(perf, main = "Curva ROC modelo de clasificación nnet")
lines(par()$usr[1:2],par()$usr[3:4])
A continuación se muestran los links con las demás herramientas que se usan para clasificar:
[1] Árboles-rpart: https://rpubs.com/Moki-chan/rpart-parcial-breast-mama
[2] randomForest: https://rpubs.com/Moki-chan/randomForest-parcial-cancer-breast
[3] Knn: https://rpubs.com/Moki-chan/knn-parcial-parcial-cancer-breast
[4] Naive-bayes: https://rpubs.com/Moki-chan/naive-bayes-parcial-breast-mama
[5] Logistic Regresion https://rpubs.com/Moki-chan/log-reg-parcial-breast-mama