IQVU da cidade de Belo Horizonte

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.

Objetivo do IQVU

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.

Resultado do índice

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.

Estatísticas

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

Objetivo desta análise

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.

Carregamento dos dados

# 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 = ";")

Descrição dos dados

# exibir o número de linhas e colunas
dim(iqvu)
## [1] 934  79

O arquivo contém 934 linhas e 79 colunas.

Ver uma parte dos dados

# 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"

Aprendizagem supervisionada X aprendizagem não-supervisionada

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.

Escalonamento dos dados

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.

Agrupamento hierárquico

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.

Árvore dendograma

É 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.

Agrupamento 1

# 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

Agrupamento 2

# 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

Agrupamento 3

# 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

Agrupamento 4

# 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

Agrupamento 5

# 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

K-means

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]

Número de clusters

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
}

Scree plot

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.

Criação do modelo K-means

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"

Visualização do modelo

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

Agrupamento hierárquico X k-means

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.

Qual modelo escolher?

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.

Conclusão

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.

Bônus

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.

Recado final

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