O Básico de NLP

Conhecendo as principais ferramentas para construir suas aplicações

Tiago Bachiega de Almeida
VLabs
14 min readJan 21, 2022

--

No trabalho com dados é extremamente comum falarmos de bases com informações bem definidas, geralmente armazenadas em bancos de dados relacionais e que são combinadas entre si e enriquecidas para gerar features relevantes para serem consumidas por modelos de Machine Learning acoplados a alguma aplicação. Como exemplos, temos bases de compras de E-commerce indicando qual cliente comprou qual item, o que pode ser utilizado para alimentar um modelo de recomendação. Ou ainda um base de dados contendo informações sobre operações financeiras que pode ser utilizada para identificar fraudes.

Este tipo de dado, que possui uma estrutura bem definida, como planilhas do Excel ou tabelas de um banco de dados, são chamados de dados estruturados e são bastante explorados em diversas aplicações. Porém, existe uma outra categoria de dados denominada não estruturados que possui informações muito úteis para diversas aplicações e abrem um novo universo de técnicas de engenharia de dados e modelagem a serem estudadas.

Como exemplos de dados não estruturados temos imagens, áudios e textos. Estes são dados não estruturados pois não possuem um padrão definido que define sua estrutura. Em um texto de comentário numa rede social, por exemplo, não há limitação de número de caracteres, delimitação de campos, restrição de conteúdo, ou outras regras e restrições deste tipo. São dados totalmente dinâmicos. No mundo real, a grande maioria dos dados são não estruturados e requerem técnicas específicas para serem trabalhados.

Dado o contexto, neste artigo iremos abordar técnicas básicas para a atuação em dados não estruturados textuais. Este tipo de informação é de extrema relevância pois permite que a tecnologia processe dados como notícias, comentários, reviews, chats, entre outras aplicações conhecidas. No campo da Inteligência Artificial, estas técnicas são conhecidas como NLP (Natural Language Processing) e permitem a criação de aplicações como motores de busca, detectores de spam, assistentes inteligentes, tradutores automáticos, entre outros.

O objetivo deste artigo não é construir alguma aplicação específica, mas sim mostrar um compilado de técnicas de modelagem que todo profissional que gostaria de começar a construir aplicações de NLP deve conhecer.

Normalizando o texto

Assim como em aplicações de Machine Learning com dados estruturados, é necessário pré-processar o texto antes de colocá-lo em algum modelo. Apesar de ser uma etapa comum a outras aplicações de ML, para texto são utilizados tratamentos diferentes. O objetivo desta etapa é normalizar o texto de forma que fique apenas a informação útil para as etapas seguintes.

Para muitas aplicações, não queremos que o modelo trate de forma diferente a mesma palavras apenas porque em uma entrada da base de dados ela está escrita com letra maiúscula e em outra com letra minúscula. O mesmo pode valer para a mesma palavra que aparece hora no singular e hora no plurar. Para o modelo, este tipo de variação muitas vezes deveria ser tratado de forma única, daí a importância desta etapa de pré-processamento.

Por exemplo, imagine as seguintes entradas de texto:

Estou indo para casa hoje!

Estamos indo para nossas casas hoje

Estou estudando NLP há 3 dias

Estudo nlp

Tendo os exemplos acima, comumente são aplicadas as seguintes normalizações:

Lowercase/uppercase: Para muitos modelos, a mesma palavra escrita com letra maiúscula ou minúscula representam a mesma informação (por exemplo, “NLP” e “nlp”).

Stemming: O mesmo pode valer para variações da mesma palavra raiz, como “estudando” e “estudo”, que podem ser simplificadas para a palavra “estud”. Este processo é chamado de Stemming. Note que, embora o resultado não seja algo legível, consegue manter o texto em um formato uniforme, contendo apenas a informação necessária.

