[1/3] Classificando textos: Vetorização

dekzin AI
Computando Arte
Published in
7 min readFeb 3, 2021

Você ja sabe um pouco sobre aprendizado de máquina? Já usa pacotes como pandas, numpy e scikit-learn? E quer aprender como trabalhar com textos?

Então esse post é pra você. Nessa série de 3 partes vamos percorrer o mundo da classificação textual, em específico a análise de sentimento, passando por abordagens mais simples até as mais recentes.

Fonte: Wikimedia Commons.

Introdução

Trabalhar com modelos para texto é diferente de quando queremos modelar um conjunto de dados estruturado com variáveis que possuem valores numéricos. Quando falamos de textos precisamos fazer com que a máquina consiga interpretar o texto, o que, de forma simplificada, significa representar textos de forma numérica. Dessa forma, o grande desafio quando trabalhamos com textos é:

“Como representar os textos de forma que um modelo seja capaz de identificar padrões?”

As formas mais básicas de se criar essas representações, principalmente para quem está começando a lidar com textos, são as vetorizações por frequência. Ou seja, utilizar informações de quantidade de aparição das palavras nas frases da base. Nesse primeiro artigo vamos falar sobre dois métodos de vetorizar a frequência das palavras: Bag of Words (BoW) e o Term-Frequency Inverse-Document-Frequency (TF-IDF). Para todas as abordagens iremos utilizar a base de dados do IMDB, que consiste em reviews de filmes classificados com um sentimento positivo ou negativo. É uma base bem simples, e ela permite que avaliemos nossos modelos nos mesmos conjuntos de dados, pois já vem com uma tag de treino e validação.

Bag of Words

O Bag of Words (BoW) consiste em simplesmente definir a frequência em que cada palavra do seu vocabuláro inteiro estão presentes em cada frase. Onde o vocabulario é o conjunto de todas as palvras distintas que você vai considerar nessa base de dados, usualmente sendo as palavras distintas na base de treinamento.

Podemos definir um pseudo código como sendo:

  • Defina seu vocabulário como todas as N palavras distintas da sua base de treinamento;
  • Para cada frase da base de dados (treinamento e validação), conte quantas vezes cada palavra aparece na frase em questão;
  • Crie vetores para cada frase, onde o vetor será de dimensão (1, N), onde cada posição será a quantidade de vezes que a palavra aparece na frase.

Ao fim, você terá uma base de dados de tamanho (L, N), onde L é o número de observações da base e N é o número de palavras do seu dicionário. A figura abaixo representa o que essa abordagem realiza.

Esquematização do processo de vetorização por meio da abordagem BoW. Fonte: Autor.

Ao fim desse processo, você terá uma representação vetorial de cada observação da sua base, e assim você pode utilizar um modelo para realizar o treinamento. Note que, quanto maior a quantidade de palavras que você considera no seu vocabulário, maior será a dimensão dos seus dados de entrada. É comum que se limite o dicionário às M palavras mais frequentes da base, para que se limite o tamanho dos vetores de entrada sem que se perca muita informação.

Outro ponto importante aqui é que algumas palavras são mais comuns de aparecer do que outras, como artigos (“o”, “a”, ou no inglês, “the”). Esse tipo de palavra é chamada de “stopword”, palavras que não carregam informação, porém são frequentes, por isso é comum que se retire as stopwords do vocabulário**. Variações de palavras nem sempre são desejadas quando trabalhamos com textos, por exemplo, palavras no singular, no plural ou em tempos verbais diferentes, podem não estar relacionados com o sentimento da frase em si. Portanto, considerar, por exemplo, “book” e “books” como palavras distintas pode trazer ruído ao modelo, aumentando a dimensionalidade do problema sem necessidade. Existem técnicas que buscam simplificar o problema, extraindo a raíz das palavras, os chamados Stemmings.

** Apesar de ser comum retirar as stopwords, nem toda tarefa envolvendo texto ficará melhor ao se retirá-las. Palavras como “sim” e “não” são consideradas stopwords, porém podem trazer informação de afirmação e negação. Ao mesmo tempo que, no contexto específico do seu projeto, outras palavras podem vir a ser stopwords, como por exemplo a palavra “cliente” em um projeto empresarial, ela pode estar tão presente em todos os documentos que acaba sendo uma palavra sem relevância. Por isso, sempre analise diversas formas de processamento de texto no seu projeto.

No contexto dessa série de artigos, vamos nos limitar somente às técnicas de representação textual (se quiserem um post falando só sobre pre processamento de texto, comenta ai que eu faço 😄).

Então vamos lá, como fazemos isso então?

O Scikit já tem a função que realiza esse tipo de vetorização, o chamado CountVectorizer. Assim basta utilizar o CountVectorizer para transformar os dados e então treinar um modelo, como segue abaixo. Se você tem interesse em como seria a implementação do CountVectorizer, pode checar meu Github, onde mostro uma implementação do zero.

