Instalar paquetes y llamar librerías

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

Importar la base de datos

cancermama <- read.csv("/Users/brisnaordaz/Downloads/cancer_de_mama.csv")

Entender la base de datos

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

Preparar variables

# 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)

Árbol de decisión (rpart)

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")

Red neuronal (neuralnet)

# 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"

Predicción con nuevos casos

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.