El análisis del comercio internacional permite identificar patrones y relaciones entre los países a partir de los flujos de importaciones y exportaciones. En este contexto, las técnicas de agrupamiento ofrecen herramientas para clasificar observaciones de acuerdo con características similares, sin necesidad de establecer previamente el número de grupos.
El presente trabajo aplica el algoritmo DBSCAN (Density-Based Spatial Clustering of Applications with Noise) al análisis del comercio exterior de Alemania durante 2023, utilizando información sobre sus importaciones y exportaciones con sus diferentes socios comerciales. A través de este método se busca identificar grupos de países con comportamientos comerciales similares y distinguir aquellas observaciones que presentan características atípicas o que no pertenecen a un conglomerado definido. Para ello, se desarrolla el fundamento matemático de DBSCAN, se determinan sus parámetros y se presentan los resultados obtenidos mediante tablas y representaciones gráficas.
El clustering o agrupamiento es una técnica de aprendizaje no supervisado cuyo propósito es descubrir patrones ocultos y agrupar observaciones similares dentro de un conjunto de datos, sin necesidad de contar previamente con etiquetas o clases definidas (Kumar, 2026). En el análisis económico, esta herramienta resulta particularmente útil para simplificar bases de datos extensas —como los flujos comerciales reportados por organismos internacionales— en subgrupos significativos que permitan identificar relaciones, similitudes o comportamientos atípicos entre países, sectores o productos.
De manera general, los algoritmos de clustering se agrupan en dos grandes familias, cuya diferencia radica en la lógica con la que construyen los grupos:
| Categoría | Lógica de construcción | Ejemplos |
|---|---|---|
| Clustering Jerárquico | Construye un árbol binario (dendrograma) mediante fusiones o divisiones sucesivas entre observaciones, sin fijar de antemano el número de grupos | Método de Ward |
| Clustering No Jerárquico | Particiona directamente los datos en un número determinado de grupos, ya sea por cercanía a un centro (particional) o por concentración de puntos (basado en densidad) | K-means, K-medianas/PAM, DBSCAN |
La elección del método no es arbitraria: depende de la naturaleza estadística de los datos que ofrece cada fuente. El método de Ward, por ejemplo, resulta adecuado para variables con gradación continua de desarrollo, como las del Banco Mundial; K-medianas/PAM se ajusta mejor a datos volátiles y con presencia de valores extremos, como los del FMI; K-means funciona bien en economías relativamente homogéneas, como las de la OCDE; y DBSCAN es idóneo cuando el fenómeno de interés involucra densidad variable y detección de ruido, como ocurre con los datos de comercio internacional de UN Comtrade.
DBSCAN (Density-Based Spatial Clustering of Applications with Noise) es un algoritmo de agrupamiento basado en la densidad de los puntos en el espacio de datos, propuesto originalmente por Ester et al. (1996) como respuesta a tres necesidades que los métodos clásicos no resolvían bien en bases de datos grandes: requerir un mínimo de conocimiento previo del dominio para fijar parámetros, ser capaces de descubrir clústeres de forma arbitraria (no solo esférica) y mantener buena eficiencia computacional.
A diferencia de métodos que exigen definir de antemano el número de grupos, DBSCAN identifica los clústeres como regiones de alta densidad separadas por zonas de baja densidad, a partir de dos parámetros:
Con base en estos parámetros, el algoritmo clasifica cada observación en uno de tres tipos (Kumar, 2026):
DBSCAN pertenece a la categoría de Clustering No Jerárquico, específicamente al subtipo basado en densidad (a diferencia del particional, como K-means, que agrupa por cercanía a un centroide). No construye un árbol o dendrograma de fusiones sucesivas como los métodos jerárquicos (por ejemplo, Ward); en cambio, particiona directamente el conjunto de datos en grupos densos y observaciones de ruido, sin ninguna estructura jerárquica de por medio (Ester et al., 1996). Esta característica implica que el número final de clústeres no se decide de antemano por el analista, sino que emerge de la propia estructura de densidad de los datos.
DBSCAN resulta idóneo para los datos obtenidos de la API de UN Comtrade porque los flujos comerciales entre países no se distribuyen de manera homogénea: existen “hubs” comerciales de alta densidad (economías con múltiples socios y montos de comercio elevados) junto a relaciones comerciales dispersas, esporádicas o marginales. Thamrin et al. (2025) aplicaron un enfoque híbrido de clustering combinando DBSCAN, el método del codo y mapas autoorganizados (SOM) sobre datos comerciales promedio de 25 países entre 2013 y 2023, y comprobaron que DBSCAN detecta eficazmente tanto los hubs comerciales densos como los comportamientos atípicos en los patrones de exportación e importación. Los autores identificaron tres clústeres consistentes con teorías económicas establecidas (el modelo de Heckscher-Ohlin y la teoría de la dependencia): líderes del comercio global, potencias comerciales emergentes y exportadores de nicho.
Esta capacidad de aislar el ruido sin forzar cada observación dentro de un clúster es clave para datos como los de Comtrade, donde los valores atípicos picos inusuales de exportación, socios comerciales esporádicos o relaciones bilaterales poco frecuentes son habituales y no representan necesariamente errores de medición, sino información relevante que métodos como K-means tenderían a distorsionar al obligar a cada país a pertenecer a un grupo predefinido (Kumar, 2026).
Además, al no exigir que los clústeres tengan forma esférica ni densidad homogénea, DBSCAN puede reconocer agrupaciones comerciales irregulares —por ejemplo, bloques regionales con dinámicas de comercio propias sin necesidad de fijar de antemano el número de grupos, lo cual resulta apropiado para el análisis exploratorio de datos de comercio internacional cuya estructura no se conoce a priori (Ester et al., 1996).
DBSCAN (Density-Based Spatial Clustering of Applications with Noise) es un algoritmo que se fundamenta matemáticamente sobre la teoría de conjuntos, la geometría métrica y el concepto de densidad local de puntos en un espacio métrico. Sus definiciones formales, propuestas por Ester et al. (1996, como se cita en Hahsler et al., 2019), se presentan a continuación.
Notación. \(D = \{p_1, \ldots, p_n\}\) es el conjunto de \(n\) puntos, y cada punto \(p_i = (p_{i1}, \ldots, p_{im})\) está descrito por \(m\) variables. \(d(p,q)\) es la distancia entre dos puntos. El símbolo \(\in\) se lee “pertenece a”; \(|A|\) es el número de elementos del conjunto \(A\); \(\mathbb{R}^{+}\) y \(\mathbb{Z}^{+}\) son los reales y los enteros positivos.
DBSCAN requiere que el usuario fije dos parámetros: el radio \(\varepsilon\) y el umbral \(\mathrm{minPts}\) (Altaei, 2024; Hahsler et al., 2019, p. 9). Intuitivamente, \(\varepsilon\) determina qué tan cerca deben estar dos puntos para considerarse vecinos, y \(\mathrm{minPts}\) cuántos vecinos hacen falta para hablar de una zona densa. Ninguno de los dos puede definirse con rigor sin antes precisar qué es una vecindad y qué clases de puntos distingue el algoritmo. Por eso, en la sección siguiente se presentan esas dos definiciones y, después, se formaliza cada parámetro.
Definición 1. Vecindad \(\varepsilon\). La vecindad \(\varepsilon\) de un punto \(p\) es el conjunto de puntos que están a una distancia menor o igual que \(\varepsilon\) de él:
\[ N_\varepsilon(p)=\{\,q\in D \mid d(p,q)\le\varepsilon\,\} \]
La distancia habitual es la euclídea (Hahsler et al., 2019, p. 9):
\[ d(p,q)=\sqrt{\sum_{k=1}^{m}\left(p_k-q_k\right)^2} \]
El propio \(p\) siempre pertenece a su vecindad, pues \(d(p,p)=0\) (Hahsler et al., 2019, p. 3).
Definición 2. Clases de puntos. Un punto \(p \in D\) es:
Núcleo (core), si \(|N_\varepsilon(p)|\ge \mathrm{minPts}\).
Borde (border), si no es núcleo, pero existe un núcleo \(q \in D\) tal que \(p \in N_{\varepsilon}(q)\).
Ruido, en cualquier otro caso (Hahsler et al., 2019, p. 3).
\(\varepsilon \in \mathbb{R}^{+}\) (radio). Es la distancia máxima que define la vecindad y se expresa en las mismas unidades que \(d\). Como \(|N_{\varepsilon}(p)|\) equivale a una estimación de densidad no normalizada con núcleo uniforme y ancho de banda \(\varepsilon\) (Hahsler et al., 2019, p. 3), \(\varepsilon\) fija la escala a la que se mide la densidad.
\(\mathrm{minPts} \in \mathbb{Z}^{+}\) (umbral de densidad). Es el número mínimo de puntos que debe tener una vecindad para que su centro sea núcleo: \(p\) es núcleo si y solo si \(|N_{\varepsilon}(p)| \geq \mathrm{minPts}\) (Hahsler et al., 2019, pp. 3, 9). Este conteo incluye al propio \(p\) (Altaei, 2024).
En conjunto, el par \((\varepsilon, \mathrm{minPts})\) fija un único nivel de densidad: la zona alrededor de \(p\) es densa si contiene al menos \(\mathrm{minPts}\) puntos a distancia menor o igual que \(\varepsilon\).
Definición 3. Directamente alcanzable por densidad. Un punto \(q\) es directamente alcanzable desde \(p\) respecto a \(\varepsilon\) y \(\mathrm{minPts}\) si, y solo si:
Es decir, \(p\) debe ser núcleo y \(q\) debe estar en su vecindad (Hahsler et al., 2019, p. 4).
Definición 4. Alcanzable por densidad. Un punto \(p\) es alcanzable desde \(q\) si existe en \(D\) una secuencia \((p_1,p_2,\ldots,p_n)\), con \(q=p_1\) y \(p=p_n\), tal que cada \(p_{i+1}\) es directamente alcanzable desde \(p_i\), para todo \(i \in \{1,2,\ldots,n-1\}\) (Hahsler et al., 2019, p. 4). De la Definición 3 se sigue que todos los puntos de la cadena, salvo quizá el último, son núcleo. Por eso la alcanzabilidad es asimétrica: desde un núcleo se puede llegar a un punto de borde, pero no a la inversa.
Definición 5. Conectado por densidad. Un punto \(p\) está conectado por densidad con \(q\) si existe un punto \(o \in D\) tal que tanto \(p\) como \(q\) son alcanzables desde \(o\) (Hahsler et al., 2019, p. 4). Esta relación es simétrica y permite vincular puntos de borde que no se alcanzan entre sí.
Definición 6. Cluster basado en densidad. Un cluster \(C\) es un subconjunto no vacío de \(D\) que cumple:
El procedimiento sigue la secuencia de Altaei (2024), generalizada, y la lógica de expansión descrita por Hahsler et al. (2019, p. 5).
Paso 1. Fijar los parámetros y preparar los datos. Se eligen \(\varepsilon\) y \(\mathrm{minPts}\), y se llevan todas las variables a escalas comparables (por ejemplo, normalizándolas al intervalo \([0,1]\)).
Paso 2. Calcular las distancias entre todos los puntos. Para cada par de puntos \(p_i\) y \(p_j\), descritos por \(m\) variables, se calcula la distancia euclídea:
\[ d(p_i,p_j) = \sqrt{\sum_{k=1}^{m}(p_{ik}-p_{jk})^2} \]
Los resultados se ordenan en una matriz de distancias \(M\), de \(n \times n\), donde cada entrada es:
\[ M_{ij}=d(p_i,p_j) \]
La diagonal vale cero, porque cada punto está a distancia cero de sí mismo:
\[ M_{ii}=0 \]
Paso 3. Identificar los vecinos y clasificar los puntos. Cada fila \(i\) de \(M\) contiene las distancias de \(p_i\) a todos los demás puntos. Sus vecinos son los que están a una distancia menor o igual que \(\varepsilon\):
\[N_\varepsilon(p_i)=\{\,p_j\in D \mid M_{ij}\le\varepsilon\,\}\]
El propio \(p_i\) siempre cuenta como vecino, porque \(M_{ii}=0\). Luego se compara el número de vecinos con \(\mathrm{minPts}\):
Paso 4. Formar los clusters y obtener el resultado. Se toma un núcleo \(p\) que aún no tenga cluster y se inicia el cluster \(C_k\) con su vecindad:
\[ C_k=N_{\varepsilon}(p) \]
Luego se amplía con la vecindad de cada núcleo \(q\) que se vaya incorporando:
\[ C_k \leftarrow C_k \cup N_{\varepsilon}(q), \qquad \text{para todo núcleo } q \in C_k \]
Los puntos de borde se suman al cluster, pero no propagan la expansión. Cuando \(C_k\) deja de crecer, se repite el proceso con otro núcleo sin asignar (\(k=k+1\)), hasta agotarlos.
El resultado son los \(K\) clusters \(C_1,\ldots,C_K\), cuyo número no se fijó de antemano, y el conjunto de ruido, formado por los puntos que no quedaron asignados:
\[ R = D \setminus \left( C_1 \cup \cdots \cup C_K \right) \]
DBSCAN es un algoritmo de agrupamiento basado en densidad (Ester et al., 1996): en lugar de agrupar por distancia a un centro (metodos de particion) o por fusion sucesiva (jerarquicos), agrupa segun la densidad de puntos en una vecindad. Esto le permite detectar formas arbitrarias, no requerir definir k de antemano, y marcar explicitamente los valores atipicos como ruido.
| Ventaja de DBSCAN | Limitacion de Ward |
|---|---|
| No requiere un parametro de distancia jerarquico previo | Ward construye toda la jerarquia (dendrograma) y luego hay que decidir donde cortarla para obtener los clusters finales |
| Detecta ruido/outliers de forma explicita | Ward no tiene nocion de ‘ruido’; cada punto termina asignado a algun nodo del arbol, sin excepcion |
| Es mas eficiente computacionalmente en datasets grandes | El agrupamiento jerarquico es computacionalmente costoso; su complejidad crece mucho mas rapido que la de DBSCAN |
| Resultado interpretable sin depender del tamano del dataset | Los dendrogramas se vuelven dificiles de visualizar e interpretar cuando el dataset es grande |
| Desventaja de DBSCAN | Fortaleza de Ward |
|---|---|
| Sensible a ε y minPts; requiere prueba y error | No fija parametros de vecindad; se corta el dendrograma despues |
| Rinde mal con clusters de densidades muy distintas | Minimiza varianza intra-cluster, tolera densidad variable |
| Se limita en alta dimensionalidad | Igual de sensible, pero entrega estructura jerarquica interpretable |
| Ventaja de DBSCAN | Limitacion de PAM |
|---|---|
| Detecta clusters de forma arbitraria | PAM no es apto para cumulos no esfericos o de forma arbitraria; es un metodo de particion, adecuado solo para grupos esfericos/convexos |
| No requiere definir k de antemano | PAM, igual que k-means, requiere que el usuario especifique k antes de correr el algoritmo |
| Maneja mejor el ruido y los valores extremos | PAM suele presentar dificultades cuando hay valores extremos o datasets ruidosos (aunque es mas robusto que k-means por usar medoides) |
| Resultados estables segun la densidad, no segun la inicializacion | Los resultados de PAM pueden variar entre ejecuciones, debido a la inicializacion aleatoria de los medoides |
| Deja explicitamente puntos fuera de todo cluster (ruido) | PAM asigna cada objeto a su medoide mas cercano; no existe categoria de ‘sin cluster’ |
| Desventaja de DBSCAN | Fortaleza de PAM |
|---|---|
| Sensible a ε y minPts; requiere prueba y error | Exige k, pero menos sensible a mala inicializacion (medoides reales) |
| Rinde mal con clusters de densidades muy distintas | No depende de densidad; usa el medoide mas representativo |
| Se limita en alta dimensionalidad | Igual de afectado, pero robusto a outliers por usar medoides |
| Ventaja de DBSCAN | Limitacion de K-Means |
|---|---|
| No requiere definir el numero de clusters (k) | K-means exige especificar k antes de correr el algoritmo; una mala eleccion distorsiona el resultado |
| Detecta clusters de forma arbitraria | K-means asume clusters esfericos/convexos y falla con formas como anillos, bandas o forma de S |
| Identifica outliers explicitamente como ruido | K-means fuerza a cada punto a pertenecer a algun cluster; un outlier puede arrastrar y deformar todo un cluster (por usar la media) |
| Funciona bien con clusters de densidades/tamanos distintos | K-means tiende a repartir mal cuando los grupos tienen tamanos muy desiguales, por depender del centroide |
| Desventaja de DBSCAN | Fortaleza de K-means |
|---|---|
| Sensible a ε y minPts; requiere prueba y error | Solo exige definir k; mas simple de ajustar |
| Rinde mal con clusters de densidades muy distintas | Funciona bien con densidad y tamano homogeneos |
| Se limita en alta dimensionalidad | Se degrada tambien, pero se combina facil con PCA |
| Complejidad, poco eficiente en datos grandes | Mas eficiente, escala mejor a datasets grandes |
Antes de especificar el método que corresponde al algoritmo asignado, es necesario reconocer que existen distintas métricas generales para determinar el número óptimo de clústeres o los parámetros de un modelo de agrupamiento, dependiendo de la familia de algoritmo empleada. Las cuatro más relevantes para los algoritmos revisados en clase son el método del codo, el coeficiente de silueta, el dendrograma y el gráfico de k-vecinos.
Método del codo (Elbow Method). Consiste en ejecutar el algoritmo de clustering (típicamente K-means) para un rango de valores de K, calcular en cada caso una medida de error o dispersión interna (como la inercia, es decir, la suma de las distancias al cuadrado de cada punto a su centroide) y graficar esta medida contra el número de clústeres. El punto donde la curva cambia bruscamente de pendiente, asemejando el codo de un brazo, señala el número óptimo de clústeres (Moya, 2016). El mismo principio de identificar un “codo” en una curva de error se emplea también, con otro propósito, para seleccionar valores óptimos de parámetros en otros algoritmos, incluido el propio k-vecinos (GeeksforGeeks, 2026).
Coeficiente de silueta. Mide, para cada observación, qué tan bien encaja dentro de su propio clúster en comparación con los demás clústeres, combinando cohesión interna y separación externa en un valor entre -1 y 1. Se calcula para distintos números de clústeres y se selecciona aquel que maximiza la silueta promedio. Es especialmente útil en algoritmos particionados y jerárquicos, aunque tiende a favorecer clústeres compactos y de forma esférica (Largo L., 2025).
Dendrograma. Es una representación gráfica en forma de árbol, propia de los métodos jerárquicos, que organiza las observaciones según su similitud progresiva. Se construye calculando iterativamente la distancia entre todos los puntos o grupos ya formados, uniendo en cada paso los dos más cercanos, hasta formar una sola rama. El número óptimo de clústeres se decide “cortando” el árbol a la altura donde se maximiza la distancia entre las uniones sucesivas (Moya, 2016).
Gráfico de k-vecinos (k-distance plot). Se basa en el concepto de vecinos más cercanos (k-nearest neighbors): para cada observación se calcula su distancia al k-ésimo vecino más próximo, estas distancias se ordenan de menor a mayor y se grafican; el punto de inflexión o “codo” de esa curva señala el parámetro de distancia óptimo. Es el método propio de los algoritmos basados en densidad (Ester et al., 1996; Kavlakoglu, 2021).
De las cuatro métricas descritas, la que corresponde analíticamente a DBSCAN es el gráfico de k-vecinos. Esto se debe a que DBSCAN no requiere fijar de antemano un número de clústeres (a diferencia de K-means o de los métodos jerárquicos), sino dos parámetros de vecindad y densidad: eps y minPts (Ester et al., 1996). Por lo tanto, el método del codo aplicado a la inercia de K-means, el coeficiente de silueta y el dendrograma no son directamente aplicables para calibrar DBSCAN; en su lugar, se emplea el mismo principio del “codo”, pero aplicado a las distancias de vecindad (k-vecinos) en lugar de a la inercia o a la altura de un dendrograma.
El algoritmo de k-vecinos más cercanos (k-nearest neighbors, KNN) es un método no paramétrico que emplea la proximidad entre observaciones para realizar clasificaciones, predicciones o, como en este caso, para caracterizar la densidad local de los datos (Kavlakoglu, 2021). El parámetro k indica cuántos vecinos cercanos se consideran al evaluar un punto: valores bajos de k generan mayor varianza (sensibilidad al ruido), mientras que valores altos producen mayor sesgo y suavizan en exceso la estructura de los datos (Kavlakoglu, 2021; GeeksforGeeks, 2026).
El algoritmo se implementa en R mediante la función dbscan() del paquete dbscan (Hahsler et al., 2019). Sin embargo, previo a su ejecución, es fundamental determinar el valor óptimo del parámetro del radio (ϵ).
Siguiendo la propuesta clásica de Ester et al. (1996) e implementada por Hahsler et al. (2019), el valor óptimo de ϵ se identifica mediante el método de la distancia al k-ésimo vecino más cercano, utilizando la función kNNdistplot(). Este procedimiento calcula la distancia euclídea de cada observación estandarizada a sus k vecinos más cercanos (k=minPts=6), permitiendo localizar el “punto de codo” donde la densidad del espacio cambia de forma crítica.
library(comtradr) # Descarga de datos de UN Comtrade
library(dplyr) # Limpieza y manipulación de datos
library(dbscan) # Algoritmo DBSCAN y gráfico kNNdist
library(ggplot2) # Gráfica de dispersión
library(knitr) # Formato de tablas
Se descargan dos flujos comerciales independientes: las importaciones (import) y las exportaciones (export) para la totalidad de los socios comerciales registrados (partner = “all_countries”) bajo la categoría agregada de bienes (commodity_code = “TOTAL”).
# Consulta de Importaciones de Alemania (DEU) en 2023
importaciones <- ct_get_data(
reporter = "DEU", partner = "all_countries",
start_date = "2023", end_date = "2023",
commodity_code = "TOTAL", flow_direction = "import"
)
# Consulta de Exportaciones de Alemania (DEU) en 2023
exportaciones <- ct_get_data(
reporter = "DEU", partner = "all_countries",
start_date = "2023", end_date = "2023",
commodity_code = "TOTAL", flow_direction = "export"
)
# Muestra de datos brutos provenientes de la API
importaciones %>%
select(reporter_iso, partner_iso, flow_desc, cifvalue,) %>%
head(5) %>%
kable(
format.args = list(big.mark = ",", scientific = FALSE),
col.names = c("Reportero", "Socio ISO", "Flujo", "Valor CIF (USD)"),
caption = "Muestra de datos brutos descargados de la API"
)
| Reportero | Socio ISO | Flujo | Valor CIF (USD) |
|---|---|---|---|
| DEU | AFG | Import | 14,968,497.4 |
| DEU | ALB | Import | 243,484,326.4 |
| DEU | ATA | Import | 402,397.9 |
| DEU | DZA | Import | 1,631,439,925.3 |
| DEU | ASM | Import | 164,411.3 |
La consulta se realiza a frecuencia anual especificando el periodo 2023 (start_date = ‘2023’, end_date = ‘2023’), lo que consolida el flujo comercial total acumulado en ese año para cada socio, evitando el sesgo o la estacionalidad de los datos mensuales.
Filtrado de agregados globales: se eliminan el total mundial (World, W00, WLD, 0-World) y los grupos de países sin identificar (Other Asia, nes; Other Africa, nes; Areas, nes), para conservar únicamente las relaciones bilaterales con entidades territoriales específicas.
Consolidación (Inner Join): se combinan las tablas
de importaciones (valor CIF) y exportaciones (valor FOB) mediante el
código partner_iso, conservando los socios que aparecen en
ambos flujos. Quedan 222 socios.
Tratamiento de valores faltantes: se verificó que ninguno de los flujos presenta valores faltantes, por lo que no fue necesario imputar ni excluir socios.
# Depuración de registros globales no territoriales
imp_clean <- importaciones %>%
filter(!partner_iso %in% c("World", "0", "000", "WLD", "W00", "0-World"),
!grepl(", nes$|^Areas", partner_desc)) %>%
select(partner_iso, partner_desc, valor_importado = cifvalue)
exp_clean <- exportaciones %>%
filter(!partner_iso %in% c("World", "0", "000", "WLD", "W00", "0-World"),
!grepl(", nes$|^Areas", partner_desc)) %>%
select(partner_iso, valor_exportado = fobvalue)
# Unión interna para consolidar importaciones y exportaciones por socio
datos <- inner_join(imp_clean, exp_clean, by = "partner_iso") %>%
arrange(partner_iso)
# Tabla 1: datos limpios y consolidados
datos %>%
select(partner_iso, partner_desc, valor_importado, valor_exportado) %>%
head(6) %>%
kable(
digits = 0,
format.args = list(big.mark = ",", scientific = FALSE),
col.names = c("ISO", "Socio Comercial", "Importaciones (USD)", "Exportaciones (USD)"),
caption = "Tabla 1: Muestra de datos procesados por país socio"
)
| ISO | Socio Comercial | Importaciones (USD) | Exportaciones (USD) |
|---|---|---|---|
| ABW | Aruba | 46,301 | 7,034,324 |
| AFG | Afghanistan | 14,968,497 | 42,186,122 |
| AGO | Angola | 114,690,342 | 309,985,499 |
| AIA | Anguilla | 128,688 | 11,349 |
| ALB | Albania | 243,484,326 | 441,024,933 |
| AND | Andorra | 4,943,228 | 69,570,514 |
La tabla muestra los datos ya consolidados por socio comercial para los flujos de importación y exportación de Alemania en 2023. Se observa una marcada disparidad en la escala de los valores de comercio bilateral: desde transacciones menores como las de Aruba (46 mil USD en importaciones) o Anguila (11 mil USD en exportaciones), hasta flujos que superan los 400 millones de dólares con Albania (441 millones USD en exportaciones), lo que justifica la necesidad técnica de aplicar transformaciones logarítmicas y estandarización Z antes de ejecutar DBSCAN.
El comercio internacional tiene sesgo a la derecha, por lo que se trabaja en logaritmos. Además, las importaciones y exportaciones, tomadas por separado, están fuertemente correlacionadas (\(r = 0.91\) en logaritmos): a más comercio, ambos flujos suben juntos, lo que concentraría los datos a lo largo de una sola diagonal y dificultaría distinguir perfiles distintos entre los socios. Para evitarlo, se construyen dos variables menos correlacionadas entre sí (\(r = -0.36\)):
log_total: tamaño total del comercio (\(\ln(\text{imp}+\text{exp}+1)\)), captura
qué tan grande es el vínculo comercial.log_ratio: orientación de la balanza (\(\ln(\text{exp}+1)-\ln(\text{imp}+1)\)),
captura si Alemania exporta más (positivo) o importa más (negativo)
respecto a ese socio. Es positivo cuando las exportaciones superan a las
importaciones y cero cuando son iguales.Ambas se estandarizan (\(Z\)) para tener media 0 y desviación 1, asegurando comparabilidad y evitando que la distancia euclídea se distorsione por escala. Tras estandarizar, el valor 0 pasa a ser el promedio de todos los socios, y el equilibrio entre exportaciones e importaciones queda en otro valor de \(Z\) (cerca de \(-0.45\)).
# Tamaño total del comercio (suma de flujos, en logaritmo)
datos$log_total <- log(datos$valor_importado + datos$valor_exportado + 1)
# Orientación/balanza relativa (diferencia de logaritmos)
datos$log_ratio <- log(datos$valor_exportado + 1) - log(datos$valor_importado + 1)
# Estandarización Z (Media = 0, Desviación Estándar = 1)
datos_escalados <- as.data.frame(scale(datos[, c("log_total", "log_ratio")]))
rownames(datos_escalados) <- datos$partner_iso
# Muestra de datos transformados
head(datos_escalados, 5) %>%
kable(
digits = 3,
col.names = c("Tamaño Comercio (Z)", "Balanza Relativa (Z)"),
caption = "Muestra de datos estandarizados en escala Z (primeras 5 observaciones)"
)
| Tamaño Comercio (Z) | Balanza Relativa (Z) | |
|---|---|---|
| ABW | -1.032 | 2.199 |
| AFG | -0.460 | 0.096 |
| AGO | 0.090 | 0.074 |
| AIA | -2.108 | -1.730 |
| ALB | 0.221 | -0.137 |
Esta tabla muestra las primeras 5 observaciones estandarizadas en escala \(Z\). Albania (0.221) tiene el mayor tamaño de comercio de la muestra y Anguila (-2.108) el menor, muy por debajo del promedio. En la balanza relativa, el equilibrio entre exportaciones e importaciones se ubica cerca de \(Z\approx-0.45\). Aruba (2.199) tiene la orientación exportadora más marcada. Afganistán (0.096), Angola (0.074) y Albania (-0.137) también quedan por encima del equilibrio, con una orientación exportadora moderada. Anguila (-1.730) es el único por debajo, con orientación importadora.
DBSCAN requiere fijar dos parámetros: el umbral \(\mathrm{minPts}\), que se define con una regla de referencia según el número de variables, y el radio \(\varepsilon\), que se calibra con los datos mediante el gráfico \(k\)-NN y una prueba de sensibilidad.
Selección de \(\mathrm{minPts}=6\). La regla de
referencia establece \(\mathrm{minPts}\ge
2\times m\) (Sander et al., 1998), donde \(2\) es una constante de la regla y \(m=2\) es el número de variables
(log_total y log_ratio), lo que da un mínimo
de \(4\). Se fija en \(6\) para exigir una densidad algo más
estricta. Como el conteo incluye al propio punto (Definición 2), un
socio es núcleo si tiene al menos \(5\)
vecinos distintos de él dentro del radio \(\varepsilon\).
Determinación del radio \(\varepsilon\). El radio se lee en el gráfico de distancias al \(k\)-ésimo vecino más cercano, con \(k=\mathrm{minPts}-1=5\): para cada socio se calcula la distancia a su 5º vecino (sin contarse a sí mismo) y se ordenan de menor a mayor. Como \(N_\varepsilon(p)\) incluye al propio \(p\), ser núcleo (\(|N_\varepsilon(p)|\ge\mathrm{minPts}\)) equivale a que esa distancia sea \(\le\varepsilon\). Por eso se usa \(k=5\) y no \(k=6\).
Para qué sirve la función
kNNdistplot(). Del paquete dbscan,
calcula la distancia de cada punto a su \(k\)-ésimo vecino más cercano y las ordena
de menor a mayor. Sirve para elegir \(\varepsilon\), el parámetro más difícil de
fijar: los puntos en zonas densas tienen distancias pequeñas y los
aislados, distancias grandes, por lo que la curva muestra dónde cambia
la densidad (Ester et al., 1996). Es una guía visual y no da un valor
exacto, por eso se complementa con la prueba de sensibilidad.
minPts <- 6
# Curva k-NN: distancia de cada socio a su 5º vecino más cercano
kNNdistplot(datos_escalados, k = minPts- 1)
# Radio elegido y línea de referencia
epsilon <- 0.25
abline(h = epsilon, col = "red", lty = 2)
title(paste("Gráfico de k-vecinos - Epsilon elegido =", epsilon))
Interpretación del gráfico \(k\)-NN
log_total y
log_ratio).Por qué se elige \(\varepsilon=0.25\).
valores_eps <- c(0.20, 0.25, 0.30, 0.35, 0.50)
sensibilidad <- do.call(rbind, lapply(valores_eps, function(e) {
r <- dbscan(datos_escalados, eps = e, minPts = minPts)
data.frame(
eps = e,
clusteres = max(r$cluster),
ruido = sum(r$cluster == 0),
pct_ruido = round(100 * sum(r$cluster == 0) / nrow(datos_escalados), 1)
)
}))
sensibilidad %>%
kable(
col.names = c("Epsilon", "Clústeres", "Socios en ruido", "% de ruido"),
caption = "Tabla: Sensibilidad del resultado al valor de epsilon (minPts = 6)"
)
| Epsilon | Clústeres | Socios en ruido | % de ruido |
|---|---|---|---|
| 0.20 | 5 | 103 | 46.4 |
| 0.25 | 3 | 76 | 34.2 |
| 0.30 | 1 | 54 | 24.3 |
| 0.35 | 2 | 44 | 19.8 |
| 0.50 | 1 | 20 | 9.0 |
Con los parámetros calibrados (\(\epsilon = 0.25\), \(minPts = 6\)), la función dbscan() procesa la matriz estandarizada de las dos variables construidas:
options(scipen = 999)
resultado <- dbscan(datos_escalados, eps = epsilon, minPts = minPts)
# Asignación de grupo
datos$grupo <- ifelse(resultado$cluster == 0, "Ruido", paste("Grupo", resultado$cluster))
datos$grupo <- factor(datos$grupo)
# Tabla: resultados individuales por socio
datos %>%
select(partner_iso, partner_desc, valor_importado, valor_exportado, grupo) %>%
arrange(grupo, partner_iso) %>%
head(10) %>%
kable(
format.args = list(big.mark = ","),
col.names = c("ISO", "Socio", "Importación (USD)", "Exportación (USD)", "Clasificación"),
caption = "Tabla 2: Clasificación individual por socio comercial (Primeros 10)"
)
| ISO | Socio | Importación (USD) | Exportación (USD) | Clasificación |
|---|---|---|---|---|
| AFG | Afghanistan | 14,968,497 | 42,186,122 | Grupo 1 |
| AGO | Angola | 114,690,342 | 309,985,499 | Grupo 1 |
| ALB | Albania | 243,484,326 | 441,024,933 | Grupo 1 |
| ARE | United Arab Emirates | 5,948,839,531 | 9,478,092,589 | Grupo 1 |
| ARG | Argentina | 986,824,117 | 2,792,623,225 | Grupo 1 |
| ARM | Armenia | 195,008,959 | 545,847,526 | Grupo 1 |
| AUS | Australia | 5,234,505,819 | 12,753,035,076 | Grupo 1 |
| AUT | Austria | 55,403,797,817 | 84,074,561,451 | Grupo 1 |
| AZE | Azerbaijan | 854,184,668 | 642,127,416 | Grupo 1 |
| BEL | Belgium | 54,301,491,826 | 65,772,959,947 | Grupo 1 |
La tabla muestra la clasificación individual de 10 socios. Como está ordenada por grupo y luego por código ISO, todos pertenecen al Grupo 1, por lo que no permite ver los demás grupos ni el ruido. Los socios de la muestra tienen tamaños de comercio muy distintos: desde Afganistán, con 15 millones de USD en importaciones, hasta Austria, con 55,403.8 millones, y Bélgica, con 54,301.5 millones. Que socios tan distintos compartan grupo se debe a que DBSCAN agrupa por conectividad de densidad y no por cercanía directa: dos socios pueden estar en el mismo clúster sin parecerse entre sí, si están unidos por una cadena de socios intermedios.
# Tabla: resumen y perfil de cada cluster
datos %>%
group_by(grupo) %>%
summarise(
"N Socios" = n(),
"Muestra de Paises" = paste(head(partner_iso, 5), collapse = ", "),
"Importacion Promedio (USD)" = round(mean(valor_importado), 0),
"Exportacion Promedio (USD)" = round(mean(valor_exportado), 0)
) %>%
kable(
format.args = list(big.mark = ","),
caption = "Tabla 3: Perfil general y caracteristicas de cada grupo detectado"
)
| grupo | N Socios | Muestra de Paises | Importacion Promedio (USD) | Exportacion Promedio (USD) |
|---|---|---|---|---|
| Grupo 1 | 119 | AFG, AGO, ALB, ARE, ARG | 9,931,036,155 | 12,976,603,418 |
| Grupo 2 | 19 | AND, BEN, BHS, BRN, BWA | 6,372,503 | 77,869,572 |
| Grupo 3 | 8 | BHR, BLR, CYP, GEO, IRN | 179,151,319 | 1,101,251,169 |
| Ruido | 76 | ABW, AIA, ASM, ATA, ATF | 3,305,578,922 | 1,784,507,965 |
# Prepara el dataframe para la gráfica final
datos_grafico <- as.data.frame(datos_escalados)
datos_grafico$grupo <- datos$grupo
La tabla resume el resultado de DBSCAN con \(\varepsilon=0.25\) y \(\mathrm{minPts}=6\): tres grupos y el ruido. El Grupo 1 es el más numeroso (119 socios, 53.6%) y el de mayor escala comercial. El Grupo 2 (19 socios) es el de menor escala y el de orientación exportadora más marcada: las exportaciones son más de 12 veces las importaciones. El Grupo 3 (8 socios) tiene una escala intermedia y también una fuerte orientación exportadora, aunque menor (unas 6 veces). El ruido reúne 76 socios (34.2%) sin un perfil común, por lo que su promedio no describe un grupo, sino relaciones atípicas.
La etapa final consolida los resultados en un mapa de dispersión bidimensional utilizando ggplot2. El gráfico representa la posición de cada socio comercial según su tamaño de comercio total y su balanza relativa, ambos estandarizados, identificando los clústeres densos y los puntos aislados.
# Valor Z que corresponde a exportaciones = importaciones (log_ratio = 0)
equilibrio <- (0 - mean(datos$log_ratio)) / sd(datos$log_ratio)
ggplot(datos_grafico, aes(x = log_total, y = log_ratio, color = grupo)) +
geom_point(alpha = 0.8, size = 2.8) +
geom_hline(yintercept = equilibrio, linetype = "dashed", color = "gray50") +
labs(
title = "DBSCAN - Socios Comerciales de Alemania (2023)",
subtitle = paste("Parámetros: eps =", round(epsilon, 3), "| minPts =", minPts,
"| Línea punteada: exportaciones = importaciones"),
x = "Tamaño del Comercio (Estandarizado Z)",
y = "Balanza Relativa Exp-Imp (Estandarizada Z)",
color = "Clasificación"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14),
panel.grid.minor = element_blank(),
legend.position = "right"
)
El eje horizontal representa el tamaño del comercio y el vertical la balanza relativa Exp-Imp (arriba, Alemania exporta más de lo que importa; abajo, importa más); la línea punteada marca el equilibrio entre exportaciones e importaciones.
El gráfico muestra que DBSCAN detecta grupos de forma y densidad distintas sin fijar su número de antemano, y aísla los casos atípicos sin contaminar los grupos densos.
El análisis con DBSCAN muestra que el comercio exterior de Alemania en 2023 se organiza en tres perfiles de socios y un conjunto de casos atípicos. Más de la mitad de los socios (119, 53.6%) forma un grupo de gran escala comercial, donde Alemania exporta en promedio alrededor de 1.3 veces lo que importa: es una relación comercial amplia y relativamente equilibrada, con superávit alemán moderado. Dos grupos pequeños (19 y 8 socios) son economías de menor escala frente a las que Alemania mantiene una posición exportadora mucho más marcada (unas 12 y 6 veces, respectivamente), es decir, son mercados que compran productos alemanes pero venden poco a Alemania. Finalmente, 76 socios (34.2%) no forman un patrón denso: sus relaciones son atípicas por escala o por balanza, y en promedio Alemania les importa más de lo que les exporta. En conjunto, los resultados sugieren que el superávit comercial alemán no es homogéneo: se concentra en unos perfiles de socios y se compensa parcialmente con relaciones deficitarias atípicas.
DBSCAN es un algoritmo de agrupamiento basado en densidad: forma clústeres uniendo puntos conectados por densidad, no requiere fijar el número de grupos de antemano y clasifica como ruido a los puntos que no alcanzan la densidad mínima. Su funcionamiento depende de dos parámetros, \(\mathrm{minPts}\) y \(\varepsilon\), y por eso su calibración es la etapa más delicada: en este ejercicio, \(\mathrm{minPts}=6\) se definió con una regla de referencia y \(\varepsilon=0.25\) se calibró con el gráfico \(k\)-NN y una prueba de sensibilidad, que mostró que el resultado cambia con el radio. Esa sensibilidad, junto con la necesidad de estandarizar las variables, es la principal limitación práctica del método.
Aplicado al comercio exterior de Alemania en 2023, con datos de UN Comtrade para 222 socios y dos variables (tamaño del comercio y balanza relativa), DBSCAN identificó tres grupos y un conjunto de casos atípicos. El Grupo 1 (119 socios, 53.6%) reúne relaciones de gran escala con un superávit alemán moderado; los Grupos 2 y 3 (19 y 8 socios) son socios de menor escala frente a los que Alemania mantiene una posición exportadora mucho más marcada; y el ruido (76 socios, 34.2%) agrupa relaciones atípicas por escala o por balanza. En conjunto, el superávit comercial alemán no es homogéneo entre sus socios. El análisis es descriptivo: se limita al valor total de importaciones y exportaciones de un solo año, por lo que no explica las causas de cada grupo, algo que requeriría datos por producto o variables adicionales.
Altaei, R. (2024, 19 de octubre). Understand the math behind DBSCAN. Medium. https://raghda-altaei.medium.com/understand-the-math-behind-dbscan-ae51672c0424
Chen, Y., Ruys, W., & Biros, G. (2020). KNN-DBSCAN: A DBSCAN in high dimensions. arXiv Preprint arXiv:2009.04552.
Data Analytics Living Textbook. (s.f.). Chapter 6 Cluster Analysis, part 1. Bookdown. https://bookdown.org/brittany_davidson1993/bookdown-demo/cluster-analysis-part-1.html
Datanovia. (2026). K-medoids (PAM) in R: Algorithm and practical examples. https://www.datanovia.com/learn/machine-learning/clustering/k-medoids-pam
DataScienceBase. (s.f.-a). Agglomerative hierarchical clustering: Comparison with other algorithms. https://www.datasciencebase.com/unsupervised-ml/algorithms/agglomerative-hierarchical-clustering/comparison/
DataScienceBase. (s.f.-b). DBSCAN: Comparison with other algorithms. https://www.datasciencebase.com/unsupervised-ml/algorithms/dbscan/comparison/
Ester, M., Kriegel, H.-P., Sander, J., & Xu, X. (1996). A density-based algorithm for discovering clusters in large spatial databases with noise. En E. Simoudis, J. Han, & U. M. Fayyad (Eds.), Proceedings of the Second International Conference on Knowledge Discovery and Data Mining (KDD-96) (pp. 226-231). AAAI Press.
GeeksforGeeks. (2023, 11 de enero). K-medoids clustering in machine learning. https://www.geeksforgeeks.org/machine-learning/k-medoids-clustering-in-machine-learning/
GeeksforGeeks. (2026, 2 de mayo). K-Nearest Neighbor (KNN) algorithm. https://www.geeksforgeeks.org/machine-learning/k-nearest-neighbours/
Hahsler, M., Piekenbrock, M., & Doran, D. (2019). dbscan: Fast density-based clustering with R. Journal of Statistical Software, 91(1), 1-30. https://doi.org/10.18637/jss.v091.i01
Kavlakoglu, E. (2021, 4 de octubre). ¿Qué es el algoritmo de k vecinos más cercanos? IBM. https://www.ibm.com/mx-es/think/topics/knn
Kumar, R. (2026). Guía sobre el algoritmo de agrupamiento DBSCAN. DataCamp. https://www.datacamp.com/es/tutorial/dbscan-clustering-algorithm
Largo L., M. F. (2025). Una introducción a los modelos de clústering empleando R [Libro en línea]. Editorial Universidad Icesi. https://www.icesi.edu.co/editorial/intro-clustering-web/
Moya, R. (2016, 12 de septiembre). Selección del número óptimo de Clusters. Jarroba. https://jarroba.com/seleccion-del-numero-optimo-clusters/
r-statistics.co. (2026). Cluster analysis in R. https://r-statistics.co/Cluster-Analysis-in-R.html
Sander, J., Ester, M., Kriegel, H.-P., & Xu, X. (1998). Density-based clustering in spatial databases: The algorithm GDBSCAN and its applications. Data Mining and Knowledge Discovery, 2(2), 169-194.
Schubert, E., Sander, J., Ester, M., Kriegel, H.-P., & Xu, X. (2017). DBSCAN revisited, revisited: Why and how you should (still) use DBSCAN. ACM Transactions on Database Systems, 42(3), 1-21. https://doi.org/10.1145/3068335
Thamrin, M., Mulyadi, I., Made Widia, I. D., Faisal, M., Hi Baharuddin, S., Wisnu Prihatmono, M., Nurdiansyah, N., & Usman, N. (2025). Machine learning for global trade analysis: A hybrid clustering approach using DBSCAN, elbow, and SOM. IAES International Journal of Artificial Intelligence (IJ-AI), 14(4), 3033-3046. https://doi.org/10.11591/ijai.v14.i4.pp3033-3046
United Nations. (2023). UN Comtrade Database. https://comtradeplus.un.org
r-statistics.co. (2026). Cluster analysis in R. https://r-statistics.co/Cluster-Analysis-in-R.html