Stopwords: Palavras extremamente comuns, que aparecem em praticamente todos os textos, como artigos (“o”, “as”, “os”, “as”, entre outros) também são geralmente eliminadas. Este tipo de palavra base do idioma é chamado de stopword e, para muitos modelos, a existência delas na base de dados é irrelevante, visto que não servem para diferenciar um texto do outro, já que aparecem em todos. Deve-se tomar um cuidado especial neste processamento, pois “não” é considerado um stopword. Caso seja relevante que o “não” apareça em sua base de dados, ele deve ser removido da lista de stopwords utilizada.

Punctuation: Pode-se eliminar também sinais de pontuação, como “!”, “?” ou “.”, que em muitas aplicações não são informações relevantes.

Números e outros caracteres especiais: Em muitas aplicações ainda não são necessários os números. Aqui, pode-se apenas removê-los do texto ou substituí-los por alguma tag, como <NUM>, caso a informação indicando se existia algum número na string, qualquer que seja ele, for importante. Veremos na etapa anterior que nem todos os modelos conseguem trabalhar com este tipo de tag customizada.

Existem outras normalizações que podem ser aplicadas, sendo estas as mais comuns. Vale dizer que todos estes exemplos de normalizações dependem da aplicação e não são obrigatórios. Por exemplo, em uma aplicação onde os números são importantes, é necessário mantê-los.

Transformando texto em feature

Em Python, Scikit-learn é possivelmente a biblioteca mais utilizada para a construção de modelos. Ainda, outras bibliotecas similares seguem uma estrutura muito parecida em suas definições de métodos, classes, parâmetros e outputs.

Tendo como exemplo o modelo RandomForest, podemos observar que a função fit, por exemplo, recebe como parâmetro o que é definido como “array-like, sparse-matrix”, cujo conteúdo é convertido para o tipo float. Com dados estruturados, utilizando o Pandas ou o Numpy, para armazenar a informação tabular, conseguimos colocar os dados diretamente nas classes de modelos do Scikit-learn sem nenhum problema. Veja pelos exemplos na documentação que os parâmetros de entrada são bem triviais para dados estruturados. Mas como isso deve ser feito para dados não estruturados? A string “Eu estudo NLP” não parece em nada uma estrutura que pode ser convertida para float. Assim, é necessária a aplicação de técnicas para transformar estes dados textuais em inputs para estes modelos, convertendo-os para o formato matricial com os valores representados por números. Aqui, veremos as principais formas de se fazer isso.

Existem diversas maneiras de se transformar o dado em feature e cada uma delas terá sua especificidade e aplicação. O que é importante ressaltar aqui é que essa transformação é possível armazenando ou não o contexto dos documentos e a necessidade de se fazer isso depende bastante do objetivo da modelagem.

Para exemplo, iremos utilizar o dataset 20 newsgroups, disponibilizado no próprio Scikit-learn, contendo trechos de texto classificados por tema, como tecnologia, ciência, religião, entre outros. Para carregá-la, basta utilizar o trecho de código a seguir:

Bag-of-words: A maneira mais básica para se transformar o texto em feature é com o bag-of-words (BoW). Esta técnica transforma cada palavra da base de dados em uma feature e conta, para cada entrada da base, quantas vezes essa palavra aparece no texto. Na prática, é como se conseguíssemos uma tabela onde cada palavra possível na base de dados fosse uma coluna e os valores seriam números inteiros, indicando quantas vezes a palavra aparece na respectiva entrada. Transformando o texto em feature dessa forma não armazena nenhuma informação sobre o contexto do conteúdo, mas pode funcionar bem para diversas aplicações. No Scikit-learn, a classe que realiza esta transformação chama-se CountVectorizer.

TF-IDF: O método anterior possui um problema: entradas na base de dados com textos maiores terão uma média de contagem de palavras maior em relação a entradas com textos menores, mesmo quando ambas as entradas falem sobre os mesmos temas. Isso pode ser um problema para muitos modelos. O TF-IDF é uma forma de transformação de texto em feature que contorna estes problemas dividindo o número de ocorrências de cada palavra na entrada pelo número total de palavras nesta mesma entrada. Ele também aplica um critério de peso, dando menos importância para palavras que aparecem muitas vezes na base de dados como um todo. Esta técnica também não captura o contexto presente nos textos. No Scikit-learn, pode-se utilizar a classe TfidfVectorizer para aplicar esta técnica.

