a. ¿Qué significa especificar el número de capas ocultas y
neuronas (hidden = c(...))?
Significa definir la arquitectura de la red
neuronal.
Cada número dentro de c(...) representa cuántas neuronas
tendrá una capa oculta. Por ejemplo:
hidden = c(5) significa una capa oculta con 5
neuronashidden = c(8,4) significa dos capas
ocultas, la primera con 8 neuronas y la segunda con 4Esto es importante porque determina la capacidad de la red para
aprender patrones.
Más capas y más neuronas permiten capturar relaciones más complejas,
pero también aumentan el riesgo de sobreajuste y el
tiempo de entrenamiento.
b. ¿Por qué es importante definir el stepmax, el
learning rate y la función de activación?
Porque estos parámetros afectan directamente cómo aprende la red.
stepmax: establece el número máximo de
pasos o iteraciones permitidos durante el entrenamiento. Si es muy bajo,
la red puede detenerse antes de aprender bien.En resumen, estos elementos determinan si la red aprende bien, mal o ni aprende, como muchos equipos de trabajo cuando dejan todo para la noche anterior.
c. ¿Cuál es la diferencia entre funciones de activación como sigmoid, tanh y ReLU?
La diferencia principal está en cómo transforman la información que recibe cada neurona:
Sigmoid: transforma los valores en un rango
entre 0 y 1.
Es útil cuando se quiere interpretar la salida como probabilidad, pero
puede provocar el problema de gradientes muy
pequeños.
tanh: transforma los valores en un rango entre
-1 y 1.
Suele funcionar mejor que sigmoid porque centra los datos alrededor de
cero, pero también puede sufrir de gradientes pequeños.
ReLU: devuelve 0 si la entrada es
negativa y deja pasar el valor si es positivo.
Es más simple y rápida, y suele funcionar mejor en redes
profundas.
d. ¿Por qué ReLU suele ser preferida en problemas de predicción con redes profundas?
Porque ayuda a que el entrenamiento sea más eficiente.
ReLU evita en gran medida el problema de que los gradientes se vuelvan
demasiado pequeños en muchas capas, lo cual permite que la red aprenda
mejor en arquitecturas profundas.
Además:
Por eso se usa mucho en redes profundas: porque funciona bien sin hacer tanto drama matemático como otras funciones.
e. ¿Qué diferencia existe entre normalización (0–1) y estandarización (z-score)?
La diferencia está en cómo se transforman los datos:
Normalización (0–1): cambia los valores para que
queden dentro de un rango entre 0 y 1.
Fórmula general:
\[
x_{norm} = \frac{x - x_{min}}{x_{max} - x_{min}}
\]
Estandarización (z-score): transforma los datos
para que tengan media 0 y desviación estándar
1.
Fórmula general:
\[
z = \frac{x - \mu}{\sigma}
\]
La normalización depende del mínimo y máximo, mientras que la estandarización depende de la media y la dispersión de los datos.
f. ¿Por qué es necesario estandarizar o normalizar las variables en ANN?
Porque las redes neuronales son sensibles a la escala de las
variables.
Si una variable tiene valores muy grandes y otra muy pequeños, la red
puede dar más peso a la variable grande solo por su magnitud, no por su
importancia real.
Estandarizar o normalizar ayuda a:
En pocas palabras: no es para “hacer bonito” el dataset, sino para que la red aprenda correctamente.
g. ¿Cómo se evalúa el desempeño de una ANN en regresión (MSE, R²)?
En problemas de regresión, una ANN se evalúa comparando los valores predichos con los valores reales.
MSE (Mean Squared Error): mide el promedio de
los errores al cuadrado.
\[
MSE = \frac{1}{n}\sum (y_i - \hat{y}_i)^2
\] Mientras más pequeño sea el MSE, mejor es el ajuste.
R² (coeficiente de determinación): indica qué
proporción de la variabilidad de la variable dependiente es explicada
por el modelo.
Su valor suele ir entre 0 y 1, y mientras más cercano a 1,
mejor.
Entonces: - MSE bajo = errores pequeños - R² alto = buena capacidad explicativa
h. ¿Por qué los coeficientes de ANN no son directamente interpretables como en econometría?
Porque en una red neuronal no existe una sola relación lineal directa
entre cada variable de entrada y la salida.
La predicción se obtiene a través de muchas combinaciones de pesos,
sesgos, capas y funciones de activación.
En econometría, un coeficiente puede interpretarse como el cambio
esperado en \(Y\) ante un cambio en
\(X\), manteniendo lo demás
constante.
En una ANN, eso no se puede hacer tan fácilmente porque:
Por eso se dice que las ANN son más difíciles de interpretar y funcionan más como una “caja negra”.
i. Explica con tus palabras qué es forward propagation (cálculo de predicciones) y backpropagation (ajuste de pesos).
Forward propagation es el proceso en el que los
datos de entrada pasan por la red capa por capa hasta generar una
predicción final.
Es básicamente cuando la red “usa lo que sabe” para dar una
respuesta.
Backpropagation es el proceso en el que la red
compara la predicción con el valor real, calcula el error y luego ajusta
los pesos internos para reducir ese error.
Es decir, la red “aprende de su error”.
En resumen: - forward propagation = producir la predicción - backpropagation = corregir la red para mejorar futuras predicciones
j. ¿Cómo afecta la elección de la función de activación la capacidad de la red para capturar relaciones no lineales en datos de negocio?
La función de activación es clave porque permite que la red modele
patrones complejos y no lineales.
Si la red no tuviera una función de activación no lineal, solo actuaría
como un modelo lineal, aunque tuviera muchas capas.
La elección de la función afecta:
En datos de negocio esto es muy importante porque muchas relaciones reales no son lineales. Por ejemplo:
Por eso, usar una función adecuada como ReLU o tanh ayuda a que la red capture mejor este tipo de comportamientos.
library(neuralnet)
library(randomForest)
## randomForest 4.7-1.2
## Type rfNews() to see new features/changes/bug fixes.
library(ggplot2)
##
## Attaching package: 'ggplot2'
## The following object is masked from 'package:randomForest':
##
## margin
library(readxl)
datos <- read_xlsx("/Users/edu_sssedu/Desktop/mx_new_fdi_data.xlsx")
## New names:
## • `region` -> `region...22`
## • `region` -> `region...23`
datos <- na.omit(datos)
# Variables del modelo
predictores <- c("crime_rate", "unemployment", "employment", "business_activity",
"real_wage", "pop_density", "exchange_rate", "inpc", "border_distance")
variables_finales <- c("new_fdi_real_mxn", predictores)
# 1. Quitar valores faltantes (Indispensable para ANN)
datos <- na.omit(datos)
# 2. Definir la función de normalización
normalize <- function(x)
return((x - min(x, na.rm = TRUE)) / (max(x, na.rm = TRUE) - min(x, na.rm = TRUE)))
# 3. Identificar y normalizar columnas numéricas
columnas_numericas <- sapply(datos, is.numeric)
datos_norm <- datos
datos_norm[, columnas_numericas] <- as.data.frame(lapply(datos[, columnas_numericas], normalize))
# 4. División de datos
set.seed(123)
index <- sample(1:nrow(datos_norm), round(0.8 * nrow(datos_norm)))
train <- datos_norm[index, ]
test <- datos_norm[-index, ]
# 1. Asegurar que los datos no tengan valores infinitos o extraños}
train_ann <- train[, variables_finales]
train_ann <- as.data.frame(lapply(train_ann, as.numeric))
# 2. Definir la fórmula
formula_ann <- new_fdi_real_mxn ~ .
# 3. Entrenamiento con parámetros de salida rápida
# Bajamos la exigencia con threshold = 0.15 y aumentamos stepmax
nn1 <- neuralnet(formula_ann,
data = train_ann,
hidden = c(5),
linear.output = TRUE,
stepmax = 5e5, # Límite de intentos
threshold = 0.15, # Tolerancia al error (más flexible)
lifesign = "full") # Para ver el progreso en tiempo real
## hidden: 5 thresh: 0.15 rep: 1/1 steps: 1000 min thresh: 2320083.5474885
## 2000 min thresh: 2092083.54748851
## 3000 min thresh: 1864083.5474885
## 4000 min thresh: 1636083.54748844
## 5000 min thresh: 1408083.54748839
## 6000 min thresh: 1180083.54748834
## 7000 min thresh: 952083.54748829
## 8000 min thresh: 724083.547488238
## 9000 min thresh: 496083.547488186
## 10000 min thresh: 394168.037088163
## 11000 min thresh: 314968.037088277
## 12000 min thresh: 235768.037088434
## 13000 min thresh: 223585.102600188
## 14000 min thresh: 223585.102600188
## 15000 min thresh: 223585.102600188
## 16000 min thresh: 223585.102600188
## 17000 min thresh: 223585.102600188
## 18000 min thresh: 223585.102600188
## 19000 min thresh: 223585.102600188
## 20000 min thresh: 223585.102600188
## 21000 min thresh: 223585.102600188
## 22000 min thresh: 223585.102600188
## 23000 min thresh: 223585.102600188
## 24000 min thresh: 223585.102600188
## 25000 min thresh: 223585.102600188
## 26000 min thresh: 223585.102600188
## 27000 min thresh: 223585.102600188
## 28000 min thresh: 223585.102600188
## 29000 min thresh: 223585.102600188
## 30000 min thresh: 223585.102600188
## 31000 min thresh: 223585.102600188
## 32000 min thresh: 223585.102600188
## 33000 min thresh: 223585.102600188
## 34000 min thresh: 223585.102600188
## 35000 min thresh: 223585.102600188
## 36000 min thresh: 223585.102600188
## 37000 min thresh: 223585.102600188
## 38000 min thresh: 223585.102600188
## 39000 min thresh: 223585.102600188
## 40000 min thresh: 223585.102600188
## 41000 min thresh: 223585.102600188
## 42000 min thresh: 223585.102600188
## 43000 min thresh: 223585.102600188
## 44000 min thresh: 223585.102600188
## 45000 min thresh: 223585.102600188
## 46000 min thresh: 223585.102600188
## 47000 min thresh: 223585.102600188
## 48000 min thresh: 223585.102600188
## 49000 min thresh: 223585.102600188
## 50000 min thresh: 223585.102600188
## 51000 min thresh: 223585.102600188
## 52000 min thresh: 223585.102600188
## 53000 min thresh: 223585.102600188
## 54000 min thresh: 223585.102600188
## 55000 min thresh: 223585.102600188
## 56000 min thresh: 223585.102600188
## 57000 min thresh: 223585.102600188
## 58000 min thresh: 223585.102600188
## 59000 min thresh: 223585.102600188
## 60000 min thresh: 223585.102600188
## 61000 min thresh: 223585.102600188
## 62000 min thresh: 223585.102600188
## 63000 min thresh: 223585.102600188
## 64000 min thresh: 223585.102600188
## 65000 min thresh: 223585.102600188
## 66000 min thresh: 223585.102600188
## 67000 min thresh: 223585.102600188
## 68000 min thresh: 223585.102600188
## 69000 min thresh: 223585.102600188
## 70000 min thresh: 223585.102600188
## 71000 min thresh: 223585.102600188
## 72000 min thresh: 223585.102600188
## 73000 min thresh: 223585.102600188
## 74000 min thresh: 223585.102600188
## 75000 min thresh: 223585.102600188
## 76000 min thresh: 223585.102600188
## 77000 min thresh: 223585.102600188
## 78000 min thresh: 223585.102600188
## 79000 min thresh: 223585.102600188
## 80000 min thresh: 223585.102600188
## 81000 min thresh: 223585.102600188
## 82000 min thresh: 223585.102600188
## 83000 min thresh: 223585.102600188
## 84000 min thresh: 223585.102600188
## 85000 min thresh: 223585.102600188
## 86000 min thresh: 223585.102600188
## 87000 min thresh: 223585.102600188
## 88000 min thresh: 223585.102600188
## 89000 min thresh: 223585.102600188
## 90000 min thresh: 223585.102600188
## 91000 min thresh: 223585.102600188
## 92000 min thresh: 223585.102600188
## 93000 min thresh: 223585.102600188
## 94000 min thresh: 223585.102600188
## 95000 min thresh: 223585.102600188
## 96000 min thresh: 223585.102600188
## 97000 min thresh: 223585.102600188
## 98000 min thresh: 223585.102600188
## 99000 min thresh: 223585.102600188
## 1e+05 min thresh: 223585.102600188
## 101000 min thresh: 223585.102600188
## 102000 min thresh: 223585.102600188
## 103000 min thresh: 223585.102600188
## 104000 min thresh: 223585.102600188
## 105000 min thresh: 223585.102600188
## 106000 min thresh: 221794.741000144
## 107000 min thresh: 219471.675400103
## 108000 min thresh: 217140.872200063
## 109000 min thresh: 214817.806600022
## 110000 min thresh: 212487.003399982
## 111000 min thresh: 210163.937799941
## 112000 min thresh: 207833.134599901
## 113000 min thresh: 205510.068999861
## 114000 min thresh: 203206.64499982
## 115000 min thresh: 200856.20019978
## 116000 min thresh: 198552.776199739
## 117000 min thresh: 196202.331399699
## 118000 min thresh: 193898.907399658
## 119000 min thresh: 191548.462599618
## 120000 min thresh: 189245.038599577
## 121000 min thresh: 186894.593799537
## 122000 min thresh: 184591.169799496
## 123000 min thresh: 182240.724999456
## 124000 min thresh: 179937.300999416
## 125000 min thresh: 177586.856199375
## 126000 min thresh: 175283.432199335
## 127000 min thresh: 172932.987399294
## 128000 min thresh: 170629.563399254
## 129000 min thresh: 168326.139399214
## 130000 min thresh: 165975.694599173
## 131000 min thresh: 163672.270599133
## 132000 min thresh: 161321.825799092
## 133000 min thresh: 159018.401799052
## 134000 min thresh: 156667.956999011
## 135000 min thresh: 154364.532998971
## 136000 min thresh: 152014.08819893
## 137000 min thresh: 149710.66419889
## 138000 min thresh: 147407.24019885
## 139000 min thresh: 145056.795398809
## 140000 min thresh: 142753.371398769
## 141000 min thresh: 140402.926598728
## 142000 min thresh: 138099.502598688
## 143000 min thresh: 135749.057798647
## 144000 min thresh: 133445.633798607
## 145000 min thresh: 131142.209798567
## 146000 min thresh: 128791.764998526
## 147000 min thresh: 126488.340998486
## 148000 min thresh: 124137.896198445
## 149000 min thresh: 121834.472198405
## 150000 min thresh: 119484.027398364
## 151000 min thresh: 117180.603398324
## 152000 min thresh: 114830.158598283
## 153000 min thresh: 112526.734598243
## 154000 min thresh: 110203.668997861
## 155000 min thresh: 107872.865797404
## 156000 min thresh: 105549.800196939
## 157000 min thresh: 103218.996996482
## 158000 min thresh: 100895.931396016
## 159000 min thresh: 98565.1281955586
## 160000 min thresh: 96242.0625950934
## 161000 min thresh: 93911.2593946364
## 162000 min thresh: 91588.1937941703
## 163000 min thresh: 89284.7697937104
## 164000 min thresh: 86934.324993248
## 165000 min thresh: 84630.9009927882
## 166000 min thresh: 82280.4561923249
## 167000 min thresh: 79977.032191865
## 168000 min thresh: 77626.5873914027
## 169000 min thresh: 75323.1633909428
## 170000 min thresh: 72972.7185904795
## 171000 min thresh: 70669.2945900197
## 172000 min thresh: 68318.8497895573
## 173000 min thresh: 66015.4257890974
## 174000 min thresh: 63664.9809886342
## 175000 min thresh: 61361.5569881743
## 176000 min thresh: 59058.1329877147
## 177000 min thresh: 56707.6881872521
## 178000 min thresh: 54404.2641867924
## 179000 min thresh: 52053.819386329
## 180000 min thresh: 49750.3953858693
## 181000 min thresh: 47399.9505854067
## 182000 min thresh: 45096.526584947
## 183000 min thresh: 42746.0817856354
## 184000 min thresh: 40442.6577865249
## 185000 min thresh: 38139.2337874143
## 186000 min thresh: 35788.7889883093
## 187000 min thresh: 33485.3649891988
## 188000 min thresh: 31134.9201900928
## 189000 min thresh: 28831.4961909823
## 190000 min thresh: 26481.0513918773
## 191000 min thresh: 24177.6273927667
## 192000 min thresh: 21827.1825936608
## 193000 min thresh: 19523.7585945503
## 194000 min thresh: 17200.6929954519
## 195000 min thresh: 14869.8897963347
## 196000 min thresh: 12546.8241972354
## 197000 min thresh: 10216.0209981182
## 198000 min thresh: 7892.95539901981
## 199000 min thresh: 5562.15219990262
## 2e+05 min thresh: 3239.08660080338
## 201000 min thresh: 908.283401686189
## 201833 error: 12291927546.2106 time: 9.93 secs
nn2 <- neuralnet(formula_ann, data = train_ann, hidden = c(10, 5),
linear.output = TRUE, stepmax = 1e6, threshold = 0.1, lifesign = "full")
## hidden: 10, 5 thresh: 0.1 rep: 1/1 steps: 1000 min thresh: 2319699.72285784
## 2000 min thresh: 2089899.72285786
## 3000 min thresh: 1860099.72285784
## 4000 min thresh: 1630299.72285779
## 5000 min thresh: 1400499.72285774
## 6000 min thresh: 1170699.72285768
## 7000 min thresh: 940899.722857632
## 8000 min thresh: 711099.72285758
## 9000 min thresh: 481299.722857527
## 10000 min thresh: 251499.722857475
## 11000 min thresh: 21699.7228576201
## 12000 min thresh: 819.32885763904
## 13000 min thresh: 819.32885763904
## 14000 min thresh: 819.32885763904
## 15000 min thresh: 819.32885763904
## 16000 min thresh: 819.32885763904
## 17000 min thresh: 819.32885763904
## 18000 min thresh: 788.571468563714
## 19000 min thresh: 691.351760527519
## 20000 min thresh: 587.877925088927
## 21000 min thresh: 487.73487309592
## 22000 min thresh: 385.374945142408
## 23000 min thresh: 285.893992832636
## 24000 min thresh: 182.558894643713
## 25000 min thresh: 101.111039880467
## 26000 min thresh: 53.5917720267753
## 27000 min thresh: 29.2263931777488
## 28000 min thresh: 15.9121185353215
## 29000 min thresh: 8.46497689218086
## 30000 min thresh: 4.60855180284852
## 31000 min thresh: 2.48359671765502
## 32000 min thresh: 1.37004976969911
## 33000 min thresh: 0.727407536716782
## 34000 min thresh: 0.384077938258997
## 35000 min thresh: 0.209175995449186
## 36000 min thresh: 0.113646858255379
## 36225 error: 20067141632.5312 time: 3.83 secs
nn3 <- neuralnet(formula_ann, data = train_ann, hidden = c(15, 10, 5),
linear.output = TRUE, stepmax = 1e6, threshold = 0.1, lifesign = "full")
## hidden: 15, 10, 5 thresh: 0.1 rep: 1/1 steps: 1000 min thresh: 2317776.5873945
## 2000 min thresh: 2087376.58739451
## 3000 min thresh: 1856976.5873945
## 4000 min thresh: 1626576.58739444
## 5000 min thresh: 1396176.58739439
## 6000 min thresh: 1165776.58739434
## 7000 min thresh: 935376.587394285
## 8000 min thresh: 704976.587394233
## 9000 min thresh: 474576.587394181
## 10000 min thresh: 244176.587394128
## 11000 min thresh: 13776.587394275
## 11073 error: 20092544924.9916 time: 1.79 secs
plot(nn1, rep = "best")
plot(nn2, rep = "best")
plot(nn3, rep = "best")
# 1. Regresión Lineal Múltiple (Econometría)
modelo_ols <- lm(formula_ann, data = train_ann)
# 2. Random Forest (Machine Learning)
set.seed(123)
modelo_rf <- randomForest(formula_ann, data = train_ann, ntree = 500)
# Imprimir resúmenes básicos
cat("Modelos OLS y Random Forest entrenados con éxito.\n")
## Modelos OLS y Random Forest entrenados con éxito.
print(summary(modelo_ols))
##
## Call:
## lm(formula = formula_ann, data = train_ann)
##
## Residuals:
## Min 1Q Median 3Q Max
## -56684 -3620 -1571 2186 47742
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 3.011e+04 3.392e+04 0.888 0.37527
## crime_rate -1.087e+01 2.010e+01 -0.541 0.58911
## unemployment -6.283e+04 3.792e+04 -1.657 0.09837 .
## employment -2.693e+04 3.404e+04 -0.791 0.42937
## business_activity -6.260e+02 7.644e+02 -0.819 0.41340
## real_wage 3.753e+01 1.274e+01 2.946 0.00342 **
## pop_density 5.386e+00 4.876e-01 11.045 < 2e-16 ***
## exchange_rate 3.102e+02 2.720e+02 1.140 0.25484
## inpc -1.155e+02 6.231e+01 -1.854 0.06453 .
## border_distance -5.503e+00 2.520e+00 -2.184 0.02958 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7702 on 374 degrees of freedom
## Multiple R-squared: 0.4479, Adjusted R-squared: 0.4346
## F-statistic: 33.72 on 9 and 374 DF, p-value: < 2.2e-16
# 1. Definir los predictores exactos
predictores <- c("crime_rate", "unemployment", "employment", "business_activity",
"real_wage", "pop_density", "exchange_rate", "inpc", "border_distance")
# 2. Limpiar el set de prueba de columnas duplicadas y NAs
# Seleccionamos solo las variables que vamos a usar para evitar el error de 'region'
test_clean <- as.data.frame(test[, variables_finales])
test_clean <- na.omit(test_clean)
# 3. SINCRONIZACIÓN DE TIPOS (ESTO QUITA EL ERROR DE 'DIFFERENT TYPES')
# Forzamos a que el set de prueba sea numérico puro, igual que el de entrenamiento
for(col in variables_finales) {
test_clean[[col]] <- as.numeric(as.vector(test_clean[[col]]))
}
# 4. Preparar matriz para la Red Neuronal
test_x_mat <- as.matrix(test_clean[, predictores])
# 5. Generar Predicciones (AQUÍ YA NO DEBE MARCAR ERROR)
pred_nn1 <- compute(nn1, test_x_mat)$net.result
pred_nn2 <- compute(nn2, test_x_mat)$net.result
pred_nn3 <- compute(nn3, test_x_mat)$net.result
# Para OLS y Random Forest usamos el dataframe limpio
pred_ols <- predict(modelo_ols, test_clean)
pred_rf <- predict(modelo_rf, test_clean)
# 6. Cálculo de Métricas para tu tabla
actual <- test_clean$new_fdi_real_mxn
calc_rmse <- function(a, p) { sqrt(mean((a - p)^2)) }
calc_r2 <- function(a, p) { cor(a, p)^2 }
# Imprimir resultados
cat("Resultados de Evaluación:\n")
## Resultados de Evaluación:
cat("ANN 1 - RMSE:", calc_rmse(actual, pred_nn1), "\n")
## ANN 1 - RMSE: 9382.743
cat("ANN 2 - RMSE:", calc_rmse(actual, pred_nn2), "\n")
## ANN 2 - RMSE: 12168.99
cat("ANN 3 - RMSE:", calc_rmse(actual, pred_nn3), "\n")
## ANN 3 - RMSE: 12170.04
cat("OLS - RMSE:", calc_rmse(actual, pred_ols), "\n")
## OLS - RMSE: 8700.815
cat("RF - RMSE:", calc_rmse(actual, pred_rf), "\n")
## RF - RMSE: 8610.465
# --- 1. Preparación de Métricas ---
# Creamos una función para calcular RMSE y R-cuadrado de forma automática
calcular_metricas <- function(real, estimado) {
rmse_val <- sqrt(mean((real - estimado)^2))
# R2 calculado como la correlación al cuadrado entre real y predicho
r2_val <- cor(real, estimado)^2
return(c(RMSE = rmse_val, R2 = r2_val))
}
# --- 2. Obtención de Resultados ---
# Usamos los objetos de predicción que generamos anteriormente
m1 <- calcular_metricas(actual, pred_nn1)
m2 <- calcular_metricas(actual, pred_nn2)
m3 <- calcular_metricas(actual, pred_nn3)
m_ols <- calcular_metricas(actual, pred_ols)
m_rf <- calcular_metricas(actual, pred_rf)
# --- 3. Tabla Comparativa de RMSE y R² ---
tabla_comparativa <- data.frame(
Modelo = c("ANN 1", "ANN 2", "ANN 3", "Regresión OLS", "Random Forest"),
Arquitectura = c("hidden = c(5)", "hidden = c(10,5)", "hidden = c(15,10,5)", "Lineal", "Bagging/Ensamble"),
RMSE = c(m1[1], m2[1], m3[1], m_ols[1], m_rf[1]),
R_Cuadrado = c(m1[2], m2[2], m3[2], m_ols[2], m_rf[2])
)
# Imprimir la tabla en el reporte
knitr::kable(tabla_comparativa, digits = 4, caption = "Comparativa de Desempeño: FDI en México")
| Modelo | Arquitectura | RMSE | R_Cuadrado |
|---|---|---|---|
| ANN 1 | hidden = c(5) | 9382.743 | 0.4227 |
| ANN 2 | hidden = c(10,5) | 12168.991 | NA |
| ANN 3 | hidden = c(15,10,5) | 12170.041 | NA |
| Regresión OLS | Lineal | 8700.815 | 0.5152 |
| Random Forest | Bagging/Ensamble | 8610.465 | 0.5424 |
# --- 4. Generación de Scatterplots Comparativos ---
# Configuramos el lienzo para mostrar 5 gráficos (2 filas, 3 columnas)
par(mfrow = c(2, 3), mar = c(4, 4, 3, 1))
# Función interna para no repetir código de graficación
hacer_plot <- function(real, pred, titulo, color) {
plot(real, pred,
main = titulo,
xlab = "Valor Real (FDI)",
ylab = "Valor Estimado",
pch = 20, col = color)
abline(0, 1, col = "red", lwd = 2) # Línea ideal de 45 grados
}
# Dibujar cada uno de los modelos solicitados
hacer_plot(actual, pred_nn1, "ANN 1 (Simple)", "royalblue")
hacer_plot(actual, pred_nn2, "ANN 2 (Intermedia)", "royalblue")
hacer_plot(actual, pred_nn3, "ANN 3 (Compleja)", "royalblue")
hacer_plot(actual, pred_ols, "Regresión OLS", "darkgreen")
hacer_plot(actual, pred_rf, "Random Forest", "darkorange")
# Resetear el layout a 1x1
par(mfrow = c(1, 1))