Em seguida, passamos nossos dados, e os transformamos em vetores. Perceba como a dimensão será L = 25.000 e N = 1000 (que definimos no argumento do CountVectorizer).

Agora podemos utilizar um modelo para associar as frequências aos rótulos de sentimento. Aqui utilizaremos um modelo simples, a Regressão Logística.

Conseguimos 86% de acurácia, somente com essa codificação e usando um modelo simples! Você pode avaliar outras métricas de classificação. Não conhece outras? Aprenda aqui outras métricas de classificação.

Term-Frequency Inverse-Document-Frequency (TF-IDF)

Como disse no BoW, algumas palavras podem não ter relevância, as famosas stopwords. É comum existir listas de palavras que comumente são stopwords, com preposições e artigos da lingua, por exemplo. O TF-IDF, de forma automática, pondera as palavras mais importantes. Basicamente, essa técnica permite que a representação vetorial tenha um peso com base da frequência em que as palavras aparecem em todas as frases da base, ou seja, uma palavra que está presente em todas as frases da base, não carrega informação, e portanto terá um peso baixo.

Mais tecnicamente, TF, ou Term Frequency, seria a mesma ideia do BoW, considerar a frequência com que cada palavra p aparece na frase f.

Equação do termo TF. Fonte: latex.codecogs.com

IDF, ou Inverse-Document-Frequency, é onde a palavra será ponderada quanto a sua capacidade de diferenciar as frases. Como o próprio nome diz, esse valor é o inverso da frequência de documento, ou seja, a frequência de documento que contém a palavra p, FD(p), seria:

Equação do termo FD. Fonte: latex.codecogs.com

Portanto, seu inverso, IDF(p), será:

Equação do termo inverso de FD. Fonte: latex.codecogs.com

Para evitar valores muito grandes de IDF, se coloca a função log no seu resultado, além de evitar divisão por zero adicionando 1 ao termo do denominador, ficando:

Equação do termo inverso normalizado pelo Log de FD. Fonte: latex.codecogs.com

Ou seja, caso todos os documentos possuirem aquela palavra, o valor do peso será log(N/N+1) ~= log(1) = 0. Dessa forma, esse parâmetro IDF, permite com que palavras que aparecem em muitos documentos, tenham pesos menores, indicando que não são variáveis discriminatórias.

O valor final de cada posição dos vetores que representarão as frases será dado por:

Equação final do TF-IDF. Fonte: latex.codecogs.com

Para nossa alegria, o TF-IDF também já consta no pacote do Sklearn, então refazemos nossa abordagem, porém utilizando a vetorização TF-IDF para a tarefa de análise de sentimentos.

Em seguida, passamos nossos dados, e os transformamos em vetores. Análogo ao CountVectorizer.

Agora podemos utilizar um modelo com os mesmos parâmetros do anterior para testarmos somente a mudança na forma de vetorizar os textos.

Conseguimos 88% de acurácia, levemente superior ao CountVectorizer. É importante notar que, não necessariamente o TF-IDF será sempre melhor que o BoW, caso queira testar outros parâmetros, acesse o Jupyter Colab (totalmente executável, com a mesma base de dados usada). No entanto, os pesos que o TF-IDF adiciona na vetorização, permite com que a representação dos textos seja melhor em relação à operações matemáticas. Mas como assim? Os pesos são menores para palavras comuns, ou irrelevantes, como “the”, “of” ou “a”, ao mesmo tempo que realçam as palavras que caracterizam melhor cada frase. Esse “realce” faz com que frases que tenham características similares também tenham vetores similares. Por causa dessa característica do TF-IDF, ele é muito utilizado para sistemas de busca de documentos por exemplo (e pretendo trazer um artigo de um sistema de ranqueamento de documentos 😉).

Conclusão

BoW e TF-IDF são duas técnicas simples de vetorização textual. Apesar de simples, elas já permitem resultados interessantes em diversas tarefas, como os 88% de acurácia na tarefa de análise de sentimentos. O TF-IDF por exemplo pode ser usado para ranqueamento de documentos [3]. No entanto, ambas as técnicas ponderam somente frequência das palavras e nada mais. No próximo post vou introduzir o conceito de “Word Embeddings”, onde a vetorização agora consegue trazer informação semântica das palavras, isto é, os vetores agora possuem propriedades semânticas, fazendo com que palavras com SENTIDO próximo possuam vetores também próximos nesse espaço. Essa técnica permitiu uma melhora grande em diversas tarefas de processamento de linguagem. Nos vemos lá então 😘

Referências

[1] https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html

[2] https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.TfidfVectorizer.html

[3] https://homepages.dcc.ufmg.br/~nivio/cursos/ri10/transp/slideschap04a.pdf

--

--

dekzin AI
Computando Arte

Um matemático formado, quase mestre em deep learning trocando uma ideia sobre inteligência artificial.