O Índice de Qualidade de Vida Urbana de Belo Horizonte (IQVU-BH) é um índice composto por diversas variáveis - como por exemplo: infraestrutura urbana, segurança, educação - que buscam quantificar a disponibilidade de bens e serviços públicos e privados na cidade. O IQVU é calculado para 79 UP´s (Unidades de Planejamento) existentes em Belo Horizonte.
Seu objetivo é delimitar as áreas prioritárias para os investimentos públicos e a melhor compreensão da distribuição dos bens e serviços públicos e privados entre as regiões da cidade.
Existem 10 variáveis que são agrupadas gerando o valor final do índice, que varia entre 0 e 1, sendo 1 o valor ideal que significa pleno acesso aos bens e serviços públicos e privados.
No portal da Prefeitura de Belo Horizonte é possível consultar as estatísticas descritivas para os dados do IQVU. Link disponível em: https://prefeitura.pbh.gov.br/estatisticas-e-indicadores/indice-de-qualidade-de-vida-urbana
E no portal de Dados Abertos da Prefeitura de Belo Horizonte estão disponibilizados os dados do IQVU em formato aberto para todos os anos da série histórica. Link disponível em: http://dados.pbh.gov.br/dataset/indice-de-qualidade-de-vida-urbana-iqvu
Utilizar um algoritmo de aprendizagem não supervisionada (unsupervised learning) para agrupamento. Será utilizado o agrupamento k-means (K-Médias) e o Hierarchical Clustering (agrupamento hierárquico). O objetivo de um algoritmo de clustering/agrupamento é localizar subgrupos homogêneos nos dados.
O agrupamento é uma técnica que divide os dados em diferentes grupos, agrupando os registros que são similares em um mesmo grupo. Baseia-se no conceito de similaridade, que significa encontrar itens similares de acordo com os seus atributos / características.
A similaridade é determinada a partir do cálculo da distância. A medida de distância mais comum utilizada é da distância euclidiana.
Para cada observação nos dados, neste caso as UP´s, será realizado o cálculo das distâncias entre os valores dos atributos de uma observação (UP) com os demais.
Assim, o objetivo será agrupar as UP´s que possuam resultados similares para as variáveis que compõem o IQVU. Agrupar UP´s com características similares pode ser muito útil para a avaliação de políticas públicas (reveja acima o objetivo do IQVU).
A partir do agrupamento das UP´s, os grupos resultantes podem ser usados diretamente ou analisados em detalhes. Será utilizado o IQVU do ano de 2016 para a nova série histórica.
# load dos dados diretamente da página de dados abertos
url <- "https://ckan.pbh.gov.br/dataset/a167194d-f308-47d6-b040-109f7fb44490/resource/d9732b34-697d-49d4-84d1-9cd498807239/download/bd_iqvu_1994_2016.csv"
iqvu <- read.csv2(url, sep = ";")
# exibir o número de linhas e colunas
dim(iqvu)
## [1] 934 79
O arquivo contém 934 linhas e 79 colunas.
# Exibindo apenas as primeiras 10 linhas e 5 colunas
head(iqvu[, 1:5], 10)
## ï..SERIE ANO CODUP NOMEUP
## 1 SERIE HISTORICA 1994 1801 Bairro das Industrias
## 2 SERIE HISTORICA 1994 1802 Lindeia
## 3 SERIE HISTORICA 1994 1803 Barreiro de Baixo
## 4 SERIE HISTORICA 1994 1804 Barreiro de Cima
## 5 SERIE HISTORICA 1994 1805 Jatoba
## 6 SERIE HISTORICA 1994 1806 Cardoso
## 7 SERIE HISTORICA 1994 1807 Olhos Dagua
## 8 SERIE HISTORICA 1994 1901 Barro Preto
## 9 SERIE HISTORICA 1994 1902 Centro
## 10 SERIE HISTORICA 1994 1903 Francisco Sales
## Hiper_e_Supermercados_M2_hab
## 1 70.97
## 2 21.36
## 3 119.40
## 4 15.90
## 5 5.08
## 6 28.62
## 7 0.00
## 8 0.00
## 9 1156.62
## 10 0.00
Na coluna de “SERIE” existem dois valores: “NOVA SERIE” e “SERIE HISTORICA”. Para este trabalho utilizarei apenas a “NOVA SERIE” e o ano mais recente que é o ano de 2016.
# Quantidade de registros existentes para cada série
table(iqvu$ï..SERIE)
##
## NOVA SERIE SERIE HISTORICA
## 395 539
A “NOVA SERIE” contém 395 registros enquanto que a série histórica possui 539 registros.
# Ano mais recente
max(iqvu$ANO)
## [1] 2016
# Selecionando o período desejado e as colunas 'NOMEUP' e indicadores do IQVU
iqvu_2016_novaserie <- subset(iqvu[, c(4, 68:77)], iqvu$ï..SERIE == "NOVA SERIE" &
iqvu$ANO == "2016")
# exibir o número de linhas e colunas após a seleção desejada
dim(iqvu_2016_novaserie)
## [1] 79 11
Foram selecionadas as 79 UP’s e os 10 indicadores do IQVU, resultando em uma base com 79 linhas e 11 colunas.
# ver um exemplo dos dados após a seleção desejada
head(iqvu_2016_novaserie, 10)
## NOMEUP IQVU_1_Abastecimento IQVU_2_Cultura IQVU_3_Educacao
## 779 Bairro das Industrias 0.9940237 0.49391543 0.81960532
## 780 Lindeia 0.9469004 0.32876608 0.82082127
## 781 Barreiro de Baixo 0.9531406 0.56962738 0.91400303
## 782 Barreiro de Cima 0.8345441 0.26612521 0.70309624
## 783 Jatoba 0.8661184 0.30256999 0.87072561
## 784 Cardoso 0.9006064 0.40632949 0.83585221
## 785 Olhos Dagua 0.4756854 0.10597645 0.76069561
## 786 Barreiro-Sul 0.4258222 0.09892561 0.01771349
## 787 Barro Preto 0.9935496 0.82597889 0.85950189
## 788 Centro 0.9999978 0.57641102 0.87000216
## IQVU_4_Esportes IQVU_5_Habitacao IQVU_6_Infra.estrutura_urbana
## 779 0.6728575 0.7488232 0.9257186
## 780 0.9020668 0.7179589 0.7485667
## 781 0.8823337 0.7667035 0.8381639
## 782 0.9181457 0.6366434 0.7683366
## 783 0.9180694 0.5701273 0.7347865
## 784 0.8849261 0.7140765 0.7879005
## 785 0.6571796 0.5299488 0.8076875
## 786 0.2009849 0.6188212 0.8255495
## 787 0.5125522 0.9163966 0.9492383
## 788 0.7126057 0.8247964 0.9517579
## IQVU_7_Meio_Ambiente IQVU_8_Saude IQVU_9_Servicos_Urbanos
## 779 0.6376637 0.6611885 0.5322750
## 780 0.8585851 0.6617711 0.4771694
## 781 0.7905610 0.7579610 0.6698302
## 782 0.9093240 0.5162690 0.3999648
## 783 0.9098311 0.5460969 0.4278200
## 784 0.8817079 0.6045992 0.4622390
## 785 0.9058444 0.6197358 0.2325130
## 786 0.9683156 0.2874423 0.1400351
## 787 0.7583063 0.8436285 0.8944410
## 788 0.9140403 0.7586674 0.8686578
## IQVU_10_Seguranca_urbana
## 779 0.7540278
## 780 0.1821682
## 781 0.1649128
## 782 0.1640017
## 783 0.1311915
## 784 0.2559824
## 785 0.8817251
## 786 0.9943229
## 787 0.5798414
## 788 0.1209365
# Transformando a coluna 'NOMEUP' em índice do datafrane e excluindo a coluna
# original
rownames(iqvu_2016_novaserie) <- iqvu_2016_novaserie$NOMEUP
iqvu_2016_novaserie$NOMEUP <- NULL
# vendo as primeiras 10 linhas
kable(head(iqvu_2016_novaserie, 10))
| IQVU_1_Abastecimento | IQVU_2_Cultura | IQVU_3_Educacao | IQVU_4_Esportes | IQVU_5_Habitacao | IQVU_6_Infra.estrutura_urbana | IQVU_7_Meio_Ambiente | IQVU_8_Saude | IQVU_9_Servicos_Urbanos | IQVU_10_Seguranca_urbana | |
|---|---|---|---|---|---|---|---|---|---|---|
| Bairro das Industrias | 0.9940237 | 0.4939154 | 0.8196053 | 0.6728575 | 0.7488232 | 0.9257186 | 0.6376637 | 0.6611885 | 0.5322750 | 0.7540278 |
| Lindeia | 0.9469004 | 0.3287661 | 0.8208213 | 0.9020668 | 0.7179590 | 0.7485667 | 0.8585851 | 0.6617711 | 0.4771694 | 0.1821682 |
| Barreiro de Baixo | 0.9531406 | 0.5696274 | 0.9140030 | 0.8823337 | 0.7667035 | 0.8381639 | 0.7905610 | 0.7579610 | 0.6698302 | 0.1649128 |
| Barreiro de Cima | 0.8345441 | 0.2661252 | 0.7030962 | 0.9181457 | 0.6366434 | 0.7683366 | 0.9093240 | 0.5162690 | 0.3999648 | 0.1640017 |
| Jatoba | 0.8661184 | 0.3025700 | 0.8707256 | 0.9180694 | 0.5701273 | 0.7347865 | 0.9098311 | 0.5460969 | 0.4278200 | 0.1311915 |
| Cardoso | 0.9006064 | 0.4063295 | 0.8358522 | 0.8849261 | 0.7140765 | 0.7879005 | 0.8817079 | 0.6045992 | 0.4622390 | 0.2559824 |
| Olhos Dagua | 0.4756854 | 0.1059764 | 0.7606956 | 0.6571796 | 0.5299488 | 0.8076875 | 0.9058444 | 0.6197358 | 0.2325130 | 0.8817251 |
| Barreiro-Sul | 0.4258222 | 0.0989256 | 0.0177135 | 0.2009849 | 0.6188212 | 0.8255495 | 0.9683156 | 0.2874423 | 0.1400351 | 0.9943229 |
| Barro Preto | 0.9935496 | 0.8259789 | 0.8595019 | 0.5125522 | 0.9163966 | 0.9492383 | 0.7583063 | 0.8436285 | 0.8944410 | 0.5798414 |
| Centro | 0.9999978 | 0.5764110 | 0.8700022 | 0.7126057 | 0.8247964 | 0.9517579 | 0.9140403 | 0.7586674 | 0.8686578 | 0.1209365 |
# nomes das colunas selecionadas
colnames(iqvu_2016_novaserie)
## [1] "IQVU_1_Abastecimento" "IQVU_2_Cultura"
## [3] "IQVU_3_Educacao" "IQVU_4_Esportes"
## [5] "IQVU_5_Habitacao" "IQVU_6_Infra.estrutura_urbana"
## [7] "IQVU_7_Meio_Ambiente" "IQVU_8_Saude"
## [9] "IQVU_9_Servicos_Urbanos" "IQVU_10_Seguranca_urbana"
Uma breve explicação sobre a diferença:
aprendizagem supervisionada é quando a base de dados possui os rótulos (labels) daquilo que se deseja prever. Por exemplo: uma base de dados de clientes que pediram empréstimos. Nesta base terá uma coluna com os valores 1 (pagou o empréstimo) e 0 (não pagou o empréstimo), juntamente com diversos outros atributos para cada cliente como renda mensal, idade, valor que pegou de empréstimo, valor em bens de garantia, se reside em casa própria, etc. A partir destes atributos será treinado um modelo que irá “aprender” com os dados para tentar prever se um determinado cliente irá pagar ou não um empréstimo. Você usa a base rotulada para ensinar ao modelo e após o modelo ser treinado, ele poderá ser usado para tentar prever o resultado em uma base nunca vista antes, ou seja, uma base sem os rótulos (mas que contenha os mesmos atributos utilizados na etapa de treino);
aprendizagem não-supervisionada: a base utilizada não contém os rótulos. Os dados de treinamento não são rotulados. Você tem uma base (muitas vezes ela é enorme) e você não sabe ainda o que pode ser feito com ela. Um exemplo: você tem uma base com muitos dados sobre os visitantes do seu site ou os clientes que compram em seu site, e você quer usar um algoritmo para tentar detectar grupos de visitantes/clientes que sejam semelhantes. Você não informa para o algoritmo em qual grupo cada visitante/cliente pertence. O algoritmo que encontrará quais são similares.
Existem diversos algoritmos para aprendizagem supervisionada e para a não-supervisionada. Para esta última, neste trabalho, serão utilizados o k-means e o Hierarchical Clustering.
Keep in mind: há mais dados não rotulados do que rotulados, logo, há muitas possibilidades de aplicar aprendizagem não-supervisionada.
Para o uso de cluster hierárquivo e k-means, é importante que os dados estejam na mesma unidade de medida e escalonados. No caso dos indicadores utilizados para o cálculo final do IQVU, conforme o relatório de metodologia de cálculo, foi realizada a padronização de todos os indicadores. Link para a metodologia de cálculo: https://prefeitura.pbh.gov.br/sites/default/files/estrutura-de-governo/planejamento/relatorio_iqvu_2016_publicacao_versaoweb-1_0.pdf
Não sendo necessário, neste trabalho, realizar o procedimento novamente.
O agrupamento hierárquico é usado quando o número de clusters (grupos) não é conhecido previamente. É necessário realizar o cálculo da distância entre as observações. Por padrão é usado o cálculo da distância Euclidiana.
# criando o agrupamento hierárquico
iqvu_hc <- hclust(d = dist(iqvu_2016_novaserie))
# saída do algoritimo
summary(iqvu_hc)
## Length Class Mode
## merge 156 -none- numeric
## height 78 -none- numeric
## order 79 -none- numeric
## labels 79 -none- character
## method 1 -none- character
## call 2 -none- call
## dist.method 1 -none- character
A saída acima é muito técnica e confusa. O mais comum (e melhor) é usar uma árvore dendograma para representar o agrupamento criado.
É um diagrama de árvore que exibe os grupos formados pelo agrupamento de observações em cada passo e em seus níveis de similaridade. As observações são listadas no eixo horizontal e o nível de similaridade no eixo vertical (pela altura).
# árvore dendograma
plot(iqvu_hc)
Como definir através da saída acima o número de agrupamentos? Através do corte da árvore pela altura. Outra forma seria através da definição de quantos agrupamentos seriam desejados.
# árvore dendograma com corte pela altura
abline(plot(iqvu_hc), h = 1, col = "red")
A altura de cada linha horizontal no dendograma representa a distância entre os clusters. Pela linha vermelha de corte foram definidos 5 agrupamentos. Cada agrupamento pode ser atribuído à sua observação.
# atribuição do agrupamento para cada observação
cutree(iqvu_hc, h = 1)
## Bairro das Industrias Lindeia
## 1 2
## Barreiro de Baixo Barreiro de Cima
## 3 2
## Jatoba Cardoso
## 2 2
## Olhos Dagua Barreiro-Sul
## 4 5
## Barro Preto Centro
## 3 3
## Francisco Sales Savassi
## 3 3
## Prudente de Morais Santo Antonio
## 3 3
## Anchieta/Sion Serra
## 3 3
## Mangabeiras Sao Bento/Sta. Lucia
## 1 1
## Belvedere Barragem
## 1 4
## Cafezal Instituto Agronomico
## 4 3
## Boa Vista Floresta/Santa Tereza
## 2 3
## Pompeia Taquaril
## 3 2
## Santa Efigenia Baleia
## 2 4
## Mariano de Abreu Santa Ines
## 4 1
## Capitao Eduardo Ribeiro de Abreu
## 4 2
## Belmonte Gorduras
## 2 2
## Sao Paulo/Goiania Cristiano Machado
## 2 3
## Cachoeirinha Concordia
## 3 3
## Gloria Abilio Machado
## 2 2
## Jardim Montanhes Caicara
## 1 3
## Antonio Carlos Padre Eustaquio
## 3 3
## Camargos PUC
## 4 2
## Santa Maria Prado Lopes
## 1 4
## Jaqueline Isidoro Norte
## 2 4
## Furquim Werneck/ Planalto
## 5 3
## Sao Bernardo Tupi/Floramar
## 2 2
## Primeiro de Maio Jardim Felicidade
## 2 4
## Cabana Jardim America
## 2 3
## Barroca Morro das Pedras
## 3 4
## Betania Estoril/Buritis/Pilar Oeste
## 2 2
## Garcas/Braunas Santa Amelia
## 1 3
## Pampulha Jaragua
## 1 2
## Sarandi Castelo
## 3 2
## Ouro Preto Sao Francisco
## 3 1
## Confisco Mantiqueira/Sesc
## 4 2
## Serra Verde Piratininga
## 2 2
## Jardim Europa Venda Nova
## 3 3
## Ceu Azul Copacabana
## 2 2
## Sao Joao Batista
## 1
E se for desejado um número menor de agrupamentos, por exemplo 3 ao invés de 5? Basta alterar o valor de corte pela altura.
# árvore dendograma com corte pela altura
abline(plot(iqvu_hc), h = 1.4, col = "red")
Considerações sobre o que foi feito acima: se o corte do dendograma for mais alto, haverão menos agrupamentos finais (passou de 5 para 3), mas o nível de similaridade será menor. Se o corte for mais baixo, o nível de similaridade será maior, mas haverão mais agrupamentos finais.
Esta decisão sobre onde aplicar o corte recai sobre a necessidade da análise, devendo então serem feitas diversas comparações entre dendogramas com cortes diferentes, para avaliar qual agrupamento final faz mais sentido para os dados.
Além disso, por padrão o algoritmo de cluster hierárquico usa o método “complete” para determinar a distância em pares entre todas as observações no cluster. Outros métodos são o “single”, “average” e “centroid”, cada um apresentando um dendograma diferente, que devem ser comparados. A regra geral é que os métodos “complete” e “average” produzem árvores mais equilibradas e por isso são os mais utilizados.
Para esta análise, será mantido o corte pela altura, resultante em 5 agrupamentos e o método “complete”.
# inserindo na base o agrupamento pelo corte como uma coluna
iqvu_2016_novaserie$cutree_height <- cutree(iqvu_hc, h = 1)
Visualizando o resultado:
#
kable(head(iqvu_2016_novaserie))
| IQVU_1_Abastecimento | IQVU_2_Cultura | IQVU_3_Educacao | IQVU_4_Esportes | IQVU_5_Habitacao | IQVU_6_Infra.estrutura_urbana | IQVU_7_Meio_Ambiente | IQVU_8_Saude | IQVU_9_Servicos_Urbanos | IQVU_10_Seguranca_urbana | cutree_height | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Bairro das Industrias | 0.9940237 | 0.4939154 | 0.8196053 | 0.6728575 | 0.7488232 | 0.9257186 | 0.6376637 | 0.6611885 | 0.5322750 | 0.7540278 | 1 |
| Lindeia | 0.9469004 | 0.3287661 | 0.8208213 | 0.9020668 | 0.7179590 | 0.7485667 | 0.8585851 | 0.6617711 | 0.4771694 | 0.1821682 | 2 |
| Barreiro de Baixo | 0.9531406 | 0.5696274 | 0.9140030 | 0.8823337 | 0.7667035 | 0.8381639 | 0.7905610 | 0.7579610 | 0.6698302 | 0.1649128 | 3 |
| Barreiro de Cima | 0.8345441 | 0.2661252 | 0.7030962 | 0.9181457 | 0.6366434 | 0.7683366 | 0.9093240 | 0.5162690 | 0.3999648 | 0.1640017 | 2 |
| Jatoba | 0.8661184 | 0.3025700 | 0.8707256 | 0.9180694 | 0.5701273 | 0.7347865 | 0.9098311 | 0.5460969 | 0.4278200 | 0.1311915 | 2 |
| Cardoso | 0.9006064 | 0.4063295 | 0.8358522 | 0.8849261 | 0.7140765 | 0.7879005 | 0.8817079 | 0.6045992 | 0.4622390 | 0.2559824 | 2 |
Quantas observações existem em cada agrupamento?
# número de observações em cada agrupamento
table(iqvu_2016_novaserie$cutree_height)
##
## 1 2 3 4 5
## 11 28 26 12 2
O agrupamento de número 5 teve apenas 2 observações atribuídas a ele.
# atribuindo o resultado em uma variável
cluster_1 <- subset(iqvu_2016_novaserie, iqvu_2016_novaserie$cutree_height == 1)
# ordenando pelo nome da linha
agrupamento_1 <- cluster_1[order(row.names(cluster_1)), ]
# ver o resultado
kable(agrupamento_1)
| IQVU_1_Abastecimento | IQVU_2_Cultura | IQVU_3_Educacao | IQVU_4_Esportes | IQVU_5_Habitacao | IQVU_6_Infra.estrutura_urbana | IQVU_7_Meio_Ambiente | IQVU_8_Saude | IQVU_9_Servicos_Urbanos | IQVU_10_Seguranca_urbana | cutree_height | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Bairro das Industrias | 0.9940237 | 0.4939154 | 0.8196053 | 0.6728575 | 0.7488232 | 0.9257186 | 0.6376637 | 0.6611885 | 0.5322750 | 0.7540278 | 1 |
| Belvedere | 0.7851803 | 0.5508537 | 0.5730123 | 0.8903124 | 0.9316566 | 0.9140777 | 0.9059968 | 0.7418715 | 0.6068697 | 0.6227948 | 1 |
| Garcas/Braunas | 0.7614688 | 0.2350067 | 0.8795490 | 0.9340299 | 0.7337522 | 0.8301982 | 0.9494177 | 0.5335223 | 0.1640585 | 0.7767290 | 1 |
| Jardim Montanhes | 0.6173111 | 0.2275934 | 0.7921893 | 0.8554592 | 0.6722587 | 0.8511292 | 0.7612865 | 0.5975027 | 0.4359724 | 0.7067686 | 1 |
| Mangabeiras | 0.7230863 | 0.4638415 | 0.6038638 | 0.9660590 | 0.8671008 | 0.9082111 | 0.9356182 | 0.8060160 | 0.5710664 | 0.8892551 | 1 |
| Pampulha | 0.5515221 | 0.5291478 | 0.9475156 | 0.9737358 | 0.9264715 | 0.9502728 | 0.9240011 | 0.7284600 | 0.6844939 | 0.4262939 | 1 |
| Santa Ines | 0.9786539 | 0.3818987 | 0.8927593 | 0.8554525 | 0.8394216 | 0.9157393 | 0.4642200 | 0.7968892 | 0.5794750 | 0.7795067 | 1 |
| Santa Maria | 0.7110602 | 0.3156483 | 0.6869099 | 0.8077881 | 0.7632177 | 0.7609661 | 0.7283513 | 0.5693577 | 0.3799815 | 0.4748987 | 1 |
| Sao Bento/Sta. Lucia | 0.7444907 | 0.5804648 | 0.8978820 | 0.9770331 | 0.8807610 | 0.9390304 | 0.9038184 | 0.7722813 | 0.7178583 | 0.6420559 | 1 |
| Sao Francisco | 0.5515037 | 0.5399481 | 0.8426964 | 0.9338547 | 0.7600041 | 0.9288037 | 0.8893979 | 0.7196239 | 0.5857436 | 0.7572766 | 1 |
| Sao Joao Batista | 0.9145829 | 0.4036522 | 0.8495814 | 0.9401365 | 0.7044349 | 0.8179134 | 0.8175300 | 0.6576366 | 0.4670836 | 0.6371298 | 1 |
# atribuindo o resultado em uma variável
cluster_2 <- subset(iqvu_2016_novaserie, iqvu_2016_novaserie$cutree_height == 2)
# ordenando pelo nome da linha
agrupamento_2 <- cluster_2[order(row.names(cluster_2)), ]
# ver o resultado
kable(agrupamento_2)
| IQVU_1_Abastecimento | IQVU_2_Cultura | IQVU_3_Educacao | IQVU_4_Esportes | IQVU_5_Habitacao | IQVU_6_Infra.estrutura_urbana | IQVU_7_Meio_Ambiente | IQVU_8_Saude | IQVU_9_Servicos_Urbanos | IQVU_10_Seguranca_urbana | cutree_height | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Abilio Machado | 0.9734998 | 0.4854838 | 0.8147780 | 0.9413833 | 0.7819786 | 0.8445814 | 0.6469493 | 0.6894619 | 0.5680944 | 0.1747543 | 2 |
| Barreiro de Cima | 0.8345441 | 0.2661252 | 0.7030962 | 0.9181457 | 0.6366434 | 0.7683366 | 0.9093240 | 0.5162690 | 0.3999648 | 0.1640017 | 2 |
| Belmonte | 0.8295122 | 0.3381819 | 0.8519867 | 0.8840932 | 0.6446348 | 0.8206476 | 0.8678555 | 0.5883268 | 0.4584026 | 0.1663061 | 2 |
| Betania | 0.9413093 | 0.3195039 | 0.8405443 | 0.9014208 | 0.7544111 | 0.8553869 | 0.8731356 | 0.7201551 | 0.6260811 | 0.1792031 | 2 |
| Boa Vista | 0.8981078 | 0.4914209 | 0.8212915 | 0.8789920 | 0.7302955 | 0.8252745 | 0.8490291 | 0.5932995 | 0.4824516 | 0.1905214 | 2 |
| Cabana | 0.7863507 | 0.4138910 | 0.8639904 | 0.8172216 | 0.5851021 | 0.8292620 | 0.5956935 | 0.4800877 | 0.4934279 | 0.1450157 | 2 |
| Cardoso | 0.9006064 | 0.4063295 | 0.8358522 | 0.8849261 | 0.7140765 | 0.7879005 | 0.8817079 | 0.6045992 | 0.4622390 | 0.2559824 | 2 |
| Castelo | 0.7630098 | 0.3359696 | 0.4406592 | 0.4732146 | 0.8046120 | 0.7549782 | 0.7431701 | 0.5977671 | 0.3460860 | 0.2610754 | 2 |
| Ceu Azul | 0.9588997 | 0.3509141 | 0.7989949 | 0.9044878 | 0.6852481 | 0.7646762 | 0.5522460 | 0.5402633 | 0.4090779 | 0.3203826 | 2 |
| Copacabana | 0.8676903 | 0.4005744 | 0.8067668 | 0.7988668 | 0.6939586 | 0.7432359 | 0.5005933 | 0.5971319 | 0.5143232 | 0.1510525 | 2 |
| Estoril/Buritis/Pilar Oeste | 0.6837038 | 0.3944249 | 0.6260830 | 0.7337317 | 0.8607602 | 0.8591561 | 0.8816822 | 0.6586636 | 0.4804221 | 0.1466424 | 2 |
| Gloria | 0.9047842 | 0.4501561 | 0.8368803 | 0.9115514 | 0.7332127 | 0.7807105 | 0.7265501 | 0.5519619 | 0.4911089 | 0.1242860 | 2 |
| Gorduras | 0.8795156 | 0.1727768 | 0.8056813 | 0.8503076 | 0.5672978 | 0.7417621 | 0.6514509 | 0.4842543 | 0.3054814 | 0.4159908 | 2 |
| Jaqueline | 0.8238592 | 0.2592931 | 0.8320143 | 0.8724150 | 0.6278570 | 0.7592285 | 0.8619364 | 0.5511006 | 0.3618563 | 0.2365435 | 2 |
| Jaragua | 0.9517781 | 0.4847023 | 0.8225070 | 0.9145345 | 0.8235658 | 0.8594631 | 0.8267321 | 0.6740744 | 0.5973530 | 0.2056518 | 2 |
| Jatoba | 0.8661184 | 0.3025700 | 0.8707256 | 0.9180694 | 0.5701273 | 0.7347865 | 0.9098311 | 0.5460969 | 0.4278200 | 0.1311915 | 2 |
| Lindeia | 0.9469004 | 0.3287661 | 0.8208213 | 0.9020668 | 0.7179590 | 0.7485667 | 0.8585851 | 0.6617711 | 0.4771694 | 0.1821682 | 2 |
| Mantiqueira/Sesc | 0.9353637 | 0.2575361 | 0.6649298 | 0.7187046 | 0.6227716 | 0.7392965 | 0.9499386 | 0.4876864 | 0.4340744 | 0.1823367 | 2 |
| Piratininga | 0.9406978 | 0.3723830 | 0.7809607 | 0.8686506 | 0.7053868 | 0.7607905 | 0.6323343 | 0.5398868 | 0.5005000 | 0.1560404 | 2 |
| Primeiro de Maio | 0.8947101 | 0.4257411 | 0.9148778 | 0.8736305 | 0.7109410 | 0.8333391 | 0.8137010 | 0.5484198 | 0.5576173 | 0.2199243 | 2 |
| PUC | 0.9213415 | 0.5181257 | 0.8381082 | 0.8974965 | 0.7921223 | 0.8320749 | 0.7905624 | 0.6602246 | 0.5676445 | 0.2463667 | 2 |
| Ribeiro de Abreu | 0.8511489 | 0.2323307 | 0.7265139 | 0.7886317 | 0.6376218 | 0.7471503 | 0.7756472 | 0.4587350 | 0.3266782 | 0.4746670 | 2 |
| Santa Efigenia | 0.9061176 | 0.4909583 | 0.8719725 | 0.9061842 | 0.7442387 | 0.8562186 | 0.7239322 | 0.7131146 | 0.6138418 | 0.2009845 | 2 |
| Sao Bernardo | 0.9445229 | 0.3371595 | 0.6195214 | 0.8434873 | 0.6933702 | 0.7348067 | 0.4625413 | 0.5978826 | 0.5572475 | 0.2894995 | 2 |
| Sao Paulo/Goiania | 0.9400384 | 0.4366240 | 0.8183741 | 0.9368328 | 0.7266636 | 0.8294034 | 0.7675744 | 0.6478320 | 0.5499172 | 0.1091074 | 2 |
| Serra Verde | 0.8871776 | 0.2638094 | 0.8237394 | 0.8451177 | 0.5970571 | 0.7641753 | 0.8269599 | 0.5618898 | 0.3534006 | 0.5345596 | 2 |
| Taquaril | 0.7234185 | 0.2726840 | 0.6316612 | 0.9119543 | 0.3891696 | 0.7472205 | 0.9194568 | 0.2870341 | 0.4598298 | 0.3023902 | 2 |
| Tupi/Floramar | 0.9036386 | 0.3804777 | 0.7729018 | 0.8737348 | 0.6784438 | 0.7662046 | 0.6791338 | 0.5808123 | 0.4340738 | 0.1416012 | 2 |
# atribuindo o resultado em uma variável
cluster_3 <- subset(iqvu_2016_novaserie, iqvu_2016_novaserie$cutree_height == 3)
# ordenando pelo nome da linha
agrupamento_3 <- cluster_3[order(row.names(cluster_3)), ]
# ver o resultado
kable(agrupamento_3)
| IQVU_1_Abastecimento | IQVU_2_Cultura | IQVU_3_Educacao | IQVU_4_Esportes | IQVU_5_Habitacao | IQVU_6_Infra.estrutura_urbana | IQVU_7_Meio_Ambiente | IQVU_8_Saude | IQVU_9_Servicos_Urbanos | IQVU_10_Seguranca_urbana | cutree_height | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Anchieta/Sion | 0.8254867 | 0.5689505 | 0.9085236 | 0.7864645 | 0.9262417 | 0.8664499 | 0.7480130 | 0.7195866 | 0.5784633 | 0.1979387 | 3 |
| Antonio Carlos | 0.9205383 | 0.5386120 | 0.7377311 | 0.8903520 | 0.7539689 | 0.8820875 | 0.8837588 | 0.6517748 | 0.6098272 | 0.1159630 | 3 |
| Barreiro de Baixo | 0.9531406 | 0.5696274 | 0.9140030 | 0.8823337 | 0.7667035 | 0.8381639 | 0.7905610 | 0.7579610 | 0.6698302 | 0.1649128 | 3 |
| Barro Preto | 0.9935496 | 0.8259789 | 0.8595019 | 0.5125522 | 0.9163966 | 0.9492383 | 0.7583063 | 0.8436285 | 0.8944410 | 0.5798414 | 3 |
| Barroca | 0.9463636 | 0.5193553 | 0.9236061 | 0.6537817 | 0.8941640 | 0.9078114 | 0.6199052 | 0.7556119 | 0.6764665 | 0.1329227 | 3 |
| Cachoeirinha | 0.8667369 | 0.5414553 | 0.7830101 | 0.7780129 | 0.7547446 | 0.8705572 | 0.6298707 | 0.6299196 | 0.5409980 | 0.2791227 | 3 |
| Caicara | 0.9167773 | 0.5130323 | 0.8266291 | 0.7352628 | 0.8265363 | 0.8446635 | 0.5933798 | 0.6720107 | 0.6234435 | 0.2017972 | 3 |
| Centro | 0.9999978 | 0.5764110 | 0.8700022 | 0.7126057 | 0.8247964 | 0.9517579 | 0.9140403 | 0.7586674 | 0.8686578 | 0.1209365 | 3 |
| Concordia | 0.9327303 | 0.5453802 | 0.8258463 | 0.9075629 | 0.8096427 | 0.9296516 | 0.6455097 | 0.6147117 | 0.5723148 | 0.4218636 | 3 |
| Cristiano Machado | 0.9423584 | 0.5059781 | 0.8809371 | 0.8801363 | 0.8499148 | 0.8391200 | 0.7678667 | 0.7150126 | 0.6137362 | 0.0809773 | 3 |
| Floresta/Santa Tereza | 0.9718088 | 0.6539600 | 0.9453499 | 0.8865079 | 0.8563911 | 0.9236339 | 0.6684365 | 0.7561517 | 0.6825058 | 0.1967615 | 3 |
| Francisco Sales | 0.9740415 | 0.8482621 | 0.9561780 | 0.9044093 | 0.9093512 | 0.9503037 | 0.8179241 | 0.8201389 | 0.8588730 | 0.5004115 | 3 |
| Instituto Agronomico | 0.8983944 | 0.4962737 | 0.8494417 | 0.8157666 | 0.8406651 | 0.8782894 | 0.9371172 | 0.6621370 | 0.5629836 | 0.2035213 | 3 |
| Jardim America | 0.9166687 | 0.5374231 | 0.9048711 | 0.8019431 | 0.7866052 | 0.8642931 | 0.7212816 | 0.6772230 | 0.6546316 | 0.0760769 | 3 |
| Jardim Europa | 0.9313161 | 0.4152176 | 0.8419118 | 0.8678828 | 0.7375583 | 0.8017025 | 0.6054388 | 0.6468581 | 0.5546888 | 0.3529627 | 3 |
| Ouro Preto | 0.8682422 | 0.4372728 | 0.8501350 | 0.7460260 | 0.8385686 | 0.8639386 | 0.8604192 | 0.7038839 | 0.5465371 | 0.3454873 | 3 |
| Padre Eustaquio | 0.9510860 | 0.5724890 | 0.9292558 | 0.8064605 | 0.8236406 | 0.8775041 | 0.9036199 | 0.7397085 | 0.6599778 | 0.0958273 | 3 |
| Planalto | 0.9350860 | 0.4948973 | 0.8548511 | 0.9651712 | 0.8228557 | 0.8784091 | 0.8834335 | 0.6903892 | 0.5805646 | 0.3814806 | 3 |
| Pompeia | 0.9311905 | 0.5083748 | 0.8992644 | 0.9249300 | 0.8040566 | 0.9109088 | 0.9185374 | 0.6764250 | 0.5916930 | 0.4485415 | 3 |
| Prudente de Morais | 0.9021083 | 0.6749044 | 0.9035871 | 0.8443336 | 0.8939687 | 0.9116258 | 0.7322147 | 0.7321983 | 0.6882467 | 0.4979945 | 3 |
| Santa Amelia | 0.9018512 | 0.4856391 | 0.9096047 | 0.7879974 | 0.8452332 | 0.8125211 | 0.9343929 | 0.6970171 | 0.6152155 | 0.1905722 | 3 |
| Santo Antonio | 0.9081489 | 0.7438807 | 0.9087191 | 0.5481197 | 0.9261440 | 0.8871531 | 0.5899393 | 0.8194126 | 0.5782301 | 0.2969755 | 3 |
| Sarandi | 0.9026992 | 0.5251789 | 0.8185930 | 0.7688139 | 0.7630036 | 0.7742018 | 0.6451983 | 0.6090351 | 0.5496841 | 0.3519339 | 3 |
| Savassi | 0.9825703 | 0.8476168 | 0.9283904 | 0.6551533 | 0.9578103 | 0.9294726 | 0.6858712 | 0.7769947 | 0.7448660 | 0.0902368 | 3 |
| Serra | 0.9054386 | 0.6560271 | 0.9037228 | 0.6451528 | 0.9234099 | 0.8610658 | 0.6558719 | 0.8161086 | 0.5511212 | 0.3595748 | 3 |
| Venda Nova | 0.9892241 | 0.6569844 | 0.9225500 | 0.6975516 | 0.7692615 | 0.8795304 | 0.8990194 | 0.4984533 | 0.6828615 | 0.3634217 | 3 |
# atribuindo o resultado em uma variável
cluster_4 <- subset(iqvu_2016_novaserie, iqvu_2016_novaserie$cutree_height == 4)
# ordenando pelo nome da linha
agrupamento_4 <- cluster_4[order(row.names(cluster_4)), ]
# ver o resultado
kable(agrupamento_4)
| IQVU_1_Abastecimento | IQVU_2_Cultura | IQVU_3_Educacao | IQVU_4_Esportes | IQVU_5_Habitacao | IQVU_6_Infra.estrutura_urbana | IQVU_7_Meio_Ambiente | IQVU_8_Saude | IQVU_9_Servicos_Urbanos | IQVU_10_Seguranca_urbana | cutree_height | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Baleia | 0.4610538 | 0.3038133 | 0.8786453 | 0.9647356 | 0.5730626 | 0.8599694 | 0.8760913 | 0.6701204 | 0.5343595 | 0.8849674 | 4 |
| Barragem | 0.4077598 | 0.3457075 | 0.6458448 | 0.7571270 | 0.2878585 | 0.7549146 | 0.6905391 | 0.6181018 | 0.4359088 | 0.6869664 | 4 |
| Cafezal | 0.5516413 | 0.3667760 | 0.7155701 | 0.9059660 | 0.2990562 | 0.7312854 | 0.5676512 | 0.5921870 | 0.4693093 | 0.5247392 | 4 |
| Camargos | 0.5038912 | 0.3300256 | 0.2923326 | 0.7884513 | 0.6704788 | 0.8957287 | 0.9394320 | 0.4654419 | 0.3718515 | 0.9387355 | 4 |
| Capitao Eduardo | 0.4318622 | 0.2342536 | 0.8086076 | 0.9292884 | 0.4022220 | 0.7287818 | 0.9680175 | 0.5909471 | 0.2961043 | 0.8794761 | 4 |
| Confisco | 0.4163964 | 0.1514995 | 0.6440894 | 0.9559487 | 0.4206272 | 0.7794183 | 0.8899061 | 0.6219845 | 0.3202651 | 0.9828316 | 4 |
| Isidoro Norte | 0.8023783 | 0.2937840 | 0.5747240 | 0.9750104 | 0.4954363 | 0.7364993 | 0.9683156 | 0.5847467 | 0.4120175 | 0.8175961 | 4 |
| Jardim Felicidade | 0.4189705 | 0.2276588 | 0.4749714 | 0.8931706 | 0.4162574 | 0.7824557 | 0.7915191 | 0.5586670 | 0.2754257 | 0.6657667 | 4 |
| Mariano de Abreu | 0.5304219 | 0.2169827 | 0.3479716 | 0.9664135 | 0.5540955 | 0.8764586 | 0.6484553 | 0.4091626 | 0.3993546 | 0.9915918 | 4 |
| Morro das Pedras | 0.8086911 | 0.3595931 | 0.5316435 | 0.9767622 | 0.4228317 | 0.8213740 | 0.7083808 | 0.5420187 | 0.4371763 | 0.6677154 | 4 |
| Olhos Dagua | 0.4756854 | 0.1059764 | 0.7606956 | 0.6571796 | 0.5299488 | 0.8076875 | 0.9058444 | 0.6197358 | 0.2325130 | 0.8817251 | 4 |
| Prado Lopes | 0.8850334 | 0.4795869 | 0.4019409 | 0.9219496 | 0.5168018 | 0.7035509 | 0.6374866 | 0.3411722 | 0.5314683 | 0.9536031 | 4 |
# atribuindo o resultado em uma variável
cluster_5 <- subset(iqvu_2016_novaserie, iqvu_2016_novaserie$cutree_height == 5)
# ordenando pelo nome da linha
agrupamento_5 <- cluster_5[order(row.names(cluster_5)), ]
# ver o resultado
kable(agrupamento_5)
| IQVU_1_Abastecimento | IQVU_2_Cultura | IQVU_3_Educacao | IQVU_4_Esportes | IQVU_5_Habitacao | IQVU_6_Infra.estrutura_urbana | IQVU_7_Meio_Ambiente | IQVU_8_Saude | IQVU_9_Servicos_Urbanos | IQVU_10_Seguranca_urbana | cutree_height | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Barreiro-Sul | 0.4258222 | 0.0989256 | 0.0177135 | 0.2009849 | 0.6188212 | 0.8255495 | 0.9683156 | 0.2874423 | 0.1400351 | 0.9943229 | 5 |
| Furquim Werneck/ | 0.2822967 | 0.1589832 | 0.0164309 | 0.6312264 | 0.4744773 | 0.7533880 | 0.9682167 | 0.4434070 | 0.2549754 | 0.7700664 | 5 |
Como o k-means funciona? O algoritmo calcula o centro de cada um dos subgrupos (“centro” é a posição média de todos os pontos do subgrupo).
Cada ponto nos dados é atribuído ao cluster de centro mais próximo (valor central), através de um processo de iteração.
Quando nenhum ponto mudar de atribuição, o algoritmo k-means termina a tarefa.
Também é possível determinar quando o k-means irá parar definindo um certo número de iterações ou se os centros de cluster se moverem menos que alguma distância.
Importante dizer que o k-means tem um componente aleatório e é executado várias vezes até encontrar a melhor solução selecionada entre as várias execuções.
# base para o k-means (mesma base mas sem a coluna de 'cutree_height')
x <- iqvu_2016_novaserie[, -11]
Diferente do agrupamento hierárquico, no k-means você precisa definir antes quantos grupos deseja ver. Esta definição, na maioria das vezes, é decorrente do conhecimento dos dados, da regra de negócio existente.
Quando não há uma regra definida, por vezes é realizado o procedimenteo de tentativa e erro (não é a melhor alternativa). São fornecidos diferentes valores de agrupamentos e é avaliado o resultado da soma total de quadrados dentro do cluster (total within cluster sum of squares).
Mas o quê isso significa? Isso é uma medida de qualidade do modelo para determinar o melhor resultado das várias execuções.
O melhor modelo será aquele com o menor número, menor erro (lowest error), de total within cluster sum of squares error.
Então, se o número de clusters não é conhecido e precisa ser determinado, o algoritmo terá que ser executado diversas vezes, cada vez com um número diferente de clusters, e observar como a medida de qualidade do modelo muda com o número de clusters.
# set seed (configurar a semente) : importante para a reprodutibilidade
# (lembre-se, k-means trabalha com iterações, várias execuções aleatórias) -
# Explicando: é uma prática para você ter sempre o mesmo resultado.
set.seed(1)
# iniciar a 'total within sum of squares error' (wss):
wss <- 0
# criar um for para executar com 1 até 15 cluster centers
for (i in 1:15) {
km.out <- kmeans(x, centers = i, nstart = 20) #nstart = repetições do algoritmo
# salvar a soma total de quadrados dentro do cluster na variável wss
wss[i] <- km.out$tot.withinss
}
Como explicado antes, definir o número de agrupamentos por tentativa e erro não é a melhor abordagem.
A abordagem ideal é executar k-means com 1 à até algum número de clusters, registrando a soma total de quadrados no cluster para cada número de clusters (isso já foi feito, no “for” anterior).
E para identificar o número ideal de clusters, é plotado o gráfico abaixo contendo o número de clusters no eixo x e o total da soma de quadrados dentro do cluster no eixo vertical.
O gráfico é chamado de “scree plot” ou “elbow plot”. Veja que há um cotovelo (elbow) no local onde a soma dos quadrados do cluster diminui muito mais lentamente com a adição de outro cluster.
# gráfico da total within sum of squares x número de clusters
plot(1:15, wss, type = "b", xlab = "Number of Clusters", ylab = "Within groups sum of squares")
Neste caso, o número de clusters ideal está entre 2 e 3.
Será usado o número de clusters = 3, a partir do gráfico anterior.
# selecionar o número de clusters
k = 3
# set seed
set.seed(2)
# construir o modelo
km.out <- kmeans(x, centers = k, nstart = 20, iter.max = 50) #iter.max é o número máximo de iterações permitidas
# ver o resultado do modelo
km.out
## K-means clustering with 3 clusters of sizes 27, 18, 34
##
## Cluster means:
## IQVU_1_Abastecimento IQVU_2_Cultura IQVU_3_Educacao IQVU_4_Esportes
## 1 0.8689847 0.3460800 0.7736026 0.8491134
## 2 0.5586263 0.2855531 0.5683044 0.8452009
## 3 0.9130249 0.5693975 0.8674249 0.8107762
## IQVU_5_Habitacao IQVU_6_Infra.estrutura_urbana IQVU_7_Meio_Ambiente
## 1 0.6775123 0.7806251 0.7644962
## 2 0.5397273 0.8097447 0.8368829
## 3 0.8397975 0.8858685 0.7655401
## IQVU_8_Saude IQVU_9_Servicos_Urbanos IQVU_10_Seguranca_urbana
## 1 0.5657696 0.4559631 0.2572400
## 2 0.5556555 0.3815336 0.8205629
## 3 0.7126979 0.6371787 0.3161038
##
## Clustering vector:
## Bairro das Industrias Lindeia
## 3 1
## Barreiro de Baixo Barreiro de Cima
## 3 1
## Jatoba Cardoso
## 1 1
## Olhos Dagua Barreiro-Sul
## 2 2
## Barro Preto Centro
## 3 3
## Francisco Sales Savassi
## 3 3
## Prudente de Morais Santo Antonio
## 3 3
## Anchieta/Sion Serra
## 3 3
## Mangabeiras Sao Bento/Sta. Lucia
## 2 3
## Belvedere Barragem
## 3 2
## Cafezal Instituto Agronomico
## 2 3
## Boa Vista Floresta/Santa Tereza
## 1 3
## Pompeia Taquaril
## 3 1
## Santa Efigenia Baleia
## 3 2
## Mariano de Abreu Santa Ines
## 2 3
## Capitao Eduardo Ribeiro de Abreu
## 2 1
## Belmonte Gorduras
## 1 1
## Sao Paulo/Goiania Cristiano Machado
## 1 3
## Cachoeirinha Concordia
## 3 3
## Gloria Abilio Machado
## 1 3
## Jardim Montanhes Caicara
## 2 3
## Antonio Carlos Padre Eustaquio
## 3 3
## Camargos PUC
## 2 3
## Santa Maria Prado Lopes
## 1 2
## Jaqueline Isidoro Norte
## 1 2
## Furquim Werneck/ Planalto
## 2 3
## Sao Bernardo Tupi/Floramar
## 1 1
## Primeiro de Maio Jardim Felicidade
## 1 2
## Cabana Jardim America
## 1 3
## Barroca Morro das Pedras
## 3 2
## Betania Estoril/Buritis/Pilar Oeste
## 1 1
## Garcas/Braunas Santa Amelia
## 2 3
## Pampulha Jaragua
## 3 3
## Sarandi Castelo
## 3 1
## Ouro Preto Sao Francisco
## 3 2
## Confisco Mantiqueira/Sesc
## 2 1
## Serra Verde Piratininga
## 1 1
## Jardim Europa Venda Nova
## 1 3
## Ceu Azul Copacabana
## 1 1
## Sao Joao Batista
## 1
##
## Within cluster sum of squares by cluster:
## [1] 2.415299 4.320440 3.734326
## (between_SS / total_SS = 50.3 %)
##
## Available components:
##
## [1] "cluster" "centers" "totss" "withinss" "tot.withinss"
## [6] "betweenss" "size" "iter" "ifault"
Veja que foram criados 3 agrupamentos de tamanhos 27, 18 e 34
Podem ser visualizados através do gráfico abaixo:
fviz_cluster(km.out, data = x, repel = TRUE, labelsize = 16, pointsize = 3)
Veja no gráfico que algumas UP’s, como exemplo Cafezal, foram atribuídas à um grupo mas estão próximas do valor central de outro grupo. Cafezal está no grupo 2 mas poderia também estar no grupo 1.
Abaixo as médias por variável para cada grupo:
kable(aggregate(x, by = list(cluster = km.out$cluster), mean))
| cluster | IQVU_1_Abastecimento | IQVU_2_Cultura | IQVU_3_Educacao | IQVU_4_Esportes | IQVU_5_Habitacao | IQVU_6_Infra.estrutura_urbana | IQVU_7_Meio_Ambiente | IQVU_8_Saude | IQVU_9_Servicos_Urbanos | IQVU_10_Seguranca_urbana |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | 0.8689847 | 0.3460800 | 0.7736026 | 0.8491134 | 0.6775123 | 0.7806251 | 0.7644962 | 0.5657696 | 0.4559631 | 0.2572400 |
| 2 | 0.5586263 | 0.2855531 | 0.5683044 | 0.8452009 | 0.5397273 | 0.8097447 | 0.8368829 | 0.5556555 | 0.3815336 | 0.8205629 |
| 3 | 0.9130249 | 0.5693975 | 0.8674249 | 0.8107762 | 0.8397975 | 0.8858685 | 0.7655401 | 0.7126979 | 0.6371787 | 0.3161038 |
Observe que ambos geraram um número de agrupamentos diferente: 5 no hierárquico e 3 no k-means.
Cada modelo assume suposições diferentes sobre os dados, gerando clusters diferentes. No entanto, observe em ambos que as UP’s Furquim Werneck e Barreiro-sul são aquelas com a menor similaridade entre as demais UP’s. No agrupamento hierárquico elas ficaram em um grupo único, já no k-means, apesar de terem ficado no cluster 2, note o quanto elas estão longe do centro do cluster.
É possível comparar ambos os algoritmos, verificando quantas observações foram atribuídas em cada grupo.
table(km.out$cluster, cutree(iqvu_hc, h = 1))
##
## 1 2 3 4 5
## 1 2 24 1 0 0
## 2 4 0 0 12 2
## 3 5 4 25 0 0
Acima, nas linhas é mostrado o k-means (grupos 1, 2 e 3), nas colunas o agrupamento hierárquico, com seus 5 grupos.
Não há um consenso a respeito sobre qual método produz os melhores clusters. O trabalho do analista em um agrupamento não-supervisionado é o de observar os clusters que foram atribuídos e fazer o julgamento de qual método irá proporcionar maior intuição/conhecimento dos dados e melhor resultado baseado no problema que se quer resolver.
Relembre o objetivo do IQVU: delimitar as áreas prioritárias para os investimentos públicos e a melhor compreensão da distribuição dos bens e serviços públicos e privados entre as regiões da cidade.
UP’s Furquim Werneck e Barreiro-sul poderiam ser consideradas prioritárias para novos investimentos públicos.
UP’s atribuídas ao cluster 3, pelo k-means, são aquelas em que a média do cluster é praticamente a maior em todos os indicadores do IQVU, ao comparar com os clusters 1 e 2. Essa informação pode auxiliar no direcionamento de novos investimentos. Exemplo: se na média as UP’s deste cluster possuem os maiores valores para o indicador de habitação, novos investimentos nessa área deveriam ser direcionados, em sua maior parte, para as UP’s dos outros clusters.
Por outro lado, observando a média do indicador “IQVU_10_Seguranca_urbana”, observe que o cluster 3, neste item, não possui a melhor média do indicador. Investimentos na área de segurança urbana, antes de serem realizados, poderiam utilizar esta análise para avaliar em quais UP’s (do cluster 3 e 1) deveriam ser priorizados.
Estes foram apenas alguns insights a partir da criação dos agrupamentos. O foco é, a partir do uso dos algoritmos, utilizar medidas objetivas ao invés de subjetivas para direcionar decisões de políticas públicas.
Há um meio de medir quão bem as observações se encaixam em seu cluster correspondente? Sim. Isso pode ser feito através do método Silhouette. Este também pode ser utilizado para estimar o valor de k.
Basicamente o método Silhouette calcula a distância dentro do cluster e a distância entre os clusters, para cada observação.
# gerar um modelo k-means usando a função pam() com k = 2
pam_k2 <- pam(x, k = 2)
# plotar o silhouette visual para o modelo pam_k2
plot(silhouette(pam_k2))
Atenção em “Average silhouette width”: quanto mais próximo de 1 melhor as observações individuais correspondem aos seus clusters respectivos (dizendo de outra forma: as observações estão no melhor cluster, no cluster correto). Se o resultado for 0 significa que os agrupamentos estão na fronteira, on border, entre os clusters (uma observação pode pertencer à mais de 1 cluster). Se o resultado for menor que zero, quanto mais próximo de -1 for o resultado, significa que os agrupamentos não estão confiáveis, não são bons agrupamentos.
Vamos gerar um agrupamento com k=3 usando o pam() e verificar se melhora a qualidade do average silhouette width.
# gerar o modelo k-means usando a função pam() com k=3
pam_k3 <- pam(x, k = 3)
# # plotar o silhouette visual para o modelo pam_k2
plot(silhouette(pam_k3))
O average silhouette diminuiu. Observe que mais observações receberam um valor menor que 0.
No hierarchical clustering, do post anterior, utilizei 5 agrupamentos. Vamos ver como o seria o resultado do average silhouette usando k = 5:
# gerar o modelo k-means usando a função pam() com k=5
pam_k5 <- pam(x, k = 5)
# # plotar o silhouette visual para o modelo pam_k5
plot(silhouette(pam_k5))
O resultado não melhorou. Algumas observações, conforme o plot acima, ainda podem ser atribuídas à mais de um grupo.
Vamos usar o método Silhouette para encontrar o melhor k (número de agrupamentos):
# usando map_dbl() para rodar vários modelos com vários números de k
sil_width <- map_dbl(2:10, function(k) {
model <- pam(x = x, k = k)
model$silinfo$avg.width
})
# gerar um DF contendo ambos valores k e sil_width
sil_df <- data.frame(k = 2:10, sil_width = sil_width)
# plotar o resultado
sil_df
## k sil_width
## 1 2 0.3726899
## 2 3 0.1994117
## 3 4 0.2009418
## 4 5 0.1898774
## 5 6 0.1859882
## 6 7 0.1795854
## 7 8 0.1835998
## 8 9 0.1454576
## 9 10 0.1873415
Veja acima que para cada valor de k foi gerado também o valor correspondente de sil_width (average silhouette width = largura média).
Agora vamos plotar a relação entre k e sil_width:
ggplot(sil_df, aes(x = k, y = sil_width)) + geom_line() + scale_x_continuous(breaks = 2:10)
O que deve ser observado aqui? O número de k que apresenta o maior valor de sil_width. Neste caso o maior valor é k=2, logo, o número ideal de agrupamentos através do método silhouette é k = 2. Com k = 2 algumas observações poderiam estar em 2 agrupamentos. No post anterior, com k=3 no modelo k-means, algumas observações também podem estar em mais de um agrupamento.
Vamos gerar uma visualização, para o modelo k-means com k = 2:
# construir um model k-means com k = 2
km.out_k2 <- kmeans(x, centers = 2, nstart = 20, iter.max = 50) #iter.max é o número máximo de iterações permitidas
fviz_cluster(km.out_k2, data = x, repel = TRUE, labelsize = 16, pointsize = 3)
Perceba que assim como no silhouette, com k=2, algumas observações podem pertencer a mais de um agrupamento.
Então, usando o algoritmo de k-means é possível utilizar dois métodos para definir o número ideal de agrupamentos: 1) elbow method (feito no post anterior) e 2) silhouette method descrito neste post. Reforçando que o silhouette também pode ser usado para definir quão bem as suas observações estão em cada grupo/cluster.
No meu post anterior, na conclusão, eu escrevi: “O foco é, a partir do uso dos algoritmos, utilizar medidas objetivas ao invés de subjetivas para direcionar decisões de políticas públicas.” Bem, preciso destacar que algoritmos de agrupamento possuem uma característica de subjetividade. As técnicas para a definição ideal dos agrupamentos servem como uma medida objetiva, no entanto, é muito importante o conhecimento prévio dos dados, a análise dos agrupamentos realizados e o problema que se busca resolver com o agrupamento.
“Generating clusters is a science, but interpreting them is an art.” from Cluster Analysis in R DataCamp course