Teoría
Una Red Neuronal Artificial (ANN) modela una relación entre un
conjunto de entradas y salidas, resolviendo un problema de
aprendizaje.
Ejemplos prácticos de la aplicación de Redes Neuronales son:
- Recomendación Netflix
- Feed Instagram o TikTok
- Determinar el número o letras escritas a mano.
Instalación de paquetes y llamar
librerías
#install.packages("neuralnet")
library(neuralnet)
set.seed(123)
Alimentar con ejemplos
examen <- c(20,10,30,20,80,30)
proyecto <- c(90,20,40,50,50,80)
estatus <- c(1,0,0,0,0,1)
df <- data.frame(examen,proyecto,estatus)
Generar Red Neuronal
red_neuronal <- neuralnet(estatus~., data=df)
plot(red_neuronal, rep="best")

# Crear datos de prueba
prueba_examen <- c(30,40,85)
prueba_proyecto <- c(85,50,40)
prueba <- data.frame(prueba_examen, prueba_proyecto)
modelo <- neuralnet(estatus ~ examen + proyecto,
data = df,
hidden = 2, # 2 neuronas ocultas
linear.output = FALSE)
plot(modelo, rep="best")

# Ahora s, usar tus datos de prueba
prueba_examen <- c(30,40,85)
prueba_proyecto <- c(85,50,40)
prueba <- data.frame(examen = prueba_examen, proyecto = prueba_proyecto)
# Hacer predicciones
prediccion <- compute(modelo, prueba)
# Revisar resultados en probabilidad
prediccion$net.result
## [,1]
## [1,] 0.3341435
## [2,] 0.3341435
## [3,] 0.3341434
# Convertir con umbral 0.5
probabilidad <- prediccion$net.result
resultado <- ifelse(probabilidad > 0.5, 1, 0)
resultado
## [,1]
## [1,] 0
## [2,] 0
## [3,] 0
df <- read.csv("C:/Users/Salvador/Downloads/cancer_de_mama (1).csv", stringsAsFactors = FALSE)
# Convertir diagnosis a 0/1 → M=1, B=0
df$diagnosis <- ifelse(df$diagnosis == "M", 1, 0)
Generar Red Neuronal
# install.packages("neuralnet")
library(neuralnet)
set.seed(123)
# --- 1) Selección de columnas y limpieza ---
cols <- c("diagnosis","radius_mean","texture_mean","perimeter_mean","area_mean","smoothness_mean")
df_nn <- na.omit(df[ , cols])
# Asegurar que la variable objetivo sea 0/1 numérica
# Edita los niveles según tu dataset ("M"/"B", "Malignant"/"Benign", etc.)
if (is.character(df_nn$diagnosis) || is.factor(df_nn$diagnosis)) {
df_nn$diagnosis <- ifelse(df_nn$diagnosis %in% c("M","Malignant","1"), 1, 0)
}
df_nn$diagnosis <- as.numeric(df_nn$diagnosis)
# --- 2) Escalado de predictores (0-1) para estabilidad del entrenamiento ---
rng01 <- function(x) (x - min(x)) / (max(x) - min(x))
Xcols <- setdiff(cols, "diagnosis")
df_nn[ , Xcols] <- lapply(df_nn[ , Xcols], rng01)
# (Opcional) Partición train/test
n <- nrow(df_nn)
idx <- sample(seq_len(n), size = floor(0.8*n))
train <- df_nn[idx, ]
test <- df_nn[-idx, ]
# --- 3) Entrenamiento con hiperparámetros más tolerantes ---
# Tips para evitar "did not converge":
# - reducir tamaño de la red (p.ej. hidden = c(4) o c(5,3) si ya escala)
# - aumentar stepmax
# - usar algorithm = "rprop+" (resilient backprop)
# - subir threshold (criterio de parada) ligeramente
formula_nn <- diagnosis ~ radius_mean + texture_mean + perimeter_mean + area_mean + smoothness_mean
red_neuronal <- neuralnet(
formula = formula_nn,
data = train,
hidden = c(4), # empieza simple; luego puedes probar c(5,3)
act.fct = "logistic",
linear.output = FALSE,
algorithm = "rprop+",
stepmax = 5e6,
threshold = 0.05,
lifesign = "minimal",
rep = 3
)
## hidden: 4 thresh: 0.05 rep: 1/3 steps: 277 error: 10.13928 time: 0.12 secs
## hidden: 4 thresh: 0.05 rep: 2/3 steps: 230 error: 10.31412 time: 0.09 secs
## hidden: 4 thresh: 0.05 rep: 3/3 steps: 323 error: 10.20643 time: 0.1 secs
# --- 4) Graficar solo si hay pesos (convergió al menos una réplica) ---
convergio <- length(red_neuronal$weights) > 0 &&
length(red_neuronal$weights[[1]]) > 0 &&
all(!sapply(red_neuronal$weights[[1]], is.null))
if (convergio) {
plot(red_neuronal, rep = which.min(red_neuronal$result.matrix["error", ]))
} else {
message("La red no convergió. Ajusta hidden/stepmax/threshold o verifica datos.")
}

