¿Podemos utilizar herramientas de machine learning en mapas web de forma sencilla? Sí, y lo comprobaremos a continuación empleando dos herramientas libres ampliamente utilizadas como son: Leaflet y TensorFlow.

Crear modelos
Machine Learning o Aprendizaje Automático es una parte de la inteligencia artificial que podemos explicar de forma muy esquemática diciendo que, es el proceso por el cual entrenamos un modelo a partir de unos datos. Se trata de entrenar un modelo que «aprenda» a partir de unos datos conocidos. El objetivo es que una vez entrenado el modelo podamos proporcionarle datos nuevos (es decir, que no han sido utilizados en el entrenamiento) para que nos haga una predicción.

En las aplicaciones SIG, la solución más evidente sería entrenar un modelo para obtener un mapa y luego proceder a su publicación web. Pero el entrenamiento y la visualización podemos hacerla en el propio navegador, empleando algunas herramientas de aprendizaje automático como TensorFlow.js.
TensorFlow
TensorFlow es una biblioteca de código abierto para machine learning desarrollada por Google.
Por su parte, TensorFlow.js es una biblioteca para el aprendizaje automático escrita en el lenguaje de programación JavaScript. Desarrolla modelos de aprendizaje automático en JavaScript y permite utilizar directamente el aprendizaje automático en el navegador o en Node.js. En nuestro caso particular, una aplicación webmapping, es la herramienta que emplearemos para crear y entrenar los modelos en el mapa.
TensorFlow.js trabaja de tres forma distintas:
1.- Ejecutando modelos existentes.
Se trata de utilizar modelos de TensorFlow que ya están listos, en el navegador o con Node.js. Estos modelos abarcan varios campos de la inteligencia artificial como:
- Visión. Analiza características en imágenes y vídeos. Realiza tareas de clasificación de imágenes, detección de objetos y segmentación semántica.
- Detección de rostros o segmentación del cuerpo.
- Texto. Uso del lenguaje natural para responder preguntas.
- Audio. Clasifica audio para detectar sonidos.
2.- Volviendo a entrenar modelos existentes.
Se pueden entrenar los modelos preexistentes de aprendizaje automático con datos propios.
3.-Desarrollando Aprendizaje Automático con JavaScript.
Podemos crear y entrena modelos directamente en JavaScript con una API flexible e intuitiva.
Para verlo mejor desarrollaremos un ejemplo: vamos a entrenar un modelo a partir de un muestreo de concentración de NO₂ en la atmósfera. Construiremos un mapa de tal forma que, al hacer clic sobre un punto, nos indique la concentración de NO₂ a partir de la predicción del modelo.
Creación de un mapa web con Leaflet
Empezaremos construyendo un mapa web. A partir de un dataset de concentraciones de NO₂, creamos un mapa de calor utilizando Leaflet. Utilizamos un heatmap para representar los valores en el mapa, porque nos parece una forma que se adapta a las características de nuestros datos, pero esto no interviene en la creación del modelo de aprendizaje automático.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Predicción de NO₂ con TensorFlow.js + Leaflet</title>
<!-- Leaflet -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://cdn.jsdelivr.net/npm/leaflet.heat@0.2.0/dist/leaflet-heat.min.js"></script>
<!-- Datos -->
<script src="ValoresNO2.js"></script>
<style>
html, body { height: 100%; margin: 0; }
#map { height: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
// Crear el mapa
const map = L.map('map').setView([40.4, -3.7], 6); // Vista inicial España
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
// Crear un mapa de calor para visualizar los datos
var heat = L.heatLayer(puntos,{blur:25,maxZoom:8,radius:15,gradient:{0.4: 'blue',0.6: 'yellow',1: 'red'}}).addTo(map);
</script>
</body>
</html>
La vista que obtenemos es la siguiente:

