top of page
Foto do escritorCarlos Silva

Ranqueamento personalizado de regiões em João Pessoa para locação de imóvel usando K-Means, Python e Google Maps.

Atualizado: 11 de jun.

Em 2023 entrei no regime 100% Home Office, nesse contexto decidir por escolher uma cidade que pudesse me atender melhor nas coisas que desejava na vida, depois de testar morar por alguns lugares no Brasil ao longo desse ano decidi que esse lugar iria ser João Pessoa na Paraíba. Agora eu tinha que enfim alugar um apartamento...

...mas morar onde? Baseado em que eu faria essa decisão? Do que eu preciso perto desse lugar para atender as minhas necessidades cotidianas?

A resolução desse problema é o que vocês verão na sequência.

A proposta de resolução passa pelas seguintes etapas executadas usando python:

  • Coleta de dados. Através dos pacotes osmnx e googlemaps (API python do Google Maps), coletando as informações de limites geográficos da cidade (ruas e afins) e os pontos de interesse (Facilities), respectivamente.

  • Seccionar os limites geográficos em hexágonos e interseccionar com os pontos comerciais de interesse.

  • Contabilizar esses pontos de interesse por hexágono e ponderar a minha importância pessoal para cada tipo deles.

  • Clusterizar essa tabela de pontos de interesse ponderados e decidir dentre uma lista de endereços de interesse as melhores regiões.


Funções python

Para deixar as coisas mais organizadas e objetivas eu montei uma série de funções em process.py e as dependências estão listadas em requeriments.txt , essas funções foram responsáveis pela coleta e o processamento geográfico, se essa parte for do seu interesse eu tive o cuidado de deixar o que cada uma faz da forma mais clara e documentada o possível. Dentre elas a obtenção da chave para usar a API do Google Maps é a que julguei que pode precisar de um pouco mais de empenho, a coleta não é a principal questão que quero abordar hoje, porém vou deixar esse link para você explorar e você vai precisar ter uma conta no serviço de Cloud do Google para prosseguir, mas deixei disponível no repositório os arquivos que obtive na minha análise.


Carregando dados geográficos

Carregando grafo e área de João Pessoa, Paraíba, Brazil

Carregando lista de locações de interesse

geopandas com coordenadas de endereços

Criando Hexágonos

A escolha por hexágonos se deve porque essa forma geometria é capaz de cobrir o globo sem ter que deformar sua geometria, além do fato que a distância do centro do hexágono para um adjacente é sempre a mesma. Eu usei um pacote chamado h3 para isso.

Facilities por Google Maps API

Existem uma infinidade de tipos de lugares de interesse, eu listei apenas os 5 principais para mim, o critério principal da escolha destes é que eu preciso acessa-los pelo menos uma vez por semana. Para saber quais os tipos disponíveis na API do Google maps você pode ver esse link.


IMPORTANTE!!! ISSO PODE TER CUSTOS DE USO DA API SE EXCEDER O LIMITE DE REQUISIÇÕES POR DIA OU MINUTO, você pode usar os arquivos pre-baixados no repositório

Interseccionando Facilities com Hexágonos


Dando pesos para os Facilities de cada Hexágono

Na cidade existem bairros que tem alta concentração de alguns desse pontos de interesse, um lugar que tem shopping no bairro por exemplo tem muitos restaurantes, porém isso não é importante para o contexto da nossa analise, já que por mais que uma área tenha 10 ou 20 restaurantes na prática eu vou pensar em 5 e frequentar de fato uns 2. Por isso ajustei as contagens para considerar no máximo 5 itens de cada, o que vai ajudar a normalizar a escala dessas variáveis para os pesos que serão aplicados.

Após todo esse processamento podemos esperar o seguinte mapa de informações.

regiões hexágonais ponderadas por facilities

Cluster K-Means

Existem uma grande variedade de tipos de clusterização, na documentação do scikit-learn é apresentada um breve resumo de algumas delas. Um algoritmo de Cluster amplamente conhecido e simples é o K-Means, ele trabalha melhor em geometria plana (duas dimensões) e com pouca quantidade de clusters, para conseguir usá-lo vai vou reduzir a quantidade de features usando o método de PCA (Principal component analysis).


Aqui vemos que a distribuição de restaurantes é praticamente uniforme, com isso já podemos prever que não será uma boa característica de agrupamento.

medidas descriticas de facilities

Redução de dimensionalidade - PCA

Aqui observamos que a variância explicada é de aproximadamente 80% usando dois componentes apenas, isso é perfeito para podermos clusterizar.

variância explicada cumulativa

Aqui vemos que boa parte das variáveis tem boa correlação com os dois primeiros componentes, com exceção de restaurante, o que era esperado pois sua distribuição nesse caso é praticamente uniforme.

correlações entre componentes e variáveis

Selecionando a quantidade de Clusters


Para escolher a quantidade ideal de clusters poremos testar diferentes números de agrupamentos e verificar como se desempenham na métricas abaixo.

