# Librerías a Utilizar
import seaborn as sns
import pandas as pd
import pysal as ps
import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt
from sklearn import cluster
En esta primera parte de la práctica, se utilizarán datos extraídos de la Base de Datos oficial de AirBnb; se trata de una compañía que provee alternativas de hospedaje diferentes de los hoteles a las personas que visitan un lugar determinado, así como de un ingreso adicional a aquellos con la posibilidad de rentar sus inmuebles. El sitio web de la compañía se actualiza de manera constante con el listado de todas las propiedades disponibles en un lugar dado para los usuarios puedan revisar y reservar según sus necesidades; asimismo, el servicio provee de un mecanismo de retroalimentación en el que ambas partes, tanto anfitriones como huéspedes, tienen la posibilidad de calificar su experiencia, lo cual permite que cada propiedad tenga no sólo una Calificación General de su aptitud como estancia, sino también puntuaciones relacionadas a la limpieza del inmueble, la facilidad de comunicación con el huésped, entre otras.
Los datos originales proporcionados por AirBnb se encuentran detallados a nivel propiedad para toda la Ciudad de México; sin embargo, dado que el número de inmuebles en esta base es demasiado alto, para propósitos de la práctica, los datos han sido agregados a nivel de AGEB. Asimismo, aunque los datos se encuentran disponibles para toda la ciudad, la gran mayoría de estas propiedades se encuentran concentradas en la Alcaldía Cuauhtémoc, donde se ubican los principales atractivos turísticos de la ciudad como el Centro Histórico, el Palacio de Bellas Artes o la Condesa; como tal, se trabajará únicamente con esta alcaldía y, dado que no todas las AGEB's de la alcaldía poseen un AirBnb, únicamente se trabajarán con las AGEB's de la Alcaldía Cuahtémoc que posean por lo menos un AirBnb en su interior, de modo que se le puedan asociar los promedios de calificaciones.
El objetivo de la práctica es crear una clasificación de las áreas (AGEB's) de la Alcaldía Cuauhtémoc, en la Ciudad de México, basándose en las calificaciones que los AirBnb en su interior han recibido. Esto permitirá crear una tipología para la geografía de AirBnb en la alcaldía y, hasta cierto punto, entender un poco mejor la distribución de las propiedades en la misma a través de lo que los propios AirBnb puedan decir del lugar en el que se encuentran. Por una parte, este ejercicio es una prueba idónea para demostrar el tipo de análisis que pueden realizarse gracias a la aparición de nuevas y grandes bases de datos en todas las áreas, algo que hace sólo algunos pocos años hubiera sido muy complicado de realizar por otros medios; por otra parte, es importante tomar en cuenta las restricciones que poseen este tipo de datos y, por ende, limitan la posibilidad de hacer interpretaciones completamente certeras hacia la población en general.
En primer lugar, y como se ha hecho hasta ahora, se establecerá una variable que contenga la ruta en la cual se encuentran almacenados los datos:
f = 'data/'
Después, puede importarse el ShapeFile
a utilizar a lo largo de la práctica, como se ha hecho tradicionalmente a través de geopandas
:
airbnb = gpd.read_file('data/agebs_airbnb.shp') # Importar el ShapeFile
airbnb = airbnb.set_index('ageb') # Establecer la Clave Geográfica del AGEB como Índice
airbnb.head() # Observar el GeoDataFrame importado
A continuación se presenta el significado de cada una de las variables contenidas en el GeoDataFrame
; es importante recordar que las calificaciones mostradas para cada AGEB resultan del promedio de todas las propiedades contenidas en su interior:
no_prop
- Número de Propiedades contenidas en el AGEB.calif
- Calificación General de las Propiedades, en una escala del 0 al 100.expec
- Calificación de Expectativa, es decir, qué tanto se asemeja la experiencia real con lo prometido.limp
- Calificación de Limpieza general de la propiedad.checkin
- Calificación de la facilidad con la que fue posible realizar el Check-In a la propiedad.com
- Calificación de facilidad de Comunicación entre el huésped y el anfitriónubi
- Calificación de Ubicación de la propiedad con respecto a la accesibilidad a otros lugares de la ciudad.precio
- Calificación del Precio, es decir, el equilibrio entre lo pagado y lo recibido.Antes de comenzar a explorar los datos más a fondo, resulta de utilidad realizar un paso más. Puede observarse que no todas las variables contenidas en la tabla resultarán de utilidad para el ejercicio, sino únicamente las asociadas a las calificaciones; como tal, para facilitar el trabajo a futuro, se almacenará el nombre de cada una de estas dentro de una Lista (Array):
calificaciones = ['calif', 'expec', 'limp', 'checkin', 'com', 'ubi', 'precio']
La mejor forma de comenzar a estudiar la geografía de las Calificaciones de AirBnb es graficandolas a todas ellas dentro de un mapa particular para cada una, lo cual nos dará una perspectiva univariada de cada una de las variables de interés.
Debido a que existen muchas columnas de las cuales generar un mapa, puede utilizarse un Bucle (Loop) del tipo for
que genere cada uno de estos mapas, y los coloque dentro de una de las unidades de la figura principal:
# Generación de figura con tres filas y tres columnas
fig, ejes = plt.subplots(nrows=3, ncols=3, figsize=(20, 20))
# Hacer los accesibles a través de un solo índice con la función '.flatten()'
ejes = ejes.flatten()
# Comenzar el bucle utilizando todas las variables de interés
for i, var in enumerate(calificaciones):
# Seleccionar el eje en el que se colocará el mapa
eje = ejes[i]
# Generar el mapa
airbnb.plot(column=var, ax=eje, scheme='Quantiles', linewidth=0.5, edgecolor = 'black', cmap='Blues')
# Remover los ejes del mapa
eje.set_axis_off()
# Colocar como título el nombre de la variable graficada
eje.set_title(var)
plt.show()
Antes de realizar cualquier interpretación de los mapas, resulta pertinente estudiar a detalle el código que permitió generar los mapas anteriores:
.subplots()
de la librería matplotlib
, así como sus argumentos nrows
y ncols
respectivamente..flatten()
para que cada uno de los espacios de la cuadrícula puedan ser llamados de forma individual. Puede pensarse como una forma de enumerar los espacios de la cuadrícula; como tal, si se llama al elemento ejes[0]
(recordando que Python comienza a enumerar desde 0), se estará trabajando con el primer cuadro de la primera fila; el elemento ejes[1]
corresponderá al segundo de la primera fila; ejes[2]
al tercero de la primera fila; ejes[3]
al primero de la segunda fila, y así consecutivamente.for
utilizando la lista de calificaciones
que se generó anteriormente; sin embargo, se está aplicando el método enumerate()
sobre la lista. Esto se debe a que la función enumerate()
, como indica su nombre, enumera a los elementos de la lista; como tal, en la lista calificaciones
, al elemento calif
se le asigna el número 0, a expec
el número 1, y así con el resto. Lo anterior permite que las variables generadas por el bucle, var
e i
, correspondan a la variable con la que se generará el mapa y su ennumeración correspondiente, respectivamente..plot()
(Línea 12); posteriormente, se remueven los ejes del mapa generado con .set_axis_off()
(Línea 14) y, por último, se le coloca como título al mapa el nombre de la variable con la que se ha trabajado.Gracias a los mapas generados, es posible observar que existe una diferencia sustancial en cómo se distribuyen las calificaciones de cada uno de los aspectos de un AirBnb en el espacio. Mientras que la Calificación General (calif
), la de Comunicación con el Anfitrión (com
) y la Ubicación (ubi
) tienden a ser altas en muy pocas AGEB's, principalmente las concentradas en los límites de la alcaldía, otras calificaciones como las de Precio (prec
) o Expectativa (expec
) también tienden a concentrarse en el centro de la misma, donde se encuentra el Centro Histórico.
Aunque se está trabajando con un número relativamente pequeño de variables, resulta complicado a primera instancia determinar cómo funcionan en conjunto y de qué forma se relacionan como un todo con la naturaleza de cada una de las AGEB's estudiadas. Como tal, también resulta de utilidad estudiar la Correlación entre cada una de las variables (como influye una en la otra) y, para esto, la librería seaborn
ofrece la función .pairplot()
, que permite estudiar esta correlación entre un grupo de variables de forma gráfica:
_ = sns.pairplot(airbnb[calificaciones], kind='reg', diag_kind='hist')
El conjunto de gráficas anterior permite responder preguntas de naturaleza univariada o bivariada, como por ejemplo:
limp
de ambos ejes se encuentra un Histograma que muestra que todas las calificaciones de este parámetro se encuentran en un rango de entre 8 y 10, siendo las más comunes las que se encuentran en un rango de entre 9.6 y 9.8.calif
y ubi
, se observará que es de tipo Positiva, es decir, mientras mejor sea una calificación, mayor será la otra.calif
con limp
presenta una mayor inclinación que la existente en la intersección con ubi
, se concluye que la calificación de Limpieza tiene una mayor correlación.Como tal, puede observarse que una gran cantidad de preguntas pueden responderse estudiando la correlación entre pares de variables; sin embargo, esto no puede resultar suficiente cuando se hacen preguntas sofisticadas y de naturaleza multivariada. La figura anterior no permite responder con certeza preguntas como:
Para responder este tipo de preguntas, que involucran una gran cantidad de variables al mismo tiempo, se requiere de un método verdaderamente multivariado, como lo es el Agrupamiento Estadístico.
Revisa la documentación oficial de la función .pairplot()
y experimenta con los parámetros de la misma; por ejemplo, cambia los Histogramas generados en la figura de arriba por Estimaciones de Densidad de Kernel (KDE).
Un análisis geodemográfico invloucra la clasificación de las áreas que forman un mapa geográfico en grupos o categorías de observaciones que se asemejan entre sí, pero resultan diferentes a las presentes en otras categorías. La clasificación se lleva a cabo utilizando un algoritmo de Agrupamiento Estadístico (Clustering) que toma como referencia un conjunto de atributos y regresa el grupo (o la etiqueta) a la que pertenece cada una de las observaciones; dependiendo del algoritmo particular utilizado, parámetros adicionales deben de ser establecidos por el usuario, los cuales pueden variar desde elementos básicos como el número de agrupaciones deseado, hasta detalles más avanzados como ancho de banda, radio, entre otroas.
Para la Clasificación Geodemográfica de la Alcaldía Cuahtémoc utilizando las calificaciones de AirBnb, se utilizará uno de los algoritmos de Agrupamiento Estadístico más populares: K-Means (o K-Medias, al traducirlo al español). Esta técnica ´unicamente requiere como entrada los atributos de las observaciones a tomar como referencia y el número de grupos en los que se desea clasificar a las observaciones; en este caso, se iniciará generando únicamente cinco categorías, para entender con facilidad el resultado obtenido.
Aunque el algoritmo asociado al Método K-Means no es para nada trivial, ejecutarlo en Python es bastante sencillo gracias a la librería scikit-learn
, pues únicamente se necesitan dos líneas de código. Primero se necesita ejecutar el método .KMeans()
, perteneciente al submódulo cluster
de la librería scikit-learn
, para establecer los parámetros del algoritmo; en este paso, aún no es necesario introducir las variables, sino únicamente determinar el número de Clusters en los cuales se desea agrupar a los datos:
kmeans5 = cluster.KMeans(n_clusters=5)
El resultado del método .KMeans()
fue almacenado dentro de una variable llamada kmeans5
; aunque únicamente se colocó de forma explícita el argumento n_clusters
para determinar el número deseado de grupos, el método posee muchos otros que establece por defecto, y que pueden ser revisados si se analiza a la variable generada:
kmeans5
Para verdaderamente ejecutar el algoritmo, es necesario ejecutar el método .fit()
sobre la variable antes creada, esta vez estableciendo cuáles son las variables que se utilizarán como referencia para generar los grupos:
# Asegurar que siempre se obtengan los mismos resultados; cambiar el número cambiará los resultados
np.random.seed(1234)
# Ejecutar el algoritmo con las variables establecidas
k5cls = kmeans5.fit(airbnb[calificaciones])
El objeto contenido dentro de la variable k5cls
contiene una gran cantidad de componentes que pueden ser utilizados para el análisis; por ahora, únicamente se utilizará el llamado labels_
, que representa las diferentes categorías en las cuales han sido agrupados los datos; es importante recordar que Python comienza su numeración desde el cero, por lo que las etiquetas se encuentran marcadas del 0 al 4 para representar cinco grupos:
k5cls.labels_
Cada número representa una categoría diferente, lo que significa que si a dos observaciones se les ha asignado el mismo número, entonces pertenecerán al mismo grupo. Dado que el orden en que se encuentran estas etiquetas es exactamente el mismo que el orden de los atributos utilizados para su generación, es posible colocar éstas como una nueva columna en el GeoDataFrame
original:
airbnb['k5cls'] = k5cls.labels_
airbnb.head()
Para entender con más detalle el resultado obtenido, resulta útil visualizar las categorías generadas en un mapa. Para esto, se generará un Mapa de Coropletas en el que cada categoría se asociará automáticamente a un color diferente, lo cual se logra gracias al argumento categorical
de la función .plot()
:
# Crear la figura y sus ejes
fig, ejes = plt.subplots(1, figsize=(12, 12))
# Generar un Mapa de Coropletas Categórico
airbnb.plot(column='k5cls', categorical=True, legend=True, edgecolor='', ax=ejes)
# Remover los ejes del mapa
ejes.set_axis_off()
# Asignar un título
plt.title('Clasificación Geodemográfica de AirBnb para la Alcaldía Cuauhtémoc')
# Mostrar el resultado
plt.show()
El mapa anterior representa la Distribución Geográfica de las cinco categorías creadas por el Algoritmo K-Means. A través de éste, es posible observar cierto patrón espacial en los resultados; por una parte, la Categorías 3 (Gris) es la que abarca la gran mayoría de la alcaldía, comprendiendo casi todas las AGEB's en el centro y suroeste de la misma; la Categoría 0 (Azul Oscuro) es la siguiente en términos de tamaño, distribuyéndose principalmente en los límites norte y este; las Categorías 1, 2 y 4 son las del menor número de elementos, distribuyéndose de forma algo heterogénea a lo largo de toda la alcaldía..
Resulta útil no sólo entender cómo es que se han distribuído las categorías en el espacio, sino también entender el porqué los elementos se han agrupado de la forma en que lo hicieron, razón por la cual se recurre a la Estadística. Como primer paso, es importante saber cuántas observaciones fueron asignadas a cada categoría; para ello, se utilizará la función .groupby()
de la librería pandas
, estudiada en prácticas anteriores, utilizando también el método .size()
que obtiene el número de elementos en un subgrupo:
k5_cuentas = airbnb.groupby('k5cls').size()
k5_cuentas
El operador .groupby()
toma un DataFrame
y lo agrupa utilizando los valores de una columna dada (k5cls
), lo cual permite aplicar sobre éste alguna operación dada, en este caso .size()
; en otras palabras, lo que se realiza es agrupar en función de las categorías creadas, y contar cuántos elementos posee cada una. Para entender esto visualmente, puede realizarse una Gráfica de Barras:
_ = k5_cuentas.plot.bar()
Como se observó en el mapa, cada una de las categorías posee un número diferente de elementos; la Categoría 3 rebasa por mucho las 80 observaciones, mientras que las Categorías 1 y 4 no logran superar las 20.
Para continuar describiendo las características de cada categoría, pueden estudiarse los valores de los atributos utilizados para crearlas. Recordando que se utilizaron las calificaciones de los AirBnb contenidos en cada AGEB para generar las categorías, podría estudiarse cuál terminó siendo el valor promedio de cada una de éstas dentro de las categorías; para esto, nuevamente se puede recurrir al método .groupby()
, pero esta vez combinándolo con la función .mean()
:
# Calcular la media de todas las calificaciones para cada Categoría
k5_promedios = airbnb.groupby('k5cls')[calificaciones].mean()
# Transponer la tabla, únicamente por cuestiones de visualización
k5_promedios.T
Analizando únicamente la Calificación General (calif
), podría decirse que las AGEB's con los AirBnb mejor claificados se concentran en la Categoría 0, mientras que los peor calificados son los de la Categoría 4.
Si se desea estudiar con mucho más detalle cada una de las categorías, desde el punto de vista estadístico, podría combinarse la función .groupby()
con .describe()
, lo cual arrojará un mayor número de cálculos:
# Obtener un Resumen Estadístico de cada una de las Categorías
k5_estad = airbnb.groupby('k5cls')[calificaciones].describe()
# Observar el resultado
k5_estad
Con esto, es posible concluir la sección relacionada con Segmentación Geodemográfica. Puede resaltarse que la escencia del algoritmo ejecutado, y de todos los que corresponden a esta categoría, tiene una base completamente estadśitica, esto es, el dónde se encuentran las observaciones no tiene relevacia alguna para el algoritmo al momento de clasificar. En algunos casos, lo anterior puede resultar idóneo, sobretodo si el objetivo de la investigación se centra en conocer si los datos tienen algún tipo de Distribución Espacial por sí mismos; sin embargo, si de antemano se sabe que esta distribución existe, y el objetivo de la investigación lo amerita, entonces se necesita tomar en cuenta la componente espacial para el cálculo.
Para esto, se recurre a las técnicas de Regionalización.
Se le conoce como Regionalización al subconjunto de técnicas de agrupamiento que consideran a la componente espacial dentro de la clasificación; en otras palabras, el resultado de regionalizar involucra áreas que son contínuas en el espacio. Lo anterior significa que estas técnicas agregan áreas en un conjunto de menor númer de unidades espaciales, llamadas regiones; lo anterior implica que las áreas se encuentran anidadas dentro de las regiones.
Ejemplos de lo anterior son los estados (áreas) que se encuentran contenidos dentro de un país (región) o, en el caso de México, los municipio (áreas) contenidos dentro de un estado (región); la diferencia principal entre los ejemplos anteriores y el resultado de un algoritmo de Regionalización es que, mientras las anteriores fueron generadas meramente a partir de principios administrativos, políticos o sociales, el algoritmo sigue principios estadísticos y, al igual que su variante no espacial, trata de conjuntar observaciones cuyos atributos sean lo más matemáticamente similares, siguendo también ahora las limitantes establecidas por la componente espacial.
Al igual que en el caso no espacial, existen una gran cantidad de algoritmos para generar una Regionalización, todos ellos variando en la forma en la que se mide la semejanza o diferencia de los atributos, el proceso de la regionalizacíon, entre otros. Aún así, todos ellos comparten algunos aspectos en común; en particular, todos ellos toman como referencia un conjunto de atributos y la representación del espacio (a través de Matrices de Pesos Espaciales), así como, en algunos casos, el número de regiones que se desean generar.
Para ilustrar estos conceptos, se aplicará un Algoritmo de Regionalización sobre los datos de AirBnb utilizados hasta ahora. En este caso, el objetivo será dividir la alcaldía en Colonias, basándose en las calificaciones de las propiedades de AirBnb en lugar de las razones administrativas detrás de las Colonias que verdaderamente existen en ésta; como tal, se generarán regiones formadas de AGEB's con similitudes en sus calificaciones de AirBnb.
Para esto, se utilizará una nueva librería de Python llamada clusterpy
. Si se revisan los archivos que forman la unidad, se encontrará que dentro de la misma carpeta de trabajo existe una carpeta con este nombre; lo anterior se debe a que clusterpy
no es una librería ampliamente distribuida, como lo son numpy
o pandas
, por lo que no será encontrada a través del manejador de liberías Conda o de forma sencilla buscando en internet. clusterpy
se trata de una librería local y, al igual que el resto de las librerías trabajadas hasta ahora, puede ser importada sencillamente a través de import
:
import clusterpy
Es importante resaltar que, en Python, no sólamente pueden utilizarse librerías ampliamente distribuidas, como las manejadas hasta ahora, sino también aquellas que desarrollen autores y grupos de trabajo de forma local, siempre y cuando se coloquen en el lugar correcto para trabajarlas.
Para utilizar los Algoritmos de Regionalización contenidos en clusterpy
, primero es necesario importar el ShapeFile
original en lo que la librería llama un objeto de tipo Layer
; esto es algo exclusivo de clusterpy
pues, a diferencia de otras librerías, no puede utilizar la importación realizada por GeoPandas
, y necesita generar una propia a través de su función .importArcData()
:
layer = clusterpy.importArcData(f + 'agebs_airbnb')
Dentro de la variable layer
se encuentra contenida la información que clusterpy
necesita para trabajar; como tal, es posible llamar la función .cluster()
para ejecutar un Algoritmo de Regionalización. Como se mencionó anteriormente, existen una gran cantidad de ellos; es posible visualizar todos los que la librería clusterpy
contiene utilizando el siguiente comando:
clusterpy.CPhelp('Layer.cluster')
En este caso, se utilizará el algotimo Automated Zoning Procedure (AZP) propuesto por S. Openshaw y L. Rao en 1995 (Artículo Original), el cual toma un conjunto de atributos, una Matriz de Pesos Espaciales y el número de regiones que se desea generar; para términos de comparación, se le solicitará al algoritmo que genere 33 regiones, que es el mismo número de colonias que puede encontrarse dentro de la Alcaldía Cuauhtémoc.
Puede notarse que, aunque se mencionó que el Algoritmo AZP requiere de una matriz de pesos espaciales, hasta el momento no se han utilizado los métodos estudiados anteriormente; esto se debe a que clusterpy
genera su propia matriz, por lo que no es necesario volver a calcularla.
Como tal, el Algoritmo de Regionalización AZP se ejecuta a través de la función .cluster()
de la siguiente forma:
layer.cluster('azp', calificaciones, 33, wType='queen')
Cabe destacar la forma en la que fueron introducidos los argumentos dentro de la función .cluster()
; primero, se especificó el tipo de algoritmo a ejecutar (azp
); después, se introdujeron los atributos a tomar en cuenta para la regionalización, siendo la lista de atributos guardada en la variable calificaciones
; posteriormente, el número de regiones deseadas (33
), para terminar con el tipo de Matriz de Pesos Espaciales a utilizar en el análisis (queen
para una Matriz de Contigüidad de Reina, y rook
para una de Torre).
En este momento, la variable layer
contiene una gran cantidad de información que puede ser analizada; sin embargo, al igual que como se hizo con el método K-Means, por el momento únicamente se desea saber a qué categoría pertenece cada una de las observaciones. Para esto, se puede revisar el atributo region2areas
del objeto de tipo Layer
, el cual arroja en forma de lista las etiquetas buscadas; como la lista se encuentra ordenada, es posible colocarla directamente como una nueva columna en el GeoDataFrame
original:
airbnb['azpcls'] = layer.region2areas
airbnb.head()
Como tal, la nueva columna azpcls
posee exactamente las mismas características que k5cls
, utilizada anteriormente, pues contiene una variable categórica que puede ser colocada en un Mapa de Coropletas Categórico. Por lo tanto, el código para obtener su mapara correspondiente es exactamente el mismo que el anterior, únicamente cambiando el argumento column
de la función .plot()
con el nombre de la nueva variable a representar:
# Crear la figura y sus ejes
fig, ejes = plt.subplots(1, figsize=(12, 12))
# Generar un Mapa de Coropletas Categórico
airbnb.plot(column='azpcls', categorical=True, legend=True, edgecolor='', ax=ejes)
# Remover los ejes del mapa
ejes.set_axis_off()
# Asignar un título
plt.title('Clasificación Geodemográfica de AirBnb para la Alcaldía Cuauhtémoc')
# Mostrar el resultado
plt.show()
Inclusive es posible realizar el mismo tipo de análisis estadístico realizado anteriormente, de modo que puedan entenderse con mayor detalle las categorías generadas. Por ejemplo, para conocer el número de observaciones contenidas en cada categoría:
azp_cuentas = airbnb.groupby('azpcls').size()
_ = azp_cuentas.plot.bar(figsize = (20,5))
Asimismo, puede obtenerse un resumen estadístico de lo observado en cada una de las categorías:
azp_promedios = airbnb.groupby('azpcls')[calificaciones].mean()
azp_promedios.T
.dissolve()
en GeoPandas
¶El mapa anterior permite tener una visualización relativamente clara de los límites de las regiones generados por el Algoritmo AZP; sin embargo, ésta aún se basa en el coloreado de las áreas (AGEB's) más pequeñas que le componen. Como tal, para obtener propiamente las nuevas regiones, es necesario "fundir" todas las AGEB's que pertenecen a una misma categoría en un sólo polígono.
Lo anterior, dentro de los Sistemas de Información Geográfica, es una operación vectorial conocida como Disolver (Dissolve); se trata de una operación ampliamente difundida en todos los SIG, y también puede ejecutarse de forma muy sencilla en GeoPandas
a través de la función .dissolve()
:
# Almacenar las columnas del 'GeoDataFrame' que son de interés para '.dissolve()'
tmp = airbnb[['azpcls','geometry']]
# Ejecutar la función
colonias_airbnb = tmp.dissolve(by = 'azpcls')
En la celda anterior, se almacena dentro de una variable temporal (tmp
) las columnas que son de interés para la función .dissolve()
; en este caso, azpcls
, debido a que las categorías contenidas en ésta serán las que determinarán qué polígonos se fundirán entre sí, y geometry
, al contener la geometría de cada polígono. Posteriormente, se ejecuta la función a esta variable, indicando a través del argumento by
cuál es la columna que regirá la operación.
Para visualizar el resultado, simplemente puede recurrirse a la función .plot()
, dado que en la celda anterior se generó un nuevo GeoDataFrame
:
# Crear la figura y sus ejes
fig, ejes = plt.subplots(1, figsize=(12, 12))
# Graficar las nuevas colonias generadas
colonias_airbnb.plot(figsize = (10,10), edgecolor = 'black', facecolor = '#50C878', ax = ejes)
# Remover los ejes del mapa
ejes.set_axis_off()
# Asignar un título
plt.title('Colonias para la Alcaldía Cuauhtémoc basadas en AirBnb')
# Mostrar el resultado
plt.show()
En la realidad, la Alcaldía Cuauhtémoc ya se encuentra dividida en Colonias, cuyos límites estan basados en criterios administrativos y sociales. Como tal, resulta interesante comparar las similitudes y diferencias entre lo obtenido por el Algoritmo AZP y lo que se tiene en la realidad.
En la carpeta de trabajo se encuentra un ShapeFile
que contiene estas colonias:
colonias_reales = gpd.read_file('data/colonias_cuauh.shp') # Importar el archivo .shp
colonias_reales = colonias_reales.set_index('id') # Determinar la variable 'id' como índice
colonias_reales.head() # Observar la tabla
Y, de igual forma a como se hizo con las Colonias basadas en AirBnb, puede obtenerse un mapa:
# Crear la figura y sus ejes
fig, ejes = plt.subplots(1, figsize=(12, 12))
# Graficar las colonias originales
colonias_reales.plot(figsize = (10,10), edgecolor = 'black', facecolor = '#50C878', ax = ejes)
# Remover los ejes del mapa
ejes.set_axis_off()
# Asignar un título
plt.title('Colonias Administrativas de la Alcaldía Cuauhtémoc')
# Mostrar el resultado
plt.show()
Resultaría de mayor utilidad si ambos mapas se generaran dentro de la misma figura, uno al lado del otro. Para conseguir esto, puede emplearse una aproximación muy similar a la manejada durante el mapeo inicial de las calificaciones de AirBnb, en la que se genera una cuadrícula de determinadas filas y columnas:
# Crear la figura y sus ejes
fig, ejes = plt.subplots(nrows = 1, ncols = 2, figsize=(20, 20))
# Aislar los ejes (cuadros) en sus propias variables
eje1 = ejes[0]
eje2 = ejes[1]
# Para el primer eje (cuadro)
# Graficar las nuevas colonias generadas
colonias_airbnb.plot(figsize = (10,10), edgecolor = 'black', facecolor = '#50C878', ax = eje1)
# Remover los ejes del mapa
eje1.set_axis_off()
# Asignar un título
eje1.set_title('Colonias para la Alcaldía Cuauhtémoc basadas en AirBnb')
# Para el segundo eje (cuadro)
# Graficar las colonias originales
colonias_reales.plot(figsize = (10,10), edgecolor = 'black', facecolor = '#50C878', ax = eje2)
# Remover los ejes del mapa
eje2.set_axis_off()
# Asignar un título
eje2.set_title('Colonias Administrativas de la Alcaldía Cuauhtémoc')
plt.show()
Observando el resultado, pueden destacarse algunas diferencias y similitudes entre los dos mapas. La más clara es que, mientras que los límites admnistrativos generan colonias de un tamaño balanceado y fácil de distinguir, los límites de las regiones generadas por AZP difieren enormemente entre sí, tanto en términos de tamaño como facilidad de visualización. Esto se debe propiamente a la naturaleza de los datos colocados en el algoritmo; basándose en las calificaciones de AirBnb, pueden observarse grandes colonias derivadas de AGEB's con características muy similares y, por ende, pertenecientes a la misma categoría, mientras que también se pueden distinguir enclaves con características lo suficientemente diferentes como para ser consideradas su propia región.
Los resultados obtenidos a través de los algoritmos disponibles en las distintas librerías de Python comúnmente son de gran utilidad y, por ende, resulta pertinente el poder almacenarlos como archivos aislados para continuar trabajando con ellos en un futuro, ya sea en algún Sistema de Información Geográfica, algún software de análisis estadístico u otro script de Python. Por fortuna, la librería GeoPandas
ofrece una forma sencilla y veloz de almacenar cualquier tipo de GeoDataFrame
generado, a través de la función .to_file()
:
colonias_airbnb.to_file('data/colonias_airbnb.shp')
En la celda anterior, el GeoDataFrame
con las colonias fue almacenado en formato ShapeFile
; sin embargo, la librería también ofrece la posibilidad de almacenar archivos en formato GeoJSON
o GeoPackage
; también es importante tomar en cuenta que el archivo exportado tendrá el mismo Sistema de Coordenadas de Referencia (CRS) que el GeoDataFrame
original.
Reproduce la práctica, esta vez utilizando el ShapeFile
dentro de la carpeta de datos bajo el nombre de agebs_educacion.shp
; éste también contiene todas las AGEB's de la Alcaldía Cuauhtémoc, pero esta vez con datos del Nivel de Escolaridad de los habitantes de cada AGEB. Las variables que contiene son:
pob_analf
- Número de habitantes en el AGEB con analfabetismo (No saben leer ni escribir)pob_sinedu
- Habitantes sin escolaridad alguna.pob_basica
- Habitantes que cursaron Primaria y/o Secundaria, pero no la finalizaronpob_secun
- Habitantes que finalizaron, como máximo, hasta el Nivel Básico (Secundaria)pob_bach
- Habitantes que finalizaron, como máximo, hasta el Nivel Medio-Superior (Bachillerato-Preparatoria)pob_sup
- Habitantes que poseen algún grado de Nivel Superior, sea Licenciatura, Maestría o Doctorado.Para reproducir el ejercicio, es necesario:
agebs_educacion.shp
)