Crear y entrenar un modelo
Comenzamos ahora el trabajo con TensorFlow.js.
Iremos añadiendo el código que vayamos escribiendo al que ya tenemos con el mapa. Lo primero que tenemos que hacer es incorporar TensorFlow.js a nuestro mapa.
Para eso añadimos en la cabecera del código lo siguiente:
<!-- TensorFlow.js --> <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@4.18.0/dist/tf.min.js"></script>
Empleamos unos datos con los valores de concentración de NO₂, que como se puede observar, los hemos añadido desde un archivo llamado ValoresNO2.js.
La estructura de los datos es: [latitud, longitud, concentración_NO2]
Por ejemplo: [42.518333,-2.619444,8.300000] vemos que se componen de las coordenadas geográficas del punto y el valor de la concentración de NO₂ en ese punto.
Necesitamos convertir estos datos antes de poder utilizarlos. Lo que haremos será separarlos en entradas y salidas. Los valores de entrada (X), es lo que en AA se conoce como características. En este ejemplo son las coordenadas del punto. Los datos de salida (y) se conocen como etiquetas y aquí es el valor de la concentración de NO₂. Lo podemos explicar de otra forma;
X → lo que el modelo recibe (latitud + longitud)
y → lo que el modelo aprende a predecir (NO₂)
// Convertir los datos const xs = tf.tensor2d(puntos.map(p => [p[0], p[1]])); // lat, lon const ys = tf.tensor2d(puntos.map(p => [p[2]])); // concentración
El siguiente paso es crear y entrenar el modelo:
const model = tf.sequential();
model.add(tf.layers.dense({ units: 8, inputShape: [2], activation: 'relu' }));
model.add(tf.layers.dense({ units: 4, activation: 'relu' }));
model.add(tf.layers.dense({ units: 1 })); // salida: concentración NO2
model.compile({ optimizer: 'adam', loss: 'meanSquaredError' });
Creamos con TensorFlow un modelo secuencial que es aquel en donde las capas se organizan una detrás de otra, o lo que es lo mismo, tienen un flujo lineal y directo (no hay bifurcaciones, saltos…)
📥 Entrada → Capa 1 → Capa 2 → 📤 Salida
- dense es un tipo de capa completamente conectada, indica que cada cada capa se conecta con todas las neuronas de la capa anterior.
- units es el número de neuronas de cada capa.
- inputShape: [2], indica que cada instancia de entrada tiene dos valores, que en nuestro ejemplos son Latitud y longitud.
- activation; hace referencia a la función de activación de la capa. Es la forma en que se le dice a cada neurona que tiene que actuar.
La última línea de este script hace referencia a la compilación del modelo.
- optimizer: ‘adam’ Ajusta los pesos utilizando el algoritmo Adam.
- loss: ‘meanSquaredError’ utiliza el error cuadrático medio. El objetivo es reducir la pérdida. La pérdida es una métrica numérica que describe qué tan incorrectas son las predicciones de un modelo.
A continuación definimos una función para el entrenamiento:
async function entrenarModelo() {
const history = await model.fit(xs, ys, {
epochs: 300,
shuffle: true,
verbose: 1
});
}
entrenarModelo();
El entrenamiento se produce en model.fit() y se emplean 300 épocas, es decir que se recorren los datos 300 veces durante el entrenamiento.
Crear la interacción con el mapa
Recapitulando lo que hemos hecho hasta ahora, vemos que en un primer momento creamos un mapa de Leaflet y luego hemos entrenado un modelo de aprendizaje automático. Ahora lo que nos queda es crear una interacción para que cuando hagamos clic sobre un punto del mapa nos devuelva la concentración de NO2, en función del modelo que hemos creado y entrenado:
map.on('click', async (e) => {
const { lat, lng } = e.latlng;
const input = tf.tensor2d([[lat, lng]]);
const pred = model.predict(input);
const value = (await pred.data())[0];
const color = value < 10 ? 'green' : value < 20 ? 'orange' : 'red';
L.circleMarker([lat, lng], {
radius: 10,
color, fillColor: color, fillOpacity: 0.7
}).addTo(map)
.bindPopup(`📍 Lat: ${lat.toFixed(3)}, Lon: ${lng.toFixed(3)}<br>🔮 Predicción NO₂: <b>${value.toFixed(2)} µg/m³</b>`)
.openPopup();
});
El resultado es el siguiente:

Discusión y conclusiones
Hemos visto que utilizar TensorFlow en un mapa web de Leaflet es sencillo y fácil de implementar, no hemos necesitado hacer ninguna instalación y nos ha permitido hacer las consultas de forma interactiva. Cierto es que presenta limitaciones, pues para modelos complejos con un gran volumen de datos de entrenamiento no es práctico hacerlo de esta forma.
En el ejemplo concreto que hemos visto podíamos haber utilizado técnicas de interpolación para resolver el problema sin necesidad de recurrir a las redes neuronales, lo cual hubiese sido más sencillo. Para mejorar el modelo se pueden añadir variables ambientales reales (meteorológicas o satelitales), en ese caso las redes neuronales y concretamente TensorFlow serían una buena opción para construir el modelo.
Tutor del curso online de Análisis GeoEspacial con Python y de los cursos online de webmapping. Echa un vistazo a todos nuestros cursos de SIG online.