# --- 5) Predicción y umbral ---
if (convergio) {
pred_prob <- compute(red_neuronal, test[ , Xcols])$net.result
pred_clas <- ifelse(pred_prob > 0.5, 1, 0)
# Métrica rápida (si tienes test$diagnosis)
if (nrow(test) > 0) {
acc <- mean(pred_clas == test$diagnosis)
cat(sprintf("\nAccuracy test: %.3f\n", acc))
}
# Ver predicciones de ejemplo
head(data.frame(prob = pred_prob, pred = pred_clas))
}
##
## Accuracy test: 0.930
## prob pred
## 1 0.9683749 1
## 9 0.9697277 1
## 15 0.9374889 1
## 17 0.6831005 1
## 18 0.9956391 1
## 28 0.9959247 1
# Crear datos de prueba (ejemplo con 3 pacientes)
prueba <- data.frame(
radius_mean = c(14.5, 20.1, 10.3),
texture_mean = c(20.2, 12.5, 18.4),
perimeter_mean = c(88.5, 130.1, 70.4),
area_mean = c(520, 1250, 320),
smoothness_mean = c(0.10, 0.09, 0.12)
)
# Predicciones
prediccion <- compute(red_neuronal, prueba)
probabilidad <- as.vector(prediccion$net.result)
resultado <- ifelse(probabilidad > 0.5, 1, 0)
# Mostrar resultados
data.frame(prueba, probabilidad, resultado)
## radius_mean texture_mean perimeter_mean area_mean smoothness_mean
## 1 14.5 20.2 88.5 520 0.10
## 2 20.1 12.5 130.1 1250 0.09
## 3 10.3 18.4 70.4 320 0.12
## probabilidad resultado
## 1 0.9999962 1
## 2 0.9999962 1
## 3 0.9999962 1
LS0tDQp0aXRsZTogIlJlZGVzIE5ldXJvbmFsZXMiDQphdXRob3I6ICJTYWx2YWRvciBOYXJ2YWV6IEEwMDU3MTg0OCINCmRhdGU6ICIyMDI1LTA4LTI1Ig0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IFRSVUUNCiAgICB0b2NfZmxvYXQ6IFRSVUUNCiAgICBjb2RlX2Rvd25sb2FkOiBUUlVFDQogICAgdGhlbWU6IGJvb3RzdHJhcA0KLS0tDQoNCjxjZW50ZXI+DQohW10oaHR0cHM6Ly9taXJvLm1lZGl1bS5jb20vdjIvcmVzaXplOmZpdDoxNDAwLzEqbHFEN1BBWkhMdzZvVHk2YmNzVlc5US5naWYpDQo8L2NlbnRlcj4NCg0KIyA8c3BhbiBzdHlsZT0iY29sb3I6bmF2eTsiPiBUZW9yw61hIDwvc3Bhbj4NCg0KVW5hIFJlZCBOZXVyb25hbCBBcnRpZmljaWFsIChBTk4pIG1vZGVsYSB1bmEgcmVsYWNpw7NuIGVudHJlIHVuIGNvbmp1bnRvIGRlIGVudHJhZGFzIHkgc2FsaWRhcywgcmVzb2x2aWVuZG8gdW4gcHJvYmxlbWEgZGUgYXByZW5kaXphamUuDQoNCkVqZW1wbG9zIHByw6FjdGljb3MgZGUgbGEgYXBsaWNhY2nDs24gZGUgUmVkZXMgTmV1cm9uYWxlcyBzb246DQoNCiogUmVjb21lbmRhY2nDs24gTmV0ZmxpeA0KKiBGZWVkIEluc3RhZ3JhbSBvIFRpa1Rvaw0KKiBEZXRlcm1pbmFyIGVsIG7Dum1lcm8gbyBsZXRyYXMgZXNjcml0YXMgYSBtYW5vLg0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpuYXZ5OyI+IEluc3RhbGFjacOzbiBkZSBwYXF1ZXRlcyB5IGxsYW1hciBsaWJyZXLDrWFzIDwvc3Bhbj4NCmBgYHtyfQ0KI2luc3RhbGwucGFja2FnZXMoIm5ldXJhbG5ldCIpDQpsaWJyYXJ5KG5ldXJhbG5ldCkNCnNldC5zZWVkKDEyMykNCmBgYA0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpuYXZ5OyI+IEFsaW1lbnRhciBjb24gZWplbXBsb3MgPC9zcGFuPg0KYGBge3J9DQpleGFtZW4gPC0gYygyMCwxMCwzMCwyMCw4MCwzMCkNCnByb3llY3RvIDwtIGMoOTAsMjAsNDAsNTAsNTAsODApDQplc3RhdHVzIDwtIGMoMSwwLDAsMCwwLDEpDQpkZiA8LSBkYXRhLmZyYW1lKGV4YW1lbixwcm95ZWN0byxlc3RhdHVzKQ0KYGBgDQoNCiMgPHNwYW4gc3R5bGU9ImNvbG9yOm5hdnk7Ij4gR2VuZXJhciBSZWQgTmV1cm9uYWwgPC9zcGFuPg0KYGBge3J9DQpyZWRfbmV1cm9uYWwgPC0gbmV1cmFsbmV0KGVzdGF0dXN+LiwgZGF0YT1kZikNCnBsb3QocmVkX25ldXJvbmFsLCByZXA9ImJlc3QiKQ0KYGBgDQpgYGB7cn0NCiMgQ3JlYXIgZGF0b3MgZGUgcHJ1ZWJhDQpwcnVlYmFfZXhhbWVuIDwtIGMoMzAsNDAsODUpDQpwcnVlYmFfcHJveWVjdG8gPC0gYyg4NSw1MCw0MCkNCnBydWViYSA8LSBkYXRhLmZyYW1lKHBydWViYV9leGFtZW4sIHBydWViYV9wcm95ZWN0bykNCg0KbW9kZWxvIDwtIG5ldXJhbG5ldChlc3RhdHVzIH4gZXhhbWVuICsgcHJveWVjdG8sDQogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZiwNCiAgICAgICAgICAgICAgICAgICAgaGlkZGVuID0gMiwgICAgICAgICAgIyAyIG5ldXJvbmFzIG9jdWx0YXMNCiAgICAgICAgICAgICAgICAgICAgbGluZWFyLm91dHB1dCA9IEZBTFNFKQ0KDQpwbG90KG1vZGVsbywgcmVwPSJiZXN0IikNCmBgYA0KYGBge3J9DQojIEFob3JhIHMsIHVzYXIgdHVzIGRhdG9zIGRlIHBydWViYQ0KcHJ1ZWJhX2V4YW1lbiA8LSBjKDMwLDQwLDg1KQ0KcHJ1ZWJhX3Byb3llY3RvIDwtIGMoODUsNTAsNDApDQpwcnVlYmEgPC0gZGF0YS5mcmFtZShleGFtZW4gPSBwcnVlYmFfZXhhbWVuLCBwcm95ZWN0byA9IHBydWViYV9wcm95ZWN0bykNCg0KIyBIYWNlciBwcmVkaWNjaW9uZXMNCnByZWRpY2Npb24gPC0gY29tcHV0ZShtb2RlbG8sIHBydWViYSkNCg0KIyBSZXZpc2FyIHJlc3VsdGFkb3MgZW4gcHJvYmFiaWxpZGFkDQpwcmVkaWNjaW9uJG5ldC5yZXN1bHQNCmBgYA0KYGBge3J9DQojIENvbnZlcnRpciBjb24gdW1icmFsIDAuNQ0KcHJvYmFiaWxpZGFkIDwtIHByZWRpY2Npb24kbmV0LnJlc3VsdA0KcmVzdWx0YWRvIDwtIGlmZWxzZShwcm9iYWJpbGlkYWQgPiAwLjUsIDEsIDApDQpyZXN1bHRhZG8NCmBgYA0KYGBge3J9DQpkZiA8LSByZWFkLmNzdigiQzovVXNlcnMvU2FsdmFkb3IvRG93bmxvYWRzL2NhbmNlcl9kZV9tYW1hICgxKS5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQoNCiMgQ29udmVydGlyIGRpYWdub3NpcyBhIDAvMSDihpIgTT0xLCBCPTANCmRmJGRpYWdub3NpcyA8LSBpZmVsc2UoZGYkZGlhZ25vc2lzID09ICJNIiwgMSwgMCkNCmBgYA0KDQojIDxzcGFuIHN0eWxlPSJjb2xvcjpuYXZ5OyI+IEdlbmVyYXIgUmVkIE5ldXJvbmFsIDwvc3Bhbj4NCmBgYHtyfQ0KIyBpbnN0YWxsLnBhY2thZ2VzKCJuZXVyYWxuZXQiKQ0KbGlicmFyeShuZXVyYWxuZXQpDQoNCnNldC5zZWVkKDEyMykNCg0KIyAtLS0gMSkgU2VsZWNjacOzbiBkZSBjb2x1bW5hcyB5IGxpbXBpZXphIC0tLQ0KY29scyA8LSBjKCJkaWFnbm9zaXMiLCJyYWRpdXNfbWVhbiIsInRleHR1cmVfbWVhbiIsInBlcmltZXRlcl9tZWFuIiwiYXJlYV9tZWFuIiwic21vb3RobmVzc19tZWFuIikNCmRmX25uIDwtIG5hLm9taXQoZGZbICwgY29sc10pDQoNCiMgQXNlZ3VyYXIgcXVlIGxhIHZhcmlhYmxlIG9iamV0aXZvIHNlYSAwLzEgbnVtw6lyaWNhDQojIEVkaXRhIGxvcyBuaXZlbGVzIHNlZ8O6biB0dSBkYXRhc2V0ICgiTSIvIkIiLCAiTWFsaWduYW50Ii8iQmVuaWduIiwgZXRjLikNCmlmIChpcy5jaGFyYWN0ZXIoZGZfbm4kZGlhZ25vc2lzKSB8fCBpcy5mYWN0b3IoZGZfbm4kZGlhZ25vc2lzKSkgew0KICBkZl9ubiRkaWFnbm9zaXMgPC0gaWZlbHNlKGRmX25uJGRpYWdub3NpcyAlaW4lIGMoIk0iLCJNYWxpZ25hbnQiLCIxIiksIDEsIDApDQp9DQpkZl9ubiRkaWFnbm9zaXMgPC0gYXMubnVtZXJpYyhkZl9ubiRkaWFnbm9zaXMpDQoNCiMgLS0tIDIpIEVzY2FsYWRvIGRlIHByZWRpY3RvcmVzICgwLTEpIHBhcmEgZXN0YWJpbGlkYWQgZGVsIGVudHJlbmFtaWVudG8gLS0tDQpybmcwMSA8LSBmdW5jdGlvbih4KSAoeCAtIG1pbih4KSkgLyAobWF4KHgpIC0gbWluKHgpKQ0KWGNvbHMgPC0gc2V0ZGlmZihjb2xzLCAiZGlhZ25vc2lzIikNCmRmX25uWyAsIFhjb2xzXSA8LSBsYXBwbHkoZGZfbm5bICwgWGNvbHNdLCBybmcwMSkNCg0KIyAoT3BjaW9uYWwpIFBhcnRpY2nDs24gdHJhaW4vdGVzdA0KbiA8LSBucm93KGRmX25uKQ0KaWR4IDwtIHNhbXBsZShzZXFfbGVuKG4pLCBzaXplID0gZmxvb3IoMC44Km4pKQ0KdHJhaW4gPC0gZGZfbm5baWR4LCBdDQp0ZXN0ICA8LSBkZl9ublstaWR4LCBdDQoNCiMgLS0tIDMpIEVudHJlbmFtaWVudG8gY29uIGhpcGVycGFyw6FtZXRyb3MgbcOhcyB0b2xlcmFudGVzIC0tLQ0KIyBUaXBzIHBhcmEgZXZpdGFyICJkaWQgbm90IGNvbnZlcmdlIjoNCiMgLSByZWR1Y2lyIHRhbWHDsW8gZGUgbGEgcmVkIChwLmVqLiBoaWRkZW4gPSBjKDQpIG8gYyg1LDMpIHNpIHlhIGVzY2FsYSkNCiMgLSBhdW1lbnRhciBzdGVwbWF4DQojIC0gdXNhciBhbGdvcml0aG0gPSAicnByb3ArIiAocmVzaWxpZW50IGJhY2twcm9wKQ0KIyAtIHN1YmlyIHRocmVzaG9sZCAoY3JpdGVyaW8gZGUgcGFyYWRhKSBsaWdlcmFtZW50ZQ0KZm9ybXVsYV9ubiA8LSBkaWFnbm9zaXMgfiByYWRpdXNfbWVhbiArIHRleHR1cmVfbWVhbiArIHBlcmltZXRlcl9tZWFuICsgYXJlYV9tZWFuICsgc21vb3RobmVzc19tZWFuDQoNCnJlZF9uZXVyb25hbCA8LSBuZXVyYWxuZXQoDQogIGZvcm11bGEgPSBmb3JtdWxhX25uLA0KICBkYXRhID0gdHJhaW4sDQogIGhpZGRlbiA9IGMoNCksICAgICAgICAgICAgICAjIGVtcGllemEgc2ltcGxlOyBsdWVnbyBwdWVkZXMgcHJvYmFyIGMoNSwzKQ0KICBhY3QuZmN0ID0gImxvZ2lzdGljIiwNCiAgbGluZWFyLm91dHB1dCA9IEZBTFNFLA0KICBhbGdvcml0aG0gPSAicnByb3ArIiwNCiAgc3RlcG1heCA9IDVlNiwNCiAgdGhyZXNob2xkID0gMC4wNSwNCiAgbGlmZXNpZ24gPSAibWluaW1hbCIsDQogIHJlcCA9IDMNCikNCmBgYA0KDQpgYGB7cn0NCiMgLS0tIDQpIEdyYWZpY2FyIHNvbG8gc2kgaGF5IHBlc29zIChjb252ZXJnacOzIGFsIG1lbm9zIHVuYSByw6lwbGljYSkgLS0tDQpjb252ZXJnaW8gPC0gbGVuZ3RoKHJlZF9uZXVyb25hbCR3ZWlnaHRzKSA+IDAgJiYNCiAgICAgICAgICAgICBsZW5ndGgocmVkX25ldXJvbmFsJHdlaWdodHNbWzFdXSkgPiAwICYmDQogICAgICAgICAgICAgYWxsKCFzYXBwbHkocmVkX25ldXJvbmFsJHdlaWdodHNbWzFdXSwgaXMubnVsbCkpDQoNCmlmIChjb252ZXJnaW8pIHsNCiAgcGxvdChyZWRfbmV1cm9uYWwsIHJlcCA9IHdoaWNoLm1pbihyZWRfbmV1cm9uYWwkcmVzdWx0Lm1hdHJpeFsiZXJyb3IiLCBdKSkNCn0gZWxzZSB7DQogIG1lc3NhZ2UoIkxhIHJlZCBubyBjb252ZXJnacOzLiBBanVzdGEgaGlkZGVuL3N0ZXBtYXgvdGhyZXNob2xkIG8gdmVyaWZpY2EgZGF0b3MuIikNCn0NCmBgYA0KYGBge3J9DQojIC0tLSA1KSBQcmVkaWNjacOzbiB5IHVtYnJhbCAtLS0NCmlmIChjb252ZXJnaW8pIHsNCiAgcHJlZF9wcm9iIDwtIGNvbXB1dGUocmVkX25ldXJvbmFsLCB0ZXN0WyAsIFhjb2xzXSkkbmV0LnJlc3VsdA0KICBwcmVkX2NsYXMgPC0gaWZlbHNlKHByZWRfcHJvYiA+IDAuNSwgMSwgMCkNCg0KICAjIE3DqXRyaWNhIHLDoXBpZGEgKHNpIHRpZW5lcyB0ZXN0JGRpYWdub3NpcykNCiAgaWYgKG5yb3codGVzdCkgPiAwKSB7DQogICAgYWNjIDwtIG1lYW4ocHJlZF9jbGFzID09IHRlc3QkZGlhZ25vc2lzKQ0KICAgIGNhdChzcHJpbnRmKCJcbkFjY3VyYWN5IHRlc3Q6ICUuM2ZcbiIsIGFjYykpDQogIH0NCg0KICAjIFZlciBwcmVkaWNjaW9uZXMgZGUgZWplbXBsbw0KICBoZWFkKGRhdGEuZnJhbWUocHJvYiA9IHByZWRfcHJvYiwgcHJlZCA9IHByZWRfY2xhcykpDQp9DQpgYGANCg0KYGBge3J9DQojIENyZWFyIGRhdG9zIGRlIHBydWViYSAoZWplbXBsbyBjb24gMyBwYWNpZW50ZXMpDQpwcnVlYmEgPC0gZGF0YS5mcmFtZSgNCiAgcmFkaXVzX21lYW4gICAgICA9IGMoMTQuNSwgMjAuMSwgMTAuMyksDQogIHRleHR1cmVfbWVhbiAgICAgPSBjKDIwLjIsIDEyLjUsIDE4LjQpLA0KICBwZXJpbWV0ZXJfbWVhbiAgID0gYyg4OC41LCAxMzAuMSwgNzAuNCksDQogIGFyZWFfbWVhbiAgICAgICAgPSBjKDUyMCwgMTI1MCwgMzIwKSwNCiAgc21vb3RobmVzc19tZWFuICA9IGMoMC4xMCwgMC4wOSwgMC4xMikNCikNCg0KIyBQcmVkaWNjaW9uZXMNCnByZWRpY2Npb24gPC0gY29tcHV0ZShyZWRfbmV1cm9uYWwsIHBydWViYSkNCnByb2JhYmlsaWRhZCA8LSBhcy52ZWN0b3IocHJlZGljY2lvbiRuZXQucmVzdWx0KQ0KcmVzdWx0YWRvIDwtIGlmZWxzZShwcm9iYWJpbGlkYWQgPiAwLjUsIDEsIDApDQoNCiMgTW9zdHJhciByZXN1bHRhZG9zDQpkYXRhLmZyYW1lKHBydWViYSwgcHJvYmFiaWxpZGFkLCByZXN1bHRhZG8pDQpgYGANCg0K