library(rpart)
library(rpart.plot)
library(readr)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(neuralnet)
##
## Attaching package: 'neuralnet'
## The following object is masked from 'package:dplyr':
##
## compute
cancermama <- read.csv("/Users/brisnaordaz/Downloads/cancer_de_mama.csv")
summary(cancermama)
## diagnosis radius_mean texture_mean perimeter_mean
## Length:569 Min. : 6.981 Min. : 9.71 Min. : 43.79
## Class :character 1st Qu.:11.700 1st Qu.:16.17 1st Qu.: 75.17
## Mode :character Median :13.370 Median :18.84 Median : 86.24
## Mean :14.127 Mean :19.29 Mean : 91.97
## 3rd Qu.:15.780 3rd Qu.:21.80 3rd Qu.:104.10
## Max. :28.110 Max. :39.28 Max. :188.50
## 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
## Min. :0.00000 Min. :0.1565 Min. :0.05504
## 1st Qu.:0.06493 1st Qu.:0.2504 1st Qu.:0.07146
## 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
str(cancermama)
## 'data.frame': 569 obs. of 31 variables:
## $ diagnosis : chr "M" "M" "M" "M" ...
## $ 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 ...
head(cancermama, 3)
## diagnosis radius_mean texture_mean perimeter_mean area_mean smoothness_mean
## 1 M 17.99 10.38 122.8 1001 0.11840
## 2 M 20.57 17.77 132.9 1326 0.08474
## 3 M 19.69 21.25 130.0 1203 0.10960
## compactness_mean concavity_mean concave_points_mean symmetry_mean
## 1 0.27760 0.3001 0.14710 0.2419
## 2 0.07864 0.0869 0.07017 0.1812
## 3 0.15990 0.1974 0.12790 0.2069
## fractal_dimension_mean radius_se texture_se perimeter_se area_se
## 1 0.07871 1.0950 0.9053 8.589 153.40
## 2 0.05667 0.5435 0.7339 3.398 74.08
## 3 0.05999 0.7456 0.7869 4.585 94.03
## smoothness_se compactness_se concavity_se concave_points_se symmetry_se
## 1 0.006399 0.04904 0.05373 0.01587 0.03003
## 2 0.005225 0.01308 0.01860 0.01340 0.01389
## 3 0.006150 0.04006 0.03832 0.02058 0.02250
## fractal_dimension_se radius_worst texture_worst perimeter_worst area_worst
## 1 0.006193 25.38 17.33 184.6 2019
## 2 0.003532 24.99 23.41 158.8 1956
## 3 0.004571 23.57 25.53 152.5 1709
## smoothness_worst compactness_worst concavity_worst concave_points_worst
## 1 0.1622 0.6656 0.7119 0.2654
## 2 0.1238 0.1866 0.2416 0.1860
## 3 0.1444 0.4245 0.4504 0.2430
## symmetry_worst fractal_dimension_worst
## 1 0.4601 0.11890
## 2 0.2750 0.08902
## 3 0.3613 0.08758
# diagnosis es la etiqueta. Normalizamos a Benigno/Maligno
cancermama$diagnosis <- factor(cancermama$diagnosis,
levels = c("B","M"),
labels = c("Benigno","Maligno"))
# Predictores numéricos (excluye 'id' si existe)
preds <- names(cancermama)[sapply(cancermama, is.numeric)]
preds <- setdiff(preds, "id")
# Dataset limpio sin NAs en predictores
datos <- cancermama[, c("diagnosis", preds)]
datos <- tidyr::drop_na(datos)
set.seed(123)
arbol_cancer <- rpart(
diagnosis ~ .,
data = datos,
method = "class",
control = rpart.control(cp = 0.01, minsplit = 20)
)
rpart.plot(arbol_cancer, type = 2, extra = 104, fallen.leaves = TRUE,
tweak = 1.1, under = TRUE)
# Alternativa con proporciones:
prp(arbol_cancer, extra = 7, prefix = "fracción \n")
# Convertimos diagnosis a binario: 1=Maligno, 0=Benigno
datos$diagnosis_bin <- ifelse(datos$diagnosis == "Maligno", 1, 0)
# Normalización 0–1 para predictores
normalize <- function(x) {
r <- range(x, na.rm = TRUE)
if (diff(r) == 0) return(rep(0, length(x)))
(x - r[1]) / (r[2] - r[1])
}
datos_norm <- datos
datos_norm[, preds] <- lapply(datos_norm[, preds, drop = FALSE], normalize)
# Partición train/test
set.seed(123)
n <- nrow(datos_norm)
ix <- sample.int(n, size = round(0.7*n))
train <- datos_norm[ix, ]
test <- datos_norm[-ix, ]
# Fórmula: diagnosis_bin ~ todos los predictores
f_nn <- as.formula(paste("diagnosis_bin ~", paste(preds, collapse = " + ")))
# Entrenamiento
red_neuronal <- neuralnet(
f_nn,
data = train,
hidden = c(10, 5), # puedes simplificar a 8 si quieres
linear.output = FALSE, # clasificación (sigmoide)
err.fct = "ce",
stepmax = 1e6
)
plot(red_neuronal, rep = "best")
# Evaluación rápida en test
prob_test <- compute(red_neuronal, test[, preds])$net.result
pred_test <- ifelse(prob_test > 0.5, 1, 0)
cm <- table(Real = test$diagnosis_bin, Pred = pred_test)
acc <- sum(diag(cm)) / sum(cm)
cm; sprintf("Accuracy (test): %.3f", acc)
## Pred
## Real 0 1
## 0 97 1
## 1 2 71
## [1] "Accuracy (test): 0.982"
train_ranges <- sapply(train[, preds, drop = FALSE], function(x) c(min=min(x), max=max(x)))
normalize_new <- function(df_new, ranges){
out <- df_new
for (nm in colnames(df_new)) {
mn <- ranges[1, nm]; mx <- ranges[2, nm]
out[[nm]] <- if (mx - mn == 0) 0 else (df_new[[nm]] - mn)/(mx - mn)
}
out
}
# EJEMPLO: usamos el promedio de tus datos originales solo para mostrar el flujo
nuevo <- as.data.frame(t(colMeans(datos[, preds], na.rm = TRUE)))
nuevo_norm <- normalize_new(nuevo, train_ranges)
prob_nuevo <- compute(red_neuronal, nuevo_norm)$net.result[1,1]
clase_nuevo <- ifelse(prob_nuevo > 0.5, "Maligno", "Benigno")
sprintf("Prob(Maligno)= %.3f | Clase predicha: %s", prob_nuevo, clase_nuevo)
## [1] "Prob(Maligno)= 1.000 | Clase predicha: Maligno"
# Conclusión
El árbol de decisión muestra que variables como radius_worst, concave_points_worst y texture_worst son las más relevantes para clasificar entre Benigno y Maligno.
**La mayoría de los casos con valores bajos en estas variables tienden a ser Benignos, mientras que valores altos se asocian con Malignos.
**La red neuronal calculó una probabilidad de 1.000 (100%) de que el caso evaluado sea Maligno.
**Ambos modelos (árbol de decisión y red neuronal) coinciden en que el caso pertenece a la clase Maligno.
Esto confirma que los modelos tienen alto poder predictivo, siempre que los datos estén bien preparados y contengan las variables clave.