Métricas de Agrupamento e Separação

  • Silhueta: É um método de interpretação e validação de consistência dentro de grupos de dados. A silhueta é uma medida de quão semelhante um objeto é ao seu próprio cluster (coesão) em comparação a outros clusters (separação) . A silhueta varia de -1 a +1, onde um valor alto indica que o objeto é bem compatível com o seu próprio cluster e mal combinado com os clusters próximos. Se a maioria dos objetos tiver um valor alto, a configuração do cluster será apropriada. Se um número significativo de pontos tiver um valor baixo ou negativo, a configuração do cluster pode ter muitos ou poucos clusters.

  • Distorção: É uma métrica de avaliação de clusters que mede a qualidade de um agrupamento de dados. Ela calcula a soma das distâncias quadradas entre cada ponto de dados e seu centroide mais próximo. Um valor de distorção menor indica um agrupamento melhor, pois significa que os pontos de dados estão mais próximos de seus centroides.

  • Calinski-Harabasz: Também conhecido como critério de razão de variância, é uma medida de quão semelhante um objeto é ao seu próprio cluster (coesão) em comparação com outros clusters (separação). Aqui, a coesão é estimada com base nas distâncias dos pontos de dados em um cluster até o centroide do cluster e a separação é baseada na distância dos centroides do cluster do centroide global. Um valor mais alto do índice CH significa que os clusters são densos e bem separados, embora não haja um valor de corte “aceitável”.


Em geral precisamos escolher aquela solução que dá um pico ou pelo menos um cotovelo abrupto no gráfico. Por outro lado, se a linha for suave (horizontal ou ascendente ou descendente), não há razão para preferir uma solução em detrimento de outras. Eu utilizei o pacote Yellowbrick para agilizar esse processo, onde optei por usar 5 clusters.

silhouette
Distorção
Calinski-Harabasz

Construindo Cluster

Então, relembrando, reduzimos a dimensão do dataset para dois componentes principais e aplicamos o K-means para formar 5 agrupamentos. O resultado que temo é o abaixo.

distribuição dos clusters nos componentes principais

Avaliando o cluster

Para entender melhor qual cluster é melhor, e estabelecer um ranking eu usei as médias dos pesos que produzi anteriormente. Vemos que o cluster 1 foi o mais bem ranqueado tendo um peso médio bom em todas as categorias, seguido pelo cluster 3 que tem valores medianos em academia, park, e farmácia.


médias dos pesos por cluster

GINI dos Clusters

Índice de Gini, é um instrumento para medir o grau de concentração em determinado grupo. O Coeficiente de Gini consiste em um número entre 0 e 1, onde 0 corresponde à completa igualdade e 1 corresponde à completa desigualdade (onde uma pessoa recebe todo o rendimento e as demais nada recebem). Levando em conta essa conceituação o que esperamos é que após a clusterização as variáveis sejam mais "iguais" dentro de um cluster do que no contexto geral. Aqui um artigo que usa o conceito de Gini para clusters.

Vemos que os Ranks de 1 a 3 são bons na em agregar toda as variáveis em intervalos mais uniformes, e os ranks 4 e 5 fazem isso apenas com a variável restaurante.

GIINI dos ranks

Mapa final

Dada essas características eu consigo projetar o seguinte mapa. Verifica-se logo que dois duas das locações que eu pré-selecionei ficam em zonas de rank 1. Eu optei por morar em uma delas.


Considerações finais

Já fazem 4 meses que me mudei para a locação que escolhi através desse processo e tenho minhas considerações.


A minha ideia era que todas as coisas que eu precisava fossem fáceis de acessar a pé. Contudo, nesse contexto podemos lidar com sub-agrupamentos dentro dos hexágonos, no meu caso a concentração de supermercados e parks fica em cantos opostos à minha locação, o que dificultou o contato. O pacote h3 que usei para produzir os hexágonos possui proporções fixas de tamanho de hexágono e essa era a que melhor se adequava ao tamanho da análise. Para uma visão geral da cidade os hexágonos servem bem, mas para analisar locações em especifico em uma próxima eu usuária distâncias calculadas, já fizemos isso nesse blog e você pode verificar aqui nesse link.


Outro ponto que acontece é que quantidade desses pontos comerciais não indica qualidade, uma mercearia pode ser categorizada como supermercado e colocada no mesmo nível de um grande supermercado (onde eu provavelmente iria preferir fazer as compras da minha semana), ou esse supermercado ser o único, porém completo. Na API do google maps é possível ter acesso a classificação do estabelecimento, nem sempre ela existe, mas seria uma melhoria interessante.


Referências



997 visualizações3 comentários

3 Comments


Ciro Figueiredo
Ciro Figueiredo
Jun 12

Oi boa tarde

Muito obrigado por compartilhar. Não sei se voce pode ajudar. Estou tentanto replicar no colab, mas estou com problemas na primeira função 'create_geo_address'

mportError: cannot import name 'create_geo_address' from 'process'

Mas acuso esse erro.

Like
Ciro Figueiredo
Ciro Figueiredo
Jun 19
Replying to

Olá Carlos,


deu certo sim! Muito obrigado mesmo!

Like
Post: Blog2_Post
Post: Blog2 Custom Feed
bottom of page