BERT: para transformar o texto em feature armazenando o contexto do conteúdo é bastante comum utilizarmos modelos pré-treinados. BERT é um dos modelos mais avançados para este objetivo, desenvolvido pelo Google. De forma bastante simplificada, este modelo é baseado em uma estrutura de rede neural chamada Transformer e já foi treinado para entender e abstrair o contexto de frases textuais, sendo um dos mais poderosos existentes hoje para isso. Existem diversas variações do BERT, cada uma com sua especificidade, e hoje iremos utilizar o bert-base-uncased, disponibilizado pelo grupo de HuggingFace.

Vale ressaltar que esta etapa deve ser pensada de acordo com o objetivo da aplicação. Tendo o BERT como exemplo, existem variações deste e de outros modelos similares que foram treinados para funcionar melhor para aplicações específicas, como classificação, geração de texto, similaridade de sentenças, entre outros.

Aplicando modelos de Machine Learning

Com o texto transformado em feature, a construção de modelos de Machine Learning segue os mesmos passos utilizados para a construção de modelos sobre dados estruturados.

Como exemplo, podemos aplicar nossa base de treino transformada em feature pelo TF-IDF no modelo RandomForestClassifier.

O mesmo vale para realizar a predição sobre novas entradas. O único ponto de atenção é que as novas entradas também virão no formato texto e é necessário aplicar a transformação em feature com o mesmo objeto utilizado sobre a base de treino. Perceba ainda que está sendo aplicada apenas a função transform do TfidfVectorizer, enquanto na base de treino foi aplicado fit_transform. Para novas entradas, não queremos aplicar o fit novamente, devendo ser aplicado apenas o transform.

Com isso, você conseguiu criar seu classificador de textos. Outros modelos funcionam exatamente da mesma maneira. Ainda, técnicas gerais de modelagem, como escolha de parâmetros, acompanhamento de métricas, entre outras, são aplicadas também da mesma maneira que para modelos com dados estruturados.

Similaridade de textos

Em aplicações de NLP é muito comum a comparação entre textos. Com isso, é possível entender se dois textos são parecidos na escrita, estão dizendo a mesma coisa, realizar buscas em uma base de dados, comparar documentos, entre outras aplicações. Aqui a similaridade de textos não se refere apenas à comparação básica de strings, mas a formas de comparação matemática entre textos, que não irá retornar a similaridade de forma binária, mas sim ela traduzida em um grau de similaridade.

Podemos comparar os conteúdos a nível de texto, sem a necessidade de transformá-lo em feature, ou a nível vetorial, após a transformação com TF-IDF, BoW, BERT, entre outros. Existem inúmeras métricas de comparação e, neste artigo, serão mostradas as que considero mais relevantes.

FuzzyWuzzy: Não é exatamente uma métrica, mas uma biblioteca Python que pode ser utilizada para comparação de strings e que abstrai a implementação matemática de algumas métricas. Possui diversos métodos de comparação de string, permitindo flexibilidade para comparar a string como um todo, removendo palavras repetidas, considerando substrings, entre outras formas.

O FuzzyWuzzy abstrai a implementação de outras métricas mais clássicas da literatura como Distância de Levenshtein. Caso deseje se aprofundar mais sobre distâncias, como exemplo, existem, além desta, Distância de Jaro, Distância de Jaccard e Distância de Jaro-Winkler.

Similaridade de Cosseno sem contexto: esta métrica é bem conhecida pois permite a comparação entre dois vetores pelo cosseno do ângulo entre eles. Na etapa de transformação de texto em feature aprendemos, em termos matemáticos, como transformar o texto em um vetor N dimensional. Podemos aproveitar este formato de dado e aplicar qualquer métrica de comparação vetorial e utilizar isso para descobrir a semelhança entre dois textos. Similaridade de Cosseno é bastante utilizada no mundo de NLP, sendo a base de muitos motores de busca e recomendação.

O Scikit-Learn permite sua implementação de forma bastante prática.

