Agrupamento de Textos com K-Means

Agrupando hinos nacionais com aprendizado não supervisionado

Lucas de Sá
Bexs.IO
8 min readDec 17, 2019

--

A versão em inglês deste artigo está disponível aqui. O jupyter notebook com toda análise está acessível neste link e o mapa final da análise esta aqui!

Uma idéia me ocorreu ouvindo um episódio de um podcast do jornal Nexo. Num momento do podcast os participantes comentam que os hinos nacionais podem ser divididos em grupos, sendo alguns hinos de caráter bélico, como o da França, outros saudando a natureza local, como o do Brasil, e assim por diante. Como ninguém hoje em dia tem tempo de classificar um monte de hinos nacionais, vamos ver como podemos fazer isso usando um algoritmo de aprendizado não supervisionado.

Essa análise será restringida aos continentes da Europa, América Latina e America do Norte, e as letras dos hinos estão em inglês. O código e o dataset, montado por mim, estao disponíveis no meu github.

Introdução

A idéia deste artigo é entender como representar um conjunto de dados textuais (neste caso os hinos nacionais) para que eles sejam usados como entrada para o algoritmo K-Means. Como estamos lidando com países é interessante visualizar seus resultados em um mapa interativo usando Folium.

O processo foi dividido nas seguintes etapas:

  1. Pré-processamento do Conjunto de Dados
  2. Extração de Features com TF-IDF
  3. Aplicação do K-Means e Análise dos Agrupamentos
  4. Visualização dos Grupos em um Mapa com Folium

Pré-processamento do Conjunto de Dados

Antes do pré-processar o conjunto de dados, é importante saber como ele está estruturado. Carregar o dataset e selecionar os continentes que queremos utilizar é bem simples:

É importante notar que além do hino (coluna ‘anthem’) e do país (coluna ‘country’), as colunas ‘alpha-2’ e ‘alpha-3’ representa os ISO-Codes dos diferentes países, que são códigos identificadores de cada país.

Agora é interessante saber a disposição dos hinos. Ao investigar o hino da Hungria fica claro que seu texto possui ruídos. Hinos nacionais tendem a fazer menção a termos locais que utilizam caracteres não representados em UTF-8, gerando “palavras” estranhas que precisam ser removidas.

Agora que sabemos o formato do nosso conjunto de documentos, vamos passar a chamá-lo de corpus. A etapa de pré-processamento se refere a série de tratamentos que devem ser feitos no corpus para que ele possa ser bem representado por um modelo estatístico antes de ser alimentado ao algoritmo de agrupamento K-Means. A rotina de pré-processamento pode ser divida em:

  1. Tokenização do corpus, ou seja, quebrar o conjunto de hinos nacionais em palavras individuais.
  2. Remoção de stop words, que são palavras comuns (a, the, not, etc) que não contribuem para o significado semântico do texto.
  3. Remoção de ruído do texto, como palavras com caracteres especiais, palavras com simbolos não ASCII, palavras juntas de números, etc. Ou seja, tudo que não dê para ser reconhecido como uma palavra.
  4. Aplicação de stemming, que reduz uma palavra para a sua raiz. Ie: [consultant, consulting, consultants] -> consult

Abaixo estão as funções auxiliares que removem uma lista de palavras (como stop words) do texto, aplicam stemming e removem palavras com 2 ou menos letras e 21 ou mais letras (pois a palavra comum mais longa da língua inglesa é ‘ Incomprehensibilities’, com 21 letras).

Agora definimos a função de processamento principal, que usa expressões regulares para remoção de ruído do texto e utiliza as funções definidas acima.

Agora o hino nacional da Hungria fica com essa cara!

Extração de Features com TF-IDF

A fase de pré-processamento foi realizada para que esta etapa gere os melhores resultados. Aqui busca-se representar o quanto uma palavra é importante num conjunto de documentos para que estes dados estejam prontos para serem usados num algoritmo. Este processo de mapeamento de dados textuais em vetores é chamado de feature extraction.

TF-IDF, abreviação de Term Frequency-Inverse Document Frequency (Frequencia de Termo-Frequencia Inversa de Documento), é uma estatística numérica que busca refletir a importância de uma palavra num corpus, onde um termo com peso alto é considerado relevante num corpus.

Este método funciona, simplificadamente, através do aumento do peso de importância de uma palavra quando ela aparece muitas vezes em um documento, e diminuindo o peso desta palavra quando ela é comum em muitos documentos.

Esta estatística é dividida em duas etapas:

. Term Frequency — TF

A frequência de termo tf(t, d) mensura o quão frequentemente um termo t ocorre num documento d, dando um peso de maior a termos frequentes.

. Inverse Document Frequency — IDF

A frequência inversa de documento idf(t, D) mensura a importância de um termo t num conjunto de documentos D. Essa estatística tende a diminuir o peso de importância de termos frequentes porém com pouca importância e aumentar o peso de termos raros que dão bastante significado a um texto.

