Geo Big Data con Datos Censales

Introducción

En este artículo mostrare un ejemplo de análisis geográfico de todas las manzanas de México, mediante un grid hexagonal a nivel nacional. Usaremos los datos del Censo 2010 del proyecto SCINCE del INEGI (Oficina Nacional de Estadística y Geografía de México). y por supuesto vamos preparando la artillería para analizar los datos del próximo censo 2020 que será publicada la próxima semana: https://censo2020.mx/censo/.

Tradicionalmente este análisis se realizaría usando una herramienta de análisis geográfico como lo puede ser QGis o alguna otra herramienta comercial. Una estrategia mas sofisticada usaría una base de datos con extensiones geográficas como PostgreSQL + PostGIS (https://postgis.net/).

Sin embargo las soluciones anteriores están fuertemente limitadas en el aspecto de escalabilidad horizontal. Pues es complejo extenderlas a un clúster distribuido.

Desde hace algunos años existe una tecnología que ofrece capacidades de procesamiento paralelo y distribuido, llamada Apache Spark (https://spark.apache.org/), que ha tardado en incorporar las capacidades geográficas a su ecosistema. Poco a poco esto ha ido cambiando y es el tema de este tutorial. Apache Spark en su conjunto ha ido madurando incorporando a Python y R como lenguajes de trabajo pues originalmente solamente funcionaba con Scala/Java. Incluso hoy día Spark es un motor optimizado paralelo y distribuido de SQL estándar. Lo cual abre las posibilidades para el procesamiento de datos por un público extenso, pues SQL es un lenguaje estructurad y relativamente sencillo para la explotación de datos. Y en combinación con Apache Spark, SQL se convierte en un lenguaje de procesamiento paralelo y distribuido! (https://spark.apache.org/sql/).

En combinación con Apache Sedona antes GeoSpark (https://sedona.apache.org/) y gracias a la actualización liberada hace algunos meses, ahora podemos usar funciones geográficas en Apache Spark mediante el lenguaje Python aprovechando librerías como Geopandas como medio de acceso a los formatos geográficos tradicionales por ejemplo Shapefiles. Y por si fuera poco podemos usar SQL con extensiones Geográficas en el entorno de Apache Spark.

Ahora bien, instalar y configurar los entornos de Big Data puede ser retador, por lo que en este tutorial usamos la tecnología de contenedores llamada docker (https://www.docker.com/). Docker facilita el uso de ambientes complejos gracias a que ya existen muchos servidores y tecnologías empaquetadas en imágenes de docker (https://hub.docker.com/) que solamente basta con invocar en la terminal de Power Shell de Windows. Permitiendo a los programadores y científicos de datos iniciar rápidamente el desarrollo de algoritmos en plataformas listas para usarse!

Pasos a Seguir

Los pasos que llevaremos a cabo serán los siguientes:

  • Preparar el entorno con Docker
  • Descargar todos los datos del proyecto, todas las manzanas de México.
  • Activar y Configurar la plataforma de análisis basada en Jupyter y Apache Spark.
  • Convertir los datos a formato parquet incluyendo la variable geográfica.
  • Calcular el centroide de cada manzana sin perder sus atributos estadísticos.
  • Obtener grid hexagonal para resumir los datos.
  • Realizar una agregación de datos censales usando los hexágonos mediante SQL.
  • Generar una visualización usando QGis.

1.- Preparar el entorno con Docker

La magia de Docker nos ayudará a simplificar varias tareas de configuración y uso de software. El precio que hay que pagar es proceder a instalarlo y verificar que funcione.

Si ya cuentas con una versión de Docker instalada y corriendo puedes pasar al paso 2 :)

Tal vez la barrera mas grande para usar Docker en Windows, es el cumplir con los requisitos básicos:

  • Windows 10 Profesional o Enterprise de 64 bits Versión 1607 o superior y Versión del Sistema Operativo en Ingles le llaman build 14393 o posterior, en la siguiente animación puedes observar cómo revisar ese dato.
Verificar verión de Windows 10
Verificar verión de Windows 10
Verificación de Windows
  • 4 Gb Ram o Superior
  • 4 Cores o Superior
  • Y la opción de vitualización activada:
Virtualización Activada

Instalación de Docker

Para descargar el instalador hay que entrar a la siguiente liga: https://hub.docker.com/editions/community/docker-ce-desktop-windows . Ya estando en esa página procede a descargar el instalador como se muestra en la siguiente imagen:

Obtener Docker

El proceso de instalación es sencillo, deja todas las opciones por defecto, si el instalador requiere ajustar alguna configuración te lo comunicará, como por ejemplo activar las características de Contenedores y Virtualización (Hyper-V), basta con aceptar las recomendación y permitir que se reinicie el equipo.

Como ya mencionamos arriba, otro aspecto importante es que en este tutorial estaremos usando contenedores de Linux, por lo que cuando el instalador pregunte respecto a usar contenedores de Windows deberemos ignorar su sugerencia y dejar el checkbox SIN seleccionar para que sigamos con los parámetros por defecto es decir podamos usar contenedores Linux:

Ignorar ésta recomendación y seguir adelante presionando [OK]

Después de reiniciar el equipo aparecerá una ballenita en tu barra de tareas:

Por último para verificar que docker está corriendo en nuestro equipo podemos ejecutar la siguiente instrucción en la terminal Power Shell:

docker version

Tendremos una salida similar a la siguiente:

Varificación de que nuestro Docker está corriendo correctamente

Si llegaste hasta aquí felicidades!!!! Haz terminado la parte mas difícil de este tutorial.

2.- Descargar todos los datos de las manzanas de México.

En esta sección empezaremos a beneficiarnos de haber instalado Docker, pues usaremos un script de Linux para descargar todos los archivos censales publicados por el INEGI.

Vamos a usar los datos geo-referenciados del Sistema de Consulta de Información Censal (SCINCE) 2010. Para simplificar la tarea generé la script para descargar los archivos que contienen toda la información censal a nivel manzana:

descarga_scince_linux.sh
Lista de archivos con la información censal a nivel manzana.
Descarga Archivo: http://bit.ly/2wdULXx

Como pueden observar es un sencillo script de bash que descarga los archivos de cada estado de México.

Antes de iniciar la descarga es necesario guardar el script de esta liga http://bit.ly/2wdULXx en alguna ruta de tu computadora, para ser consistentes usaremos C:\geobigdata, quedaría asi:

El siguiente paso es usar alguna imagen de Docker que pueda ejecutar el script que descargaste. Eso se logra ejecutando la siguiente linea de código en tu terminal Power Shell, la cual va a funcionar debido a que tienes Docker en tu equipo.

docker run --rm -it -v C:/geobigdata:/home jgoclawski/wget

El parámetro mas interesante de la instrucción anterior es:

-v C:/geobigdata:/home

Lo que le indica a Docker que en nuestro equipo tenemos una carpeta que queremos compartir en el Mini-Linux que vamos a arrancar, por lo que los archivos que estén ahí se “verán” en ese ambiente. Y mejor aun, los archivos que descarguemos con ese Linux, quedarán cuando el contenedor desaparezca y podremos usarlos independientemente del Linux que usamos para descargarlos :D

Retomando, la instrucción “docker run …” iniciará en modo interactivo el contenedor de docker que estará usando la imagen docker-wget (https://github.com/jgoclawski/docker-wget) que contiene una distribución mínima de Linux llamada Alpine que incluye la utilería instalada wget. Los lectores observadores habrán notado que es la instrucción con la que inicia cada línea de la lista de archivos del script. Esa instrucción le indica al sistema operativo que descargue el archivo que se está en la URL que le sigue:

wget https://www.inegi.org.mx/contenidos/masiva/indicadores/inv/01_SCINCE_zip.zip

Al iniciar el contenedor interactivo podemos ver un cursor con el carácter #, es ahí donde podemos escribir comandos de Linux, por ejemplo movernos a la ruta /home y listar los archivos que se encuentren ahí, con el comando ls -alht. Por favor realiza esos comandos como se muestra en la siguiente imagen.

Contenedor interactivo, con el directorio local mapeado en /home

Podemos ver que el contenido de nuestro directorio C:/geobigdata se encuentra mapeado al interior del contenedor Linux en la ruta /home, lo cual es justo lo que le indicamos a docker cuando iniciamos el mini-Linux Alpine. Felicidades ! El Cielo es el límite!

Ahora podemos ejecutar el archivo para que descargue los archivos del INEGI. Esto se logra al escribir el siguiente comando de consola.

# sh descarga_scince_linux.sh

El comando ejecuta secuencialmente cada línea del script, lo cual descarga uno por uno los archivos listados. El resultado se puede ver gráficamente en la siguiente imagen:

Descargando los Datos Abiertos del Censo 2010 de México

Una vez concluido el proceso (entre 30 minutos y una hora, depende de tu conexión a internet) podemos ir desde el explorador de Windows a nuestro directorio dónde encontraremos todos los archivos que acabamos de descargar.

Los 32 archivos con toda la información del Censo 2010

Ahora puedes salir del mini Linux con el comando: exit eso fue todo para el mini-Linux de la imagen docker-wget, este proceso también ha servido para conocer un ejemplo básico de docker. Sigamos adelante con el proceso principal.

Exploremos los archivos descargados

La manera mas fácil de extraer todos los archivos es con la herramienta de Software Libre 7zip (https://www.7-zip.org/). Selecciona los archivos *.zip y ejecuta el comando Extraer aquí:

Carpetas con la información Censal

Lo cual descomprimirá todos los archivos dejando un folder para cada archivo ZIP. Ahora tenemos 32 carpetas una para cada estado de México.

Al interior de cada carpeta encontraremos múltiples archivos, para una descripción completa te sugiero que explores los metadatos que se publican en el PDF siguiente: http://bit.ly/2x3SI8w. En nuestro caso usaremos solamente un pequeño conjunto de ellos, estará en tus manos sacarle el máximo provecho al resto de la información. Vamos a usar el llamado manzanas.shp, este archivo en realidad es parte de un grupo de archivos con extensiones DBF, PRJ y SHX. Los cuales en su conjunto se refieren a una capa de información geográfica en formato vectorial, mas específicamente las manzanas de cada estado de la República Mexicana y su información estadística. Usando el software libre QGIS (https://qgis.org/), podemos abrir ese archivo con extension .shp, correspondiente a el estado de Aguascalientes en el archivo: C:\geobigdata\01\manzanas.shp

Algunas Manzanas del Estado de Aguascalientes México

Al seleccionar una manzana podemos ver del lado derecho sus atributos estadísticos. Para interpretar el significado de cada atributo necesitaremos abrir en Excel o incluso en el mismo QGIS un segundo archivo llamado: C:\geobigdata\01\descriptores\desc_cpv2010.DBF. Como podemos observar es una descripción de los campos que vimos del lado derecho al seleccionar visualmente una manzana del estado de Aguascalientes.

Descripción de los campos estadísticos de cada Manzana geográfica.

En este tutorial usaremos el campo POB1 que registra la población total que habita en cada manzana, según el Censo de Población 2010.

3.- Activar y Configurar la plataforma de análisis basada en Jupyter y Apache Spark.

Para llevar a cabo el trabajo con todos los datos a la vez, es decir realizar análisis nacionales con todas las manzanas, usaremos otra imagen de docker, en esta ocasión la llamada jupyter/all-spark-notebook del proyecto Jupyter Docker Stacks (https://jupyter-docker-stacks.readthedocs.io/en/latest/), te recomiendo leer con detenimiento la documentación de dicho proyecto. Esa imagen simplifica al máximo el uso de Jupyter facilitando incluso el uso de Apache Spark ya que también está configurado dentro de esa imagen. Para que podamos procesar los archivos descargados será necesario ajustar los recursos asignados a la maquina de Docker. Se requieren al menos 8 Gb de Ram, lo cual se ajusta en la configuración de Docker Dashboard, ver la siguiente animación:

Después del cambio docker tardara unos 15 minutos en reiniciarse. Una vez ajustada la memoria asignada a nuestro docker, vamos a ejecutar la siguiente instrucción, observe que seguimos aprovechando la carpeta local C:\geobigdata y el parámetro -v, solo que en esta ocasión el directorio interno es /home/jovyan/work.

docker run -d -P -v C:/geobigdata:/home/jovyan/work  --name geobigdata jupyter/all-spark-notebook

A diferencia de la imagen anterior, esta es mucho mas grande aproximadamente 5 GB. Por lo que la primera vez que ejecutes este comando se va a tardar un rato, dependiendo de tu conexión a internet. Solo te puedo decir que vale la pena porque estas bajando un entorno de trabajo completo para el trabajo con Apache Spark, Python, R y Scala. El comando ejecutado nombra al contenedor cómo geobigdata y una vez descargado todo se queda ejecutando en segundo plano. Para poder conectarnos a dicho servicio debemos conocer el puerto asignado y el token de conexión de la siguiente manera, abriendo una consola de Power Shell y poniendo los siguientes comandos:

docker port geobigdata 8888
Ejemplo de la salida del comendo anterior.

La instrucción anterior pregunta por el puerto al que se encuentra mapeado el puerto :8888 del contenedor. En el caso del ejemplo es el puerto :32769. Cabe aclarar que cada vez que se reinicia el contenedor o la maquina física es necesario volver a repetir estos pasos. El segundo paso implica consultar el token de conexión con la instrucción:

docker logs --tail 10 geobigdata
URL de Conexión a Jupyter Notebook

Ahora podemos tomar el token de conexión : http://127.0.0.1:8888/?token=e24c9e2e1aacaec1a1d2b67fa659680d846ce8b14148b843

Y reemplazar el valor :8888 con el resultado de la primera consulta, en este caso :32769. Quedando:

http://127.0.0.1:32769/?token=e24c9e2e1aacaec1a1d2b67fa659680d846ce8b14148b843

Recuerda que dicha URL es única para cada usuario y contenedor, por lo que tendrás que repetir el proceso cada vez que reinicies el equipo o el contenedor. Una vez construida la URL la podemos abrir en nuestro navegador, lo cual se conectará al contenedor y mostrara un Jupyter totalmente configurado, con Python, R y Scala además de Apache Spark con esos tres sabores.

Jupyter corriendo y configurado con varios lenguajes ademas de Apache Spark

Es relevante notar que para tener todo esto corriendo solo bastó una sola línea en Power Shell, considero que con éste ejemplo podemos visualizar el valor de tener Docker instalado y corriendo en nuestro equipo.

La plataforma está prácticamente lista para usarse, sin embargo, será necesario realizar algunos ajustes para poder agregarle las librerias que nos permitirán ejecutar análisis Geográficos con Apache Spark.

Eso es debido a que las librerías tienen pocos meses de haber salido a la luz y aun no se incluyen en las distribuciones populares de Docker.

Usaremos el proyecto Apache Sedona antes GeoSpark : https://sedona.apache.org/. Este proyecto permite realizar análisis espaciales a través de operadores SQL dentro de Apache Spark y sus derivados como PySpark. Mas adelante veremos un ejemplo. Primeramente hay que incluirlo dentro de nuestro contenedor. Para lo cual es necesario descargar los archivos JAR del proyecto GeoSpark, de la siguiente URL: https://github.com/apache/incubator-sedona/releases

Quedan descargados los siguientes archivos:

En la carpeta de Descargas encontramos los archivos del proyecto GeoSpark

Ahora hay que cargarlos al contenedor que está ejecutando el servidor de Jupyter. Es importante notar que si creamos otro contenedor que usa la misma imagen deberemos repetir este proceso. Para lo cual hay que abrir una terminal de Power Shell y dirigirnos a el directorio de Descargas. Debemos ejecutar los siguientes comandos, los cuales cargan al directorio por default de Apache Spark, las nuevas librerías, lo cual permitirá que reconozca las nuevas funciones geoespaciales.

docker cp geospark-1.3.1.jar geobigdata:/usr/local/spark/jars/geospark-1.3.1.jar

docker cp geospark-sql_2.3-1.3.1.jar geobigdata:/usr/local/spark/jars/geospark-sql_2.3-1.3.1.jar

docker cp geospark-viz_2.3-1.3.1.jar geobigdata:/usr/local/spark/jars/geospark-viz_2.3-1.3.1.jar

Ahora, procederemos a instalar los paquetes de Python necesarios para que todo funcione en nuestros cuadernos.

El Jupyter que tenemos instalado nos da la posibilidad de abrir una terminal conectada a la maquina donde se encuentra corriendo, es decir desde nuestro navegador web, podemos conectarnos a la terminal del contenedor que está corriendo el servicio de Jupyter y Spark, vea la siguiente animación.

En esa terminal ejecutamos los siguientes comandos,

pip install geospark
conda install geopandas

Primer comando:

pip install geospark

Y el segundo comando:

conda install geopandas

Por fin!!!!

Tenemos todo listo, en realidad la próxima vez que lo requieras te darás cuenta que es más rápido de lo que parece. Ahora vamos a realizar el análisis prometido.

4.- Convertir los datos a formato parquet incluyendo la variable geográfica

Apache Parquet (https://parquet.apache.org/) es un formato basado en columnas listo para aplicaciones de Big Data, por lo que ahora veremos como convertir los archivos descargados del INEGI a ese formato más escalable.

Vamos a realizar el primer cuaderno de Jupyter con Python 3 y PySpark. No tenemos de qué preocuparnos pues ya tenemos todo listo e instalado en nuestro contenedor de Jupyter llamado geobigdata.

En la página a la que nos conectamos armando el Token y Cambiando el puerto podemos crear una carpeta a la que vamos a llamar “cuadernos”, dentro del directorio work. La cual se encuentra mapeada a nuestro disco duro, es decir podremos ver y llevarnos los cuadernos a otras computadoras.

Crear la carpeta llamada: cuadernos

Ahora creamos un cuaderno de Python 3, dentro de la carpeta recien creada, solamente para mantener un orden.

Ahora escribimos el siguiente código, qué toma las manzanas de cada estado en formato shapefile y las convierte en formato parquet en la proyección EPSG:4326 (https://epsg.io/4326) es decir a coordenadas geográficas siendo estas una medida mas estándar. El formato parquey nos va a permitir conseguir mayor escalabilidad en los procesos de análisis.

Código que lee los archivos shapefile descargados del INEGI y los convierte a formato parquet.

Aquí está el cuaderno de Jupyter mostrado arriba, lo puedes descargar y guardar en tu carpeta para que solamente ejecutes las celdas. Para que funcione es necesario que directamente en la carpeta C:\geobigdata se encuentren las 32 carpetas que descargamos del INEGI.

(01_Shape_2_Parquet.ipynb) : http://bit.ly/2QoH7Yt

Una vez ejecutado el código de arriba tendremos en la carpeta mza_parquets los archivos parquet de todos los estados, las dos ultimas lineas leen todos los archivos de los 32 estados de una sola vez y cuentan el número de manzanas de todo México registradas para el censo 2010. Dando como resultado 1,376,969 mazanas. Un efecto colateral de parquet es que compacta la información por la estrategia interna de almacenamiento basada en columnas. Podemos ver que el acumulado de los archivos descargados correspondientes a las manzanas nos da un total de 1.31 GB. Y en el caso de la misma acumulación de formatos parquet baja a 479 MB sin pérdida de datos.

Todos los archivos manzanas.shp, manzanas.shx, manzanas.prj, manzanas.dbf para los 32 estados suman 1.31 GB
En el caso de el formato parquet bajo a 479 MB siendo menos de la mitad del formato shapefile original.

En el caso de que el primer código presente dificultades en la generación de parquets, o simplemente no quieres ejecutarlo. Puedes descargar cada parquet de la siguiente ruta: http://bit.ly/2IRlT1s.

5.- Calcular el centroide de cada manzana sin perder sus atributos estadísticos.

Ahora que ya contamos con los archivos parquet con todas las variables estadísticas y la variable geográfica. Vamos a usar las capacidades de análisis geográfico de GeoSpark para calcular el centroide de cada manzana. Lo cual es una oportunidad para observar la integración con SQL.

Para lo cual partimos de los parquets generados en el paso anterior:

Generar un nuevo parquet con los centroides de las manzanas y todos sus atributos, el cuaderno se puede descargar de aquí: http://bit.ly/2wiG8Cl

Del código anterior es interesante la tercer celda, pues crea una tabla virtual, que puede ser usada dentro de Apache Spark, mediante un SQL enriquecido con funciones geográficas gracias a GeoSpark. La cuarta celda es un código SQL que selecciona todos los campos de la tabla manzanas y calcula el centroide del polígono de cada manzana, convirtiendo a las manzanas en puntos dispersos a lo largo de todo México. La función usada es ST_Centroid su documentación se encuentra en: https://sedona.apache.org/api/sql/GeoSparkSQL-Function/#st_centroid.

Es interesante notar que el tamaño de nuevo archivo parquet creado es de 233 MB, respecto al anterior disminuyo su tamaño debido a que todos los polígonos de manzanas se convirtieron solamente en un punto con 2 coordenadas gracias a la función ST_Centroid. Sin embargo sigue teniendo todos los atributos estadísticos.

6.- Obtener grid hexagonal para resumir los datos

Para este tutorial se desarrolle un grid de hexagonos, de aproximadamente 85 Kilometros cuadrados con un total de 23,688 hexagonos cubriendo todo México.

23,688 hexágonos cubriendo todo Mexico, lo puedes descargar de aquí http://bit.ly/2IUS9kf

Procederemos a crear el archivo parquet, a partir del shapefile de hexagonos lo cual mejorará la velocidad de procesamiento y escalabilidad de los siguientes análisis, para lo cual se requiere que el archivo descargado se extraiga en la ruta C:\geobigdata\grid.

Lo mencionado se realiza con el siguiente código:

Convertir el Grid a parquet el código aquí http://bit.ly/3b5IrYq

7.- Realizar una agregación de datos censales usando los hexágonos mediante SQL.

Ya tenemos los elementos básicos para realizar el análisis nacional de cualquier atributo poblacional, a) las manzanas representadas por su centroide y sus atributos estadísticos y b) hexágonos cubriendo toda la república lo que resta es vincular ambas geometrías mediante un JOIN geográfico, que en este caso se realizará con la función ST_Within, que dadas dos geometrías evalúa la pregunta de si la primer geometría se encuentra dentro de la segunda.

Cuaderno de Jupyter que crea un archivo Shapefile con el resultado del análisis espacial de todas las manzanas de México agregadas por Población total, se puede descargar aquí http://bit.ly/2UdsUis

La estrategia general es generar una tabla con el resumen para cada hexágono, el detalle se puede ver en la tercera celda en la que se realiza la suma del total de población (POB1) de los centroides que caen en cada hexágono.

La tabla llamada “fid_pob” tiene dos campos: 1) el identificador único de cada hexágono que intersectó con alguna manzana al que se llamó FID y 2) la suma del total de población llamado POB_TOT. Finalmente en la celda 7 se hace una unión por la izquierda, para conservar todas las geometrías de los hexagonos aunque no tengan alguna manzana. Finalmente se guarda el resultado en un shapefile que podemos usar externamente a nuestra plataforma.

8.- Generar una visualización usando QGis

El resultado del proceso anterior generó un archivo Shapefile:

Para generar la visualización final de este tutorial usaremos la herramienta de Software Libre llamada QGIS descargable del sitio: https://qgis.org/

El resultado es una visualización que muestra la distribución geográfica de la población en México de acuerdo a su densidad.

Por ultimo una vista mas sin el fondo:

Conclusión

En este tutorial mostramos una secuencia de pasos que nos permiten instalar una plataforma de Big Data con capacidades Geográficas. El ejercicio puede mejorar mucho, por ejemplo incluir las localidades Rurales. Eso ya lo dejo para que el lector pruebe sus nuevas habilidades de procesamiento de Geo Big Data.

Finalmente aquí tienes el resultado en un mapa interactivo de CartoDB: http://bit.ly/3datq9x

Gracias por Leerme Abel Coronado

Father-Husband-Data Scientist-Philosopher-Entrepreneur-Professor PhD c. in Data Science-MSc Stats #R #Scala #Spark #SatelliteImagery #Python #BigData #Nerd

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store