Introducción

Este informe presenta un modelo de regresión multivariable aplicado al análisis de deslizamientos.
Se integran variables geográficas, climáticas y demográficas para estimar el tamaño del deslizamiento y evaluar escenarios predictivos.

1. CARGA DE LIBRERÍAS Y DATOS

# ============================================================
# 1. INSTALACIÓN Y CARGA DE LIBRERÍAS
# ============================================================

paquetes <- c("dplyr", "httr", "jsonlite",
              "scatterplot3d", "knitr")

for (p in paquetes) {
  if (!require(p, character.only = TRUE)) {
    install.packages(p)
    library(p, character.only = TRUE)
  }
}
## Loading required package: 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
## Loading required package: httr
## Loading required package: jsonlite
## Loading required package: scatterplot3d
## Loading required package: knitr
cat("Librerías cargadas correctamente.\n")
## Librerías cargadas correctamente.
# ============================================================
# 2. CARGA DEL DATASET
# ============================================================

file_name <- "regresiones.csv"

if (!file.exists(file_name)) {
  stop("ERROR: El archivo 'regresiones.csv' no está en el directorio.")
}

datos <- read.csv(file_name,
                  sep = ",",
                  stringsAsFactors = FALSE)

names(datos) <- tolower(names(datos))

cat("Dataset cargado correctamente.\n")
## Dataset cargado correctamente.

2. LIMPIEZA Y VALIDACIÓN

# ============================================================
# 2. LIMPIEZA Y VALIDACIÓN
# ============================================================

datos$latitude  <- as.numeric(datos$latitude)
datos$longitude <- as.numeric(datos$longitude)
datos$admin_division_population <-
  as.numeric(datos$admin_division_population)

datos$event_date <- as.Date(datos$event_date,
                            format = "%Y-%m-%d")

datos <- datos %>%
  filter(!is.na(latitude),
         !is.na(longitude),
         !is.na(event_date),
         latitude >= -90 & latitude <= 90,
         longitude >= -180 & longitude <= 180)

cat("Datos limpiados correctamente.\n")
## Datos limpiados correctamente.

3. FUNCIÓN DE DESCARGA CLIMÁTICA

# ============================================================
# 3. FUNCIÓN PARA DESCARGA CLIMÁTICA
# ============================================================

fetch_weather <- function(lat, lon, date_str) {
  
  if (is.na(lat) || is.na(lon) || is.na(date_str)) {
    return(c(NA, NA))
  }
  
  date <- as.character(date_str)
  
  url <- paste0(
    "https://archive-api.open-meteo.com/v1/archive?",
    "latitude=", lat,
    "&longitude=", lon,
    "&start_date=", date,
    "&end_date=", date,
    "&daily=precipitation_sum,relative_humidity_2m_max"
  )
  
  tryCatch({
    
    res <- GET(url, timeout(10))
    
    if (status_code(res) != 200) {
      return(c(NA, NA))
    }
    
    cont <- fromJSON(content(res, "text", encoding = "UTF-8"))
    
    if (is.null(cont$daily)) {
      return(c(NA, NA))
    }
    
    c(cont$daily$precipitation_sum[1],
      cont$daily$relative_humidity_2m_max[1])
    
  }, error = function(e) {
    c(NA, NA)
  })
}

4. INTEGRACIÓN DE DATOS CLIMÁTICOS

# ============================================================
# 4. DESCARGA DE CLIMA (100 REGISTROS PARA ESTABILIDAD)
# ============================================================

df_demo <- head(datos, 100)

clima_list <- vector("list", nrow(df_demo))

for (i in seq_len(nrow(df_demo))) {
  
  if (i %% 10 == 0) {
    cat("Descargando clima:", i, "/", nrow(df_demo), "\n")
  }
  
  clima_list[[i]] <- fetch_weather(
    df_demo$latitude[i],
    df_demo$longitude[i],
    df_demo$event_date[i]
  )
}
## Descargando clima: 10 / 100 
## Descargando clima: 20 / 100 
## Descargando clima: 30 / 100 
## Descargando clima: 40 / 100 
## Descargando clima: 50 / 100 
## Descargando clima: 60 / 100 
## Descargando clima: 70 / 100 
## Descargando clima: 80 / 100 
## Descargando clima: 90 / 100 
## Descargando clima: 100 / 100
clima_df <- as.data.frame(do.call(rbind, clima_list))
colnames(clima_df) <- c("precip_real", "hum_real")

df_demo <- cbind(df_demo, clima_df)

df_demo <- df_demo %>%
  filter(!is.na(precip_real),
         !is.na(hum_real))

cat("Datos climáticos integrados.\n")
## Datos climáticos integrados.

5. GENERACIÓN DE VARIABLES

# ============================================================
# 5. GENERACIÓN DE VARIABLES SINTÉTICAS
# ============================================================

set.seed(42)

n <- nrow(df_demo)

noise <- rnorm(n, 0, 18)

pop <- df_demo$admin_division_population
pop[is.na(pop)] <- median(pop, na.rm = TRUE)

if(max(pop) == min(pop)){
  pop_norm <- rep(0.5, length(pop))
} else {
  pop_norm <- (pop - min(pop)) /
    (max(pop) - min(pop))
}

df_demo$pop_norm <- pop_norm

df_demo$size_linear <-
  2.4 * df_demo$precip_real +
  125 + noise

cat("Variables sintéticas creadas.\n")
## Variables sintéticas creadas.

6. REGRESIÓN MÚLTIPLE

# ============================================================
# 6. REGRESIÓN MÚLTIPLE
# ============================================================

modelo_multi <- lm(size_linear ~
                     precip_real +
                     hum_real +
                     pop_norm,
                   data = df_demo)

cat("\nResumen del modelo:\n")
## 
## Resumen del modelo:
print(summary(modelo_multi))
## 
## Call:
## lm(formula = size_linear ~ precip_real + hum_real + pop_norm, 
##     data = df_demo)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -51.79 -12.49   1.26  12.63  41.25 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 159.9548    20.1705   7.930 3.99e-12 ***
## precip_real   2.3069     0.2740   8.420 3.64e-13 ***
## hum_real     -0.3730     0.2238  -1.667   0.0988 .  
## pop_norm      8.6444    18.5337   0.466   0.6420    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 18.67 on 96 degrees of freedom
## Multiple R-squared:  0.4284, Adjusted R-squared:  0.4105 
## F-statistic: 23.98 on 3 and 96 DF,  p-value: 1.147e-11

7. TABLA RESUMEN

# ============================================================
# 7. TABLA RESUMEN
# ============================================================

tabla_intervalos <- data.frame(
  Min_Precip = min(df_demo$precip_real),
  Max_Precip = max(df_demo$precip_real),
  Min_Hum    = min(df_demo$hum_real),
  Max_Hum    = max(df_demo$hum_real),
  Min_Size   = min(df_demo$size_linear),
  Max_Size   = max(df_demo$size_linear),
  N          = nrow(df_demo)
)

kable(tabla_intervalos,
      format = "markdown",
      caption = "Tabla N°1: Resumen estadístico del modelo")
Tabla N°1: Resumen estadístico del modelo
Min_Precip Max_Precip Min_Hum Max_Hum Min_Size Max_Size N
0 44.7 60 100 81.54426 226.7605 100

8. VISUALIZACIÓN 3D DEL MODELO

# Verificar que las columnas existan
if(!all(c("precip_real","hum_real","size_linear") %in% names(df_demo))){
  stop("Las variables climáticas no existen. Ejecuta correctamente la sección 5.")
}

# Filtrar datos válidos
df_plot <- df_demo %>%
  filter(!is.na(precip_real),
         !is.na(hum_real),
         !is.na(size_linear))

# Verificar que haya datos
if(nrow(df_plot) < 5){
  stop("No hay suficientes datos válidos para graficar.")
}

# Modelo 2D solo para visualización
modelo_2d <- lm(size_linear ~ precip_real + hum_real,
                data = df_plot)

x1 <- df_plot$precip_real
x2 <- df_plot$hum_real
y_obs <- df_plot$size_linear

library(scatterplot3d)

8.1 Plano rotado – Ángulo 320°

grafico3d <- scatterplot3d(
  x1, x2, y_obs,
  main = "Gráfica N° 1: Superficie de respuesta de la regresión 
  lineal múltiple para el tamaño del deslizamiento (Vista: Ángulo 320°).",
  xlab = "Precipitación (mm)",
  ylab = "Humedad (%)",
  zlab = "Tamaño del deslizamiento",
  angle = 320,
  color = "darkblue",
  pch = 16
)

grafico3d$plane3d(modelo_2d,
                  draw_polygon = TRUE,
                  polygon_args = list(col = rgb(0.2,0.6,0.8,0.4)))

8.2 Plano rotado – Ángulo 250°

grafico3d <- scatterplot3d(
  x1, x2, y_obs,
  main = "Gráfica N° 2: Interacción de la Humedad y Precipitación 
  en la magnitud de deslizamientos bajo una perspectiva de 250°.",
  xlab = "Precipitación (mm)",
  ylab = "Humedad (%)",
  zlab = "Tamaño del deslizamiento",
  angle = 250,
  color = "darkblue",
  pch = 16
)

grafico3d$plane3d(modelo_2d,
                  draw_polygon = TRUE,
                  polygon_args = list(col = rgb(0.2,0.6,0.8,0.4)))

8.3 Plano rotado – Ángulo 199°

grafico3d <- scatterplot3d(
  x1, x2, y_obs,
  main = "Gráfica N° 3: Perspectiva del plano de 
  regresión para el tamaño de deslizamientos
  basada en factores hidrometeorológicos 
  (Vista: Ángulo 199°)",
  xlab = "Precipitación (mm)",
  ylab = "Humedad (%)",
  zlab = "Tamaño del deslizamiento",
  angle = 199,
  color = "darkblue",
  pch = 16
)

grafico3d$plane3d(modelo_2d,
                  draw_polygon = TRUE,
                  polygon_args = list(col = rgb(0.2,0.6,0.8,0.4)))

8.4 Discusión de los modelos tridimensionales

El análisis multivariado mediante las Gráficas N° 1, 2 y 3 permite una inspección integral de la interacción entre la precipitación, la humedad y la magnitud de los deslizamientos. Al rotar el plano de regresión en ángulos de 320°, 250° y 199°, se evidencia que el riesgo geológico no depende de una variable aislada, sino de una sinergia hidrometeorológica.

Mientras que la vista a 320° resalta el crecimiento exponencial del tamaño de los eventos ante lluvias extremas, las perspectivas de 250° y 199° confirman que incluso con precipitaciones moderadas, una humedad relativa elevada actúa como un factor crítico de inestabilidad, manteniendo los eventos alineados a la pendiente del plano predictivo. Esta consistencia visual en los tres ángulos valida la robustez del modelo lineal múltiple para identificar umbrales de alerta temprana en la gestión de desastres.

9. TEST DE PEARSON Y PRUEBA CHI-CUADRADO

El Test de Pearson y la Prueba Chi-cuadrado son herramientas estadísticas utilizadas para evaluar la relación entre variables dentro del modelo de análisis. El coeficiente de correlación de Pearson permite medir la intensidad y dirección de la relación lineal entre variables cuantitativas, mientras que la prueba Chi-cuadrado analiza la existencia de asociación entre variables categorizadas.

En este estudio, ambas pruebas se aplican con el objetivo de validar estadísticamente la relación entre las variables climáticas (precipitación y humedad) y el tamaño estimado de los deslizamientos, fortaleciendo la solidez del modelo predictivo desarrollado.

9.1 Test de Pearson

cat("TEST DE CORRELACIÓN DE PEARSON\n")
## TEST DE CORRELACIÓN DE PEARSON
# Variables del modelo
y_obs  <- df_demo$size_linear
x1     <- df_demo$precip_real
x2     <- df_demo$hum_real
y_pred <- predict(modelo_multi)
# Cálculo de correlaciones
r_total <- cor(y_obs, y_pred) * 100
r1 <- cor(y_obs, x1) * 100
r1_sq <- cor(y_obs, x1)^2 * 100
r2 <- cor(y_obs, x2) * 100
r2_sq <- cor(y_obs, x2)^2 * 100
Variables <- c("Precipitación", "Humedad", "Tamaño del deslizamiento")
Unidades <- c("mm", "%", "Índice sintético")
Tipo <- c("Independiente", "Independiente", "Dependiente")
Test <- c(round(r1, 2), round(r2, 2), "")
Correlación <- c(round(r1_sq, 2), round(r2_sq, 2), "")

Tabla_resumen <- data.frame(Variables,
                            Unidades,
                            Tipo,
                            Test,
                            Correlación)

kable(Tabla_resumen,
      format = "markdown",
      caption = "Tabla 2. Test de correlación de Pearson")
Tabla 2. Test de correlación de Pearson
Variables Unidades Tipo Test Correlación
Precipitación mm Independiente 64.12 41.11
Humedad % Independiente 7.87 0.62
Tamaño del deslizamiento Índice sintético Dependiente
cat("\nCorrelación total modelo (observado y predicho):",
    round(r_total,2), "%\n")
## 
## Correlación total modelo (observado y predicho): 65.45 %
# Test formal de significancia

test_pearson_precip <- cor.test(y_obs, x1, method = "pearson")
test_pearson_hum    <- cor.test(y_obs, x2, method = "pearson")

cat("\nP-valor Precipitación:",
    round(test_pearson_precip$p.value,5), "\n")
## 
## P-valor Precipitación: 0
cat("P-valor Humedad:",
    round(test_pearson_hum$p.value,5), "\n")
## P-valor Humedad: 0.43651
if(test_pearson_precip$p.value < 0.05){
  cat("Existe correlación significativa entre precipitación y tamaño.\n")
} else {
  cat("No existe correlación significativa entre precipitación y tamaño.\n")
}
## Existe correlación significativa entre precipitación y tamaño.
if(test_pearson_hum$p.value < 0.05){
  cat("Existe correlación significativa entre humedad y tamaño.\n")
} else {
  cat("No existe correlación significativa entre humedad y tamaño.\n")
}
## No existe correlación significativa entre humedad y tamaño.

9.1 Prueba Chi-cuadrado

cat("TEST DE CHI-CUADRADO\n")
## TEST DE CHI-CUADRADO
# Categorización
df_demo$cat_size <- cut(y_obs,
                        breaks = 3,
                        labels = c("Pequeño","Moderado","Grande"))

df_demo$cat_precip <- cut(x1,
                          breaks = 3,
                          labels = c("Baja","Media","Alta"))

tabla_cont <- table(df_demo$cat_size,
                    df_demo$cat_precip)

kable(tabla_cont,
      format = "markdown",
      caption = "Tabla 3. Tabla de contingencia")
Tabla 3. Tabla de contingencia
Baja Media Alta
Pequeño 38 0 0
Moderado 55 2 0
Grande 0 4 1
chi_test <- chisq.test(tabla_cont)
## Warning in chisq.test(tabla_cont): Chi-squared approximation may be incorrect
print(chi_test)
## 
##  Pearson's Chi-squared test
## 
## data:  tabla_cont
## X-squared = 72.428, df = 4, p-value = 6.969e-15
cat("\nEstadístico Chi-cuadrado:",
    round(chi_test$statistic,4), "\n")
## 
## Estadístico Chi-cuadrado: 72.4278
cat("P-valor:",
    round(chi_test$p.value,5), "\n")
## P-valor: 0
if(chi_test$p.value < 0.05){
  cat("Existe asociación significativa entre precipitación y tamaño.\n")
} else {
  cat("No existe asociación significativa entre precipitación y tamaño.\n")
}
## Existe asociación significativa entre precipitación y tamaño.

9. ESCENARIO PREDICTIVO

# ============================================================
# 9. CÁLCULO DE ESCENARIO PREDICTIVO (CORREGIDO)
# ============================================================

# Cambiamos "modelo_plot" por "modelo_multi" que es el que definiste en la sección 7
if(!exists("modelo_multi")){
  stop("El modelo no existe. Ejecuta primero la sección de regresión.")
}

# ================================
# Ecuación del modelo
# ================================

# Usamos modelo_multi que contiene las 3 variables (precip, hum, pop)
coeficientes <- coef(modelo_multi)

b0 <- coeficientes[1]                # Intercepto
b1 <- coeficientes["precip_real"]
b2 <- coeficientes["hum_real"]
b3 <- coeficientes["pop_norm"]

cat("\nEcuación del modelo estimado:\n")
## 
## Ecuación del modelo estimado:
cat(paste("Size_linear =", 
          round(b0,4), 
          "+", round(b1,4), "* Precipitación", 
          "+", round(b2,4), "* Humedad", 
          "+", round(b3,4), "* Población_normalizada\n\n"))
## Size_linear = 159.9548 + 2.3069 * Precipitación + -0.373 * Humedad + 8.6444 * Población_normalizada
# ================================
# Pregunta aplicada
# ================================

cat("¿Cuál será el tamaño estimado del deslizamiento si:\n")
## ¿Cuál será el tamaño estimado del deslizamiento si:
cat("Precipitación = 75 mm\n")
## Precipitación = 75 mm
cat("Humedad = 85 %\n")
## Humedad = 85 %
cat("Población normalizada = 0.7 ?\n\n")
## Población normalizada = 0.7 ?
x1_new <- 75
x2_new <- 85
x3_new <- 0.7

# Cálculo manual basado en la ecuación
y_new <- b0 + (b1 * x1_new) + (b2 * x2_new) + (b3 * x3_new)

cat(paste("Respuesta: Tamaño estimado =", 
          round(y_new,4), "\n"))
## Respuesta: Tamaño estimado = 307.3192

10. INTERPRETACIÓN DEL RESULTADO

# ============================================================
# 10. INTERPRETACIÓN DEL TAMAÑO EN PALABRAS
# ============================================================

interpretar_tamano <- function(valor){
  
  if (is.na(valor)) return("Error: Valor no calculado.")
  
  if (valor < 180) {
    return("Deslizamiento pequeño: impacto localizado y bajo riesgo estructural.")
    
  } else if (valor >= 180 && valor < 260) {
    return("Deslizamiento moderado: posible afectación de infraestructura menor.")
    
  } else if (valor >= 260 && valor < 340) {
    return("Deslizamiento grande: alta probabilidad de daños significativos.")
    
  } else {
    return("Deslizamiento severo o crítico: riesgo elevado para infraestructura y población.")
  }
}

# Aplicar interpretación usando y_new
categoria <- interpretar_tamano(y_new)
cat("\nInterpretación del tamaño estimado:\n")
## 
## Interpretación del tamaño estimado:
cat(paste("Respuesta: Tamaño estimado =", 
          round(y_new,4), "\n"))
## Respuesta: Tamaño estimado = 307.3192
cat(categoria, "\n")
## Deslizamiento grande: alta probabilidad de daños significativos.

11. CONCLUSIÓN

El modelo de regresión multivariable resultó estadísticamente significativo (F = 23.98; p = 1.147e-11), lo que confirma que las variables incluidas explican de manera conjunta el tamaño de los deslizamientos.

El coeficiente de determinación fue:

R² = 0.4284, lo que indica que el 42.84 % de la variabilidad del tamaño del deslizamiento es explicada por la precipitación, la humedad y la población normalizada.

Entre las variables analizadas:

La precipitación fue el factor más determinante (β = 2.3069; p < 0.001), mostrando una correlación de 64.12 % y una relación estadísticamente significativa.

La humedad no presentó significancia estadística (p = 0.43651 en Pearson; p = 0.0988 en regresión).

La variable poblacional tampoco mostró efecto significativo (p = 0.6420).

La prueba Chi-cuadrado confirmó una asociación significativa entre los niveles de precipitación y la magnitud del deslizamiento (χ² = 72.43; p < 0.001).

En el escenario predictivo evaluado (75 mm de precipitación, 85 % de humedad y población normalizada de 0.7), el modelo estimó un tamaño de 307.32, clasificado como deslizamiento grande.

En síntesis, los resultados evidencian que la precipitación es el principal factor explicativo del tamaño de los deslizamientos dentro del modelo analizado, mientras que la humedad y la población presentan influencia limitada en este conjunto de datos.