A multiplicação de tf(t, d) por idf(t, D) nos gera o score tf-idf de um termo.

Apesar de toda a matemática, é bem fácil aplicar o TF-IDF usando o sklearn!

As palavras com maior peso por documento

Aplicação do K-Means e Análise dos Agrupamentos

O K-Means é um dos algoritmos de machine learning mais simples e populares que existe. Ele é considerado de aprendizado não supervisionado pois não precisa que os dados sejam rotulados anteriormente, no nosso caso quer dizer que nenhum texto pertence a nenhuma classe ou grupo. Ele é um algoritmo de clustering (agrupamento ou aglomeração) que separa um conjunto dados em um número K pré definido de clusters (grupos).

A idéia por trás deste algoritmo é que sua divisão de grupos seja feita por K centróides, onde um centróide é um ponto que representa o centro de um grupo. Este algoritmo funciona de forma iterativa, onde os centróides são inicialmente colocados de forma aleatória no espaço vetorial do conjunto de dados e movem-se para o centro dos pontos mais próximos deles. A cada nova iteração é recalculada a distância entre os centróides e os pontos e eles se movem novamente para o centro dos seus pontos mais próximos. O algoritmo é finalizado quando a posição ou os grupos não são mais alterados ou quando a distância da mudança dos centróides atinge um limiar pré definido.

Visualização do K-Means. Imagem extraída deste artigo.

Como inicialmente nao sabe-se o número ideal de grupos, rodamos o K-Means com 2 até 7 grupos e selecionaremos o melhor resultado.

Com o resultado de diferentes agrupamentos, precisa-se agora escolher o melhor número de clusters, que é uma análise muito subjetiva. Há medidas de desempenho, como o Elbow Method e média Silhouette, que trazem insights para essa escolha. Eu recomendo este artigo escrito por uma coléga para se aprofundar nestes métodos.

Para a escolha do melhor número de clusters analisou-se os distintos clusters em cada agrupamento através de gráficos de palavras mais dominantes em cada grupo. Concluiu-se que os grupos que mais faziam sentido entre si foi quando eles foram separados em 5 grupos.

best_result = 5
kmeans = kmeans_results.get(best_result)
Palavras mais dominantes por cluster
Word Clouds dos agrupamentos

Ao examinar os clusters, fica claro o tema que as palavras inferem em cada grupo. No Cluster 0, por exemplo, há um carater mais positivo nas palavras “heart”, “beauti” e “mother” (coração, belo e mãe), enquanto no Cluster 3 é mais bélico com os termos “war”, “blood”, “glori” (guerra, sangue e glória).

Agora vamos atribuir as labels resultantes do K-Means em seu respectivo país.

labels = kmeans.labels_ 
data['label'] = labels
data.head()

Visualização dos Grupos em um Mapa com Folium

A ideia agora é colorir cada país com a cor de seu respectivo grupo em um mapa, também conhecido como mapa coroplético. Isso possível com o uso da biblioteca Folium.

Primeiro vamos criar uma paleta de 5 cores, uma para cada cluster.

Agora precisamos delimitar as coordenadas de cada país no mapa. Existe um arquivo Json que identifica cada país pelo seu ISO-Code de 3 letras e possui os poligonos que traçam os limites cada país.

Dessa forma é simples fazer um merge dos labels dos países com os seus poligonos do arquivo Json pelo ISO-Code de cada país!

Com poligonos e as labels que delimitam os países associados no dataframe acima, o que resta agora é criar uma instância de um mapa com Folium, desenhar os poligonos e pintar países com a sua respectiva cor.

Você pode interagir com o mapa aqui

As cores representam os seguintes clusters:

  • Cluster 0 — Vermelho, de palavras positivas que saudam a terra natal
  • Cluster 1— Amarelo, de palavras que saudam a pátria e a liberdade
  • Cluster 2 — Verde, termos de amor a terra natal e de tom religioso
  • Cluster 3 — Azul, de termos que remetem a guerra
  • Cluster 4 — Magenta, termos que se encaixam nos outros clusters

Conclusão

Análise de clusters de um conjunto de textos é um processo que envolve Natural Languge Processing (NLP) e o uso de um algoritmo de agrupamento. Este metodo de estruturar textos não estruturados pode ser aplicado em diversos segmentos, como segmentação de pesquisa, análise de feedback, etc.

Dentro do K-Means há outras variáveis que influenciam no resultado do algoritmo, como diferentes métricas de distância (distância euclidiana, manhattan, similaridade cosseno, etc), a posição inicial dos centróides, além da análise dos agrupamentos ser algo completamente subjetivo.

É importante lembrar que o K-Means não é a única maneira de agrupar dados, existem outras alternativas como algoritmos de agrupamento hierárquico.

--

--

Lucas de Sá
Bexs.IO
Editor for

Stockholm based Data Engineer and Functional Programming Practioner.