Note que utilizamos a função cosine_similarity passando toda a lista de textos como parâmetros, realizando a cálculo da métrica entre cada par de textos da lista. O output nos indicou que o primeiro (“Fui ao shopping”) e o segundo (“Hoje fui ao shopping”) são bastante similares.

Como utilizamos uma transformação do texto em vetor que não armazena a informação do contexto, as métricas de similaridade também não irão considerar este detalhe.

Similaridade de Cosseno com contexto: para conseguir realizar a comparação de texto considerando o contexto, podemos utilizar a similaridade de cosseno com o BERT, que consegue codificar o valor contextual dos documentos. No exemplo abaixo, paraphrase-xlm-r-multilingual-v1 é um modelo similar ao BERT, utilizado anteriormente.

Note como foi corretamente identificado que as duas primeiras frases, embora completamente distintas entre si, falam sobre a mesma coisa, e que a última frase se refere a outro tema.

Soluções importantes de NLP

Agora que passamos pelos principais conceitos, é importante conhecermos soluções de NLP que são bastante famosas. Muitas dessas soluções são modelos prontos, pré-treinados para algum objetivo específico. Seus resultados podem ser acoplados a aplicações para a solução de problemas reais e muitas delas estão disponíveis em bibliotecas OpenSource ou em serviços Cloud como AWS, Azure ou Google Cloud.

Análise de sentimentos: este modelo é essencialmente um classificador capaz de indicar qual o sentimento predominante no texto (positivo, negativo, neutro, misto, entre outros). É bastante utilizado para análise de comentários em redes sociais. Não existem muitos modelos pré-treinados para análise de sentimentos em português, porém existem boas bases de dados e tutoriais no Kaggle que podem ajudar com esta tarefa. Os serviços Cloud, como o Amazon Comprehend, suportam texto em português para este objetivo, embora haja um custo associado ao processamento.

Named Entity Recognition (NER): este tipo de modelo busca identificar entidades citadas no texto. Entidades são palavras como nomes de pessoas, localidades, datas, números, referências a moeda, entre outros exemplos. Na frase “Microsoft é uma empresa de tecnologia fundada em Albuquerque”, um modelo deste tipo encontraria as entidades “Microsoft” e a associaria à categoria “Organização” e “Albuquerque” e a associaria à categoria “Localidade”. Existem diversos serviços Cloud que disponibilizam modelos de NER para português, como o Amazon Comprehend. No cenário OpenSource, podemos utilizar a biblioteca SpaCy.

Summarization: Existem modelos capazes de resumir uma grande quantidade de textos, gerando um texto novo, menor, mas que contém as informações relevantes da massa original. O HuggingFace disponibiliza modelos bastante robustos para este objetivo. Veja o exemplo abaixo, onde é resumida a descrição inicial da banda The Beatles encontrada no Wikipedia em português.

Question Answering: Este tipo de modelo entende um dado contexto e possibilidade que informações sejam extraídas com base em perguntas. É bastante útil para algumas aplicações de busca e mineração de informação em corpus muito grandes. Experimente o exemplo abaixo, que utiliza o pipeline do HuggingFace, com outras perguntas.

Tradução: Como o nome sugere, este modelo traduz textos entre idiomas. Em Python, é possível utilizar a própria API do GoogleTranslator para este objetivo. Perceba como ele é eficiente para traduzir até mesmo siglas.

Este artigo tinha como objetivo dar a bagagem inicial para qualquer pessoa que deseja começar a se aventurar no mundo de NLP. Embora não tenhamos entrado em detalhe em nenhum tópico, acredito que a diversidade de temas nesta etapa do aprendizado possibilita mais repertório para discutir, planejar e iniciar o desenvolvimento de aplicações com este tipo de tecnologia. Conforme você for descobrindo novos desafios sobre NLP na carreira, espero que este artigo o ajude a entender quais tecnologias existem para serem aplicadas. A partir daí, você estudará e desenvolverá com mais detalhe os modelos que forem necessários.

Se você chegou até aqui, espero que esteja mais confiante para trabalhar nas suas próprias aplicações de NLP. Até a próxima!

--

--