library(readxl)
library(tidyverse)
library(dplyr)
library(stringr)
library(ggplot2)
library(sf)
library(terra)
library(leaflet)
library(leaflet.extras)
library(geodata)
library(spdep)
library(dbscan)
library(RColorBrewer)
library(cluster)
library(factoextra)
library(inflection)
library(kableExtra)#cargo de los datos y despues análisis estadístico exploratorio
incendios_huanuco2025 <- st_read("C:/_ALIDE/Documentos/data_ciencia/MPP-CDD-02/data/serfor/incendios_huanuco.shp") ## Reading layer `incendios_huanuco' from data source
## `C:\_ALIDE\Documentos\data_ciencia\MPP-CDD-02\data\serfor\incendios_huanuco.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 1260 features and 43 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: -77.2306 ymin: -10.47345 xmax: -74.86699 ymax: -8.466419
## Geodetic CRS: WGS 84
## FUENTE DOCREG FECREG OBSERV
## Length:1260 Length:1260 Min. :1899-12-30 Length:1260
## Class :character Class :character 1st Qu.:1899-12-30 Class :character
## Mode :character Mode :character Median :1899-12-30 Mode :character
## Mean :1899-12-30
## 3rd Qu.:1899-12-30
## Max. :1899-12-30
## NA's :2
## ZONUTM ORIGEN REFER ANNO
## Min. :18 Min. :0 Length:1260 Length:1260
## 1st Qu.:18 1st Qu.:0 Class :character Class :character
## Median :18 Median :0 Mode :character Mode :character
## Mean :18 Mean :0
## 3rd Qu.:18 3rd Qu.:0
## Max. :18 Max. :0
##
## MES DIA DURAC CODPIF
## Length:1260 Length:1260 Length:1260 Length:1260
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
##
## CODRIF CODOIF CODSIN SUPTOT
## Length:1260 Length:1260 Length:1260 Min. : 0.42
## Class :character Class :character Class :character 1st Qu.: 2.80
## Mode :character Mode :character Mode :character Median : 5.62
## Mean : 12.43
## 3rd Qu.: 12.34
## Max. :272.63
##
## NOMDEP NOMPRO NOMDIS CATDEP
## Length:1260 Length:1260 Length:1260 Length:1260
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
##
## CATPRO CATDIS VERAFECT TIPRO
## Length:1260 Length:1260 Min. :0 Min. :0
## Class :character Class :character 1st Qu.:0 1st Qu.:0
## Mode :character Mode :character Median :0 Median :0
## Mean :0 Mean :0
## 3rd Qu.:0 3rd Qu.:0
## Max. :0 Max. :0
##
## CODCF CODPAS FFECHA CODRVIF
## Length:1260 Length:1260 Length:1260 Length:1260
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
##
## created_us created_da last_edite
## Length:1260 Min. :2025-09-22 Length:1260
## Class :character 1st Qu.:2025-09-22 Class :character
## Mode :character Median :2025-10-24 Mode :character
## Mean :2025-10-10
## 3rd Qu.:2025-10-24
## Max. :2025-10-24
##
## last_edi_1 GID_1 GID_0 COUNTRY
## Min. :2025-10-09 Length:1260 Length:1260 Length:1260
## 1st Qu.:2025-10-09 Class :character Class :character Class :character
## Median :2025-10-24 Mode :character Mode :character Mode :character
## Mean :2025-10-17
## 3rd Qu.:2025-10-24
## Max. :2025-10-24
##
## NAME_1 VARNAME_1 NL_NAME_1 TYPE_1
## Length:1260 Length:1260 Length:1260 Length:1260
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
##
## ENGTYPE_1 CC_1 HASC_1 ISO_1
## Length:1260 Length:1260 Length:1260 Length:1260
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
##
## [1] "sf" "data.frame"
## [1] "FUENTE" "DOCREG" "FECREG" "OBSERV" "ZONUTM"
## [6] "ORIGEN" "REFER" "ANNO" "MES" "DIA"
## [11] "DURAC" "CODPIF" "CODRIF" "CODOIF" "CODSIN"
## [16] "SUPTOT" "NOMDEP" "NOMPRO" "NOMDIS" "CATDEP"
## [21] "CATPRO" "CATDIS" "VERAFECT" "TIPRO" "CODCF"
## [26] "CODPAS" "FFECHA" "CODRVIF" "created_us" "created_da"
## [31] "last_edite" "last_edi_1" "GID_1" "GID_0" "COUNTRY"
## [36] "NAME_1" "VARNAME_1" "NL_NAME_1" "TYPE_1" "ENGTYPE_1"
## [41] "CC_1" "HASC_1" "ISO_1" "geometry"
## [1] 1260 44
# Información del CRS y tipo de geometría
# ver si está en grados, sino reproyectaremos a metros
st_crs(incendios_huanuco2025)## Coordinate Reference System:
## User input: WGS 84
## wkt:
## GEOGCRS["WGS 84",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433]],
## CS[ellipsoidal,2],
## AXIS["latitude",north,
## ORDER[1],
## ANGLEUNIT["degree",0.0174532925199433]],
## AXIS["longitude",east,
## ORDER[2],
## ANGLEUNIT["degree",0.0174532925199433]],
## ID["EPSG",4326]]
## [1] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [13] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [25] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [37] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [49] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [61] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [73] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [85] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [97] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [109] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [121] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [133] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [145] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [157] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [169] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [181] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [193] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [205] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [217] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [229] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [241] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [253] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [265] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [277] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [289] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [301] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [313] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [325] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [337] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [349] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [361] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [373] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [385] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [397] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [409] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [421] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [433] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [445] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [457] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [469] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [481] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [493] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [505] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [517] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [529] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [541] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [553] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [565] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [577] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [589] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [601] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [613] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [625] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [637] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [649] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [661] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [673] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [685] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [697] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [709] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [721] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [733] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [745] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [757] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [769] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [781] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [793] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [805] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [817] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [829] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [841] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [853] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [865] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [877] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [889] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [901] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [913] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [925] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [937] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [949] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [961] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [973] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [985] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [997] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1009] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1021] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1033] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1045] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1057] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1069] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1081] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1093] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1105] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1117] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1129] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1141] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1153] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1165] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1177] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1189] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1201] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1213] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1225] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1237] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## [1249] POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT POINT
## 18 Levels: GEOMETRY POINT LINESTRING POLYGON MULTIPOINT ... TRIANGLE
# Incluyo límites administrativos (nivel 1 = departamentos) y los pasamos a sf
peru_spat <- geodata::gadm("PER", level = 1, path = "C:/_ALIDE/tmp_gadm")
peru <- st_as_sf(peru_spat)
# Igualo CRS del límite al CRS actual de incendios (solo para poder dibujarlos juntos)
peru <- st_transform(peru, st_crs(incendios_huanuco2025))
# Filtro el departamento de Huánuco
huanuco <- peru[ peru$NAME_1 %in% c("Huánuco", "Huanuco"), ]
# Mapa combinado para ubica los puntos de ocurrencias o incendios en Huánuco.
ggplot() +
geom_sf(data = huanuco, fill = NA, color = "black", linewidth = 1) + # Polígono de Huánuco
geom_sf(data = incendios_huanuco2025, color = "red", alpha = 0.6, size = 1) + # Puntos de incendios
labs(title = "Incendios en el Departamento de Huánuco",
subtitle = "Puntos de ocurrencias",
x = "Longitud", y = "Latitud") +
theme_minimal() #PREPARACIÓN PARA CLUSTERING: COORDENADAS EN METROS
#Como K-means, DBSCAN esan tn grados reproyectamos los CRS en METROS (ajusta el EPSG a tu zona; 5347).
# Para extraer coordenadas (X,Y) en METROS (del CRS actual)
coords <- st_coordinates(incendios_huanuco2025)
incendios_huanuco2025$X <- coords[,1]
incendios_huanuco2025$Y <- coords[,2]
#lo convierte a metros
incendios_huanuco2025 <- st_transform(incendios_huanuco2025, 5347)
# 3. Mapa
ggplot() +
geom_sf(data = incendios_huanuco2025, size = 0.7, alpha = 0.7, color = "red") +
labs(title = "Puntos de incendios en Huánuco (CRS en metros)",
subtitle = "Datos en metros para clustering",
x = "Este (m)", y = "Norte (m)") +
geom_sf(data = huanuco, fill = NA, color = "black", linewidth = 1) +
theme_minimal()#Se tiene que sembrar una semilla de la aleatoriedad (centroides iniciales aleatorios)
set.seed(123)# K=3
modelo_kmeans3 <- kmeans(x=incendios_huanuco2025 %>% st_coordinates(.), # Eso hace que lea lista como dos columnas de datos de coordenadas, st_Coordinates (da la estructura)
centers=3,
nstart=25,
iter.max =20)## K-means clustering with 3 clusters of sizes 586, 238, 436
##
## Cluster means:
## X Y
## 1 3664508 8874643
## 2 3612662 8976207
## 3 3725074 8839576
##
## Clustering vector:
## [1] 1 1 1 1 1 3 3 3 1 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 1 3
## [38] 2 1 3 1 2 2 2 3 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 3 3 3 3 1 1 1 1 1 1 1 1 1
## [75] 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## [112] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## [149] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## [186] 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [223] 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [260] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [297] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [334] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3
## [371] 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## [408] 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [445] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [482] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [519] 2 2 2 2 2 2 2 2 2 2 2 2 2 3 2 2 1 1 1 1 3 1 1 1 1 1 1 1 1 1 1 3 3 3 1 1 1
## [556] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [593] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## [630] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## [667] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## [704] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## [741] 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [778] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [815] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 3 1 1 3
## [852] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 1 1 1
## [889] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [926] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3
## [963] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 1 1 1 3 3 3 3 3 3 3 3 3 1 1
## [1000] 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## [1037] 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [1074] 1 1 1 1 1 1 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2
## [1111] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [1148] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 1 1 1 1 1 1 1 1 1
## [1185] 1 1 1 1 1 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 2
## [1222] 2 2 1 1 1 1 1 1 3 1 1 1 3 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [1259] 1 1
##
## Within cluster sum of squares by cluster:
## [1] 868125698752 177627508177 360734134382
## (between_SS / total_SS = 78.1 %)
##
## Available components:
##
## [1] "cluster" "centers" "totss" "withinss" "tot.withinss"
## [6] "betweenss" "size" "iter" "ifault"
# Asigna el número de cluster a cada punto
incendios_huanuco2025 <- incendios_huanuco2025 %>%
mutate(cluster_kmeans=modelo_kmeans3$cluster)#Mapa de K=3 (solo para ver la partición en el espacio)
ggplot()+
geom_sf(data=incendios_huanuco2025, aes(color=as.factor(cluster_kmeans)))+
geom_sf(data = huanuco, fill = NA, color = "black", linewidth = 1) K-means identificó tres regiones prioritarias donde los incendios se concentran. Esto sugiere que existen factores territoriales o socioambientales que influyen en la recurrencia del fuego en esas áreas (uso de suelo, cercanía a campos agrícolas, zonas de transición bosque-selva, etc.), pero este metodo es mas limitado que el DBSCAN o HDBSCAN.
# K=8
modelo_kmeans8 <- kmeans(x = incendios_huanuco2025 %>%
st_coordinates(geometry),
centers = 8,
iter.max = 20,
nstart = 25)
modelo_kmeans8## K-means clustering with 8 clusters of sizes 201, 209, 183, 173, 111, 222, 5, 156
##
## Cluster means:
## X Y
## 1 3667735 8872056
## 2 3610637 8982440
## 3 3730720 8823766
## 4 3678274 8902616
## 5 3636327 8912009
## 6 3722680 8852664
## 7 3833443 8945707
## 8 3661615 8821570
##
## Clustering vector:
## [1] 1 1 1 1 1 6 3 6 8 6 6 6 4 4 4 4 4 4 4 5 5 5 5 5 5 4 4 5 5 5 5 5 5 5 6 1 7
## [38] 2 4 3 5 2 2 2 6 4 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 6 6 6 8 4 4 4 4 4 4 4 4 4
## [75] 4 4 4 4 4 4 4 4 6 1 1 1 1 1 8 1 1 5 1 5 5 1 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
## [112] 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## [149] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 6 6 6 6 6
## [186] 6 6 3 3 1 1 1 1 1 1 1 1 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 4 4 4 4 4
## [223] 4 6 4 4 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 1 1 1 1 1 4 4 4 4 1 1 1 5 5 5 5 5
## [260] 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
## [297] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
## [334] 4 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 2 2 2 2 2 2 2 3 3 6 8 6 8
## [371] 8 6 6 6 6 8 8 8 8 8 8 8 8 1 1 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
## [408] 6 6 6 6 6 1 1 1 1 1 1 1 1 1 1 1 8 8 8 8 1 5 5 5 4 4 4 4 4 4 4 4 4 4 4 4 4
## [445] 4 4 4 4 4 5 4 5 5 5 5 5 5 5 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [482] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 5 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [519] 2 2 2 2 2 2 2 2 2 2 2 2 2 6 2 2 4 4 4 4 6 4 4 4 4 1 1 1 6 1 1 6 6 6 1 1 1
## [556] 1 1 4 4 4 4 1 1 4 4 4 4 4 4 4 4 4 1 1 1 1 1 1 1 1 1 1 1 1 8 8 1 1 1 8 8 8
## [593] 8 8 1 1 1 1 1 1 5 5 5 5 5 5 5 5 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
## [630] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 6 6
## [667] 3 3 3 3 3 3 3 3 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 3 3 3 3 3 3 3 3 3 3 3 3 3
## [704] 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 6 6 3 3 6 6 6 6 6 6 6 6 6 6
## [741] 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 8 1 1 1 8 8 8 8 8
## [778] 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8
## [815] 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 4 1 8 8 8 6 6 1 1 6
## [852] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 4 4 4 4 4 5 5 5 5 5 5 5 5 1 1 1
## [889] 1 1 1 1 1 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 4 4 4 4 4 4 4 4 1 1 1 1 4 4 5 5 5
## [926] 5 5 5 5 5 5 5 5 5 5 5 5 5 5 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3
## [963] 3 3 3 3 3 3 3 6 6 6 6 6 6 6 6 6 6 8 8 8 8 8 8 8 8 8 6 8 6 8 8 6 6 6 6 1 1
## [1000] 1 1 1 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
## [1037] 6 6 6 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 1
## [1074] 1 1 1 4 4 4 7 7 7 7 6 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 4 2 2 2 2 2 2 2
## [1111] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
## [1148] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 6 3 3 3 5 8 8 8 8 8 1 1 1
## [1185] 1 1 1 1 1 6 6 6 6 6 6 6 6 6 6 6 6 3 6 6 3 3 8 8 8 8 6 2 2 2 2 2 2 2 2 2 2
## [1222] 2 2 5 5 5 5 5 5 6 1 8 8 3 6 6 6 6 6 6 6 6 6 6 8 1 1 1 1 1 1 1 1 1 1 1 1 1
## [1259] 1 1
##
## Within cluster sum of squares by cluster:
## [1] 64797157310 100489822452 48657413518 52067139774 65758442772
## [6] 52449108401 2235358179 57337522606
## (between_SS / total_SS = 93.1 %)
##
## Available components:
##
## [1] "cluster" "centers" "totss" "withinss" "tot.withinss"
## [6] "betweenss" "size" "iter" "ifault"
ggplot()+
geom_sf(data = huanuco, fill = NA, color = "black", linewidth = 1)+
geom_sf(data = incendios_huanuco2025, aes(color=as.factor(cluster_kmeans8)), inherit.aes = FALSE)+
labs(color="Clusters")+
scale_color_brewer(palette = "Paired")+
theme_void()
Método del Codo ¿Cuántos K elegir? este método busca el
punto de inflexión
Método silhouette
# - Silhouette: calidad promedio de asignación por K (1≈muy bien, 0≈frontera, <0≈mal)
sil_kmeans3 <- silhouette(x = modelo_kmeans3$cluster,
dist = incendios_huanuco2025 %>%
st_coordinates(.) %>%
dist())Valores cercanos a 0 indican que el punto está próximo al límite entre dos clusters.
sil_kmeans8 <- silhouette(x = modelo_kmeans8$cluster,
dist = incendios_huanuco2025 %>%
st_coordinates(.) %>%
dist())fviz_nbclust(x = incendios_huanuco2025 %>%
st_coordinates(.),
FUN = kmeans,
method = "silhouette",
k.max = 20)k-means supone clusters “compactos y de tamaño similar”. Si la forma es alargada o hay ruido/atípicos, DBSCAN/HDBSCAN suele ir mejor.
CLUSTERS POR DENSIDAD (SIN FIJAR K)
#Identificar el nivel de eps y minPts optimo
# DBSCAN usa dos parámetros:
# - eps: radio de vecindad (EN METROS, por nuestro CRS)
# - minPts: mínimo de puntos en esa vecindad para ser “núcleo”
kNNdistplot(st_coordinates(incendios_huanuco2025), k = 20)
abline(h = 150, col = "red")#para Calcular distancias al k-ésimo vecino más cercano
k <- 20
dist_knn <- kNNdist(st_coordinates(incendios_huanuco2025), k = k)
# Ordena distancias (requisito para detectar el codo)
dist_sorted <- sort(dist_knn)
idx <- seq_along(dist_sorted)
# etecta automáticamente el punto de inflexión ("codo")
knee_index <- uik(x = idx, y = dist_sorted) # uik = unit invariant knee
eps_optimo <- dist_sorted[knee_index]
eps_optimo## [1] 2976.641
El eps óptimo ordenado es 3000 o 3 km
#Un primer intento (ajustado la escala a 3000 m o 3 km).
modelo_dbscan <- dbscan(x = incendios_huanuco2025 %>%
st_coordinates(.),
eps = 3000,
minPts = 15)## DBSCAN clustering for 1260 objects.
## Parameters: eps = 3000, minPts = 15
## Using euclidean distances and borderpoints = TRUE
## The clustering contains 11 cluster(s) and 1002 noise points.
##
## 0 1 2 3 4 5 6 7 8 9 10 11
## 1002 16 46 21 27 26 18 28 28 17 16 15
##
## Available fields: cluster, eps, minPts, metric, borderPoints
# Etiquetamos: cluster 0 = ruido (no asignado a ningún núcleo)
incendios_huanuco2025 <- incendios_huanuco2025 %>%
mutate(cluster_dbscan=modelo_dbscan$cluster)# Mapa: ruido en gris, clusters con color
ggplot()+
geom_sf(data = huanuco, fill = NA, color = "black", linewidth = 1)+
geom_sf(data=incendios_huanuco2025 %>%
filter(cluster_dbscan==0), color="gray", size=0.7)+
geom_sf(data=incendios_huanuco2025 %>%
filter(cluster_dbscan!=0), aes(color=as.factor(cluster_dbscan)))#Para hacer un zoom hacemos un interactivo
leaflet() %>%
addTiles() %>%
addCircleMarkers(data=incendios_huanuco2025 %>%
filter(cluster_dbscan!=0) %>%
st_transform(4326))pal <- colorFactor(palette = colorRampPalette(brewer.pal(12, "Set3"))(51),
domain = incendios_huanuco2025$cluster_dbscan)leaflet() %>%
addProviderTiles(providers$CartoDB.DarkMatter) %>%
addCircleMarkers(
data = incendios_huanuco2025 %>%
st_transform(4326) %>%
filter(cluster_dbscan != 0),
radius = 3,
color = ~pal(cluster_dbscan),
fillOpacity = 0.8,
stroke = TRUE,
weight = 1
) %>%
addMiniMap(tiles = providers$CartoDB.DarkMatter)#Envolventes convexas por cluster (para visualizar “manchas”)
incendios_dbscan <- incendios_huanuco2025 %>%
filter(cluster_dbscan != 0) %>%
group_by(cluster_dbscan) %>%
summarise(geometry = st_union(geometry)) %>%
st_convex_hull()# Mapa interactivo (Web Mercator) con puntos/convex-hull
leaflet() %>%
addProviderTiles(providers$CartoDB.DarkMatter) %>%
addPolygons(data=incendios_dbscan %>%
st_transform(4326),
color = ~pal(cluster_dbscan),
popup = ~paste0("Cluster N°: ", cluster_dbscan)) %>%
addCircleMarkers(data=incendios_huanuco2025 %>%
st_transform(4326) %>%
filter(cluster_dbscan != 0),
radius = 3,
color = ~pal(cluster_dbscan),
fillOpacity = 0.8,
stroke = TRUE,
weight = 1) %>%
addMiniMap(tiles = providers$CartoDB.DarkMatter)sil_dbscan <- silhouette(modelo_dbscan$cluster, incendios_huanuco2025 %>%
st_coordinates(.) %>%
dist())#Silhouette de DBSCAN (usualmente ignorando ruido = 0)
sil_dbscan %>%
as.data.frame() %>%
filter(cluster!=0) %>%
summarise(sil_width=mean(sil_width))AJUSTE AUTOMÁTICO DE eps CON “CODO” kNN
Método k-NN (K-Nearest Neighbors)
#Distancias al k-ésimo vecino (k=20), 2) ordenarlas, 3) buscar el “codo”
knndist_dbscan <- kNNdist(x = incendios_huanuco2025 %>%
st_coordinates(.),
k = 20)## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 2809 5042 6729 8829 10643 146849
## [1] 2
## [1] 2976.641
#Visual para documentar la elección
kNNdistplot(x = incendios_huanuco2025 %>%
st_coordinates(.),
k = 20)
abline(v = knee_index, col = "red")
abline(h = eps_optimo, col = "steelblue")modelo_dbscan_ajustado <- dbscan(x = incendios_huanuco2025 %>%
st_coordinates(.),
eps = eps_optimo,
minPts = 20)## DBSCAN clustering for 1260 objects.
## Parameters: eps = 2976.64145565701, minPts = 20
## Using euclidean distances and borderpoints = TRUE
## The clustering contains 2 cluster(s) and 1215 noise points.
##
## 0 1 2
## 1215 22 23
##
## Available fields: cluster, eps, minPts, metric, borderPoints
sil_dbscan_ajustado <- silhouette(modelo_dbscan_ajustado$cluster, incendios_huanuco2025 %>%
st_coordinates(.) %>%
dist())# Nueva silhouette (excluyendo ruido)
sil_dbscan_ajustado %>%
as.data.frame() %>%
filter(cluster!=0) %>%
summarise(sil_width=mean(sil_width))incendios_huanuco2025 <- incendios_huanuco2025 %>%
mutate(cluster_dbscan_ajustado=modelo_dbscan_ajustado$cluster)# Envolventes para los clusters ajustados (solo visual)
incendios_dbscan_ajustado <- incendios_huanuco2025 %>%
filter(cluster_dbscan_ajustado != 0) %>%
group_by(cluster_dbscan_ajustado) %>%
summarise(geometry = st_union(geometry)) %>%
st_convex_hull()# Mapa interactivo con capas (clusters / ruido) con control
leaflet() %>%
addProviderTiles(providers$CartoDB.DarkMatter) %>%
addPolygons(data=incendios_dbscan_ajustado %>%
st_transform(4326),
color = ~pal(cluster_dbscan_ajustado),
popup = ~paste0("Cluster N°: ", cluster_dbscan_ajustado)) %>%
addCircleMarkers(data=incendios_huanuco2025 %>%
st_transform(4326) %>%
filter(cluster_dbscan_ajustado != 0),
radius = 3,
color = ~pal(cluster_dbscan_ajustado),
fillOpacity = 0.5,
stroke = TRUE,
weight = 1) %>%
addMiniMap(tiles = providers$CartoDB.DarkMatter)leaflet() %>%
addProviderTiles(providers$CartoDB.DarkMatter) %>%
addPolygons(data=incendios_dbscan_ajustado %>%
st_transform(4326),
color = ~pal(cluster_dbscan_ajustado),
popup = ~paste0("Cluster N°: ", cluster_dbscan_ajustado)) %>%
addCircleMarkers(data=incendios_huanuco2025 %>%
st_transform(4326) %>%
filter(cluster_dbscan_ajustado != 0),
radius = 3,
color = "#7B1FA2",
fillOpacity = 0.8,
stroke = TRUE,
weight = 1) %>%
addMiniMap(tiles = providers$CartoDB.DarkMatter)HDBSCAN: DENSIDAD JERÁRQUICA (SIN eps)
# Ventaja: no requiere eps y maneja densidades heterogéneas; entrega "scores" de estabilidad.
modelo_hdbscan <- hdbscan(x = incendios_huanuco2025 %>%
st_coordinates(.),
minPts = 20)## HDBSCAN clustering for 1260 objects.
## Parameters: minPts = 20
## The clustering contains 6 cluster(s) and 196 noise points.
##
## 0 1 2 3 4 5 6
## 196 204 31 23 93 365 348
##
## Available fields: cluster, minPts, coredist, cluster_scores,
## membership_prob, outlier_scores, hc
ggplot()+
geom_sf(data = huanuco, fill = NA, color = "black", linewidth = 1)+
geom_sf(data=incendios_huanuco2025 %>%
filter(cluster_hdbscan==0),
color="gray", size=0.5)+
geom_sf(data=incendios_huanuco2025 %>%
filter(cluster_hdbscan!=0),
aes(color=as.factor(cluster_hdbscan)))+
labs(color="Clusters")+
theme_void()# Mapa: ruido (0) en gris, clusters coloreados
pal_hdbscan <- colorFactor(palette = colorRampPalette(brewer.pal(12, "Set3"))(90),
domain = incendios_huanuco2025$cluster_hdbscan)# Envolventes convexas por cluster HDBSCAN (visual)
incendios_hdbscan <- incendios_huanuco2025 %>%
dplyr::filter(cluster_hdbscan != 0) %>%
dplyr::group_by(cluster_hdbscan) %>%
dplyr::summarise(n = dplyr::n(), .groups = "drop") %>%
sf::st_convex_hull()# Leaflet de HDBSCAN (puntos + envolventes)
leaflet() %>%
addProviderTiles(providers$CartoDB.DarkMatter) %>%
# Polígonos (envolventes)
addPolygons(
data = incendios_hdbscan %>% st_transform(4326),
color = ~pal_hdbscan(cluster_hdbscan),
fillColor = ~pal_hdbscan(cluster_hdbscan),
fillOpacity = 0.25,
weight = 2
) %>%
# Puntos de clúster
addCircleMarkers(
data = incendios_huanuco2025 %>%
st_transform(4326) %>%
dplyr::filter(cluster_hdbscan != 0),
radius = 4,
color = ~pal_hdbscan(cluster_hdbscan),
fillOpacity = 0.85,
stroke = FALSE
) %>%
# Puntos ruido (cluster 0) opcional
addCircleMarkers(
data = incendios_huanuco2025 %>%
st_transform(4326) %>%
dplyr::filter(cluster_hdbscan == 0),
radius = 2,
color = "gray70",
fillOpacity = 0.4,
stroke = FALSE
) %>%
addMiniMap(tiles = providers$CartoDB.DarkMatter)El método eliminó gran parte del “ruido”, es decir, los puntos aislados sin patrón claro. Cada envolvente (polígono) muestra la extensión geográfica de cada clúster, no solo puntos sueltos.
# Métrica silhouette (excluyendo ruido)
sil_hdbscan <- silhouette(modelo_hdbscan$cluster, incendios_huanuco2025 %>%
st_coordinates(.) %>%
dist())# Estabilidad de clusters (propia de HDBSCAN), valores mayores = clusters más robustos
hdbscan_estabilidad <- incendios_huanuco2025 %>%
filter(cluster_hdbscan!=0) %>%
group_by(cluster_hdbscan) %>%
summarise(n=n()) %>%
mutate(estabilidad=modelo_hdbscan$cluster_scores)