Similaridade entre títulos de produtos com Word2Vec

Publicamos anteriormente artigos sobre a importância de encontrar a equivalência de produtos para uma plataforma de marketplace e como utilizar a técnica de visão computacional SIFT para encontrar similaridade entre imagens. Neste artigo iremos falar sobre como medir a similaridade entre títulos de produtos como mais uma ferramenta para encontrar produtos equivalentes em um catálogo crescente.

Para um ser humano, decidir se dois títulos são similares (ou até mesmo equivalentes) é uma tarefa simples, certo? De fato, considerando o poder computacional e a versatilidade que do cérebro humano, esta decisão pode ser tomada facilmente. Mas como podemos fazer uma máquina tomar este tipo de decisão por nós? As respostas para esta e outras perguntas semelhantes são resultados das pesquisas em uma área do conhecimento chamada processamento de linguagem natural (em inglês natural language processing, ou NLP).

A natureza não estruturada dos textos gera um grande desafio para se lidar computacionalmente com eles. Computadores são extremamente eficientes para executar operações entre vetores ou matrizes, mas limitados ao lidar puramente com dados sem uma estrutura definida. Como podemos, então, buscar uma representação mais adequada dos nossos dados para lidar com este problema?

Word2Vec

Uma das possíveis abordagens, proposta neste artigo por uma equipe de pesquisadores do google em 2013, é uma técnica chamada Word2Vec, cuja ideia é transformar cada palavra (a.k.a. token) do nosso conjunto de frases (a.k.a. corpus) em um vetor numérico que a represente semanticamente.

Utilizando-se esta técnica, podemos obter representações com propriedades bem interessantes. Um exemplo apontado pelos autores do artigo é: o vetor que representa o token “Madri”, subtraído do vetor representante de “Espanha” e somado ao vetor de “França” será muito próximo do vetor obtido para “Paris”. Ou de uma forma equacionada:

vec(“Madri”) — vec(“Espanha”) + vec(“França”) ≈ vec(“Paris”)

Este modelo também é capaz de capturar relações entre as palavras como, por exemplo: “homem” está para “mulher” assim como “rei” está para “rainha”.

Representação bidimensional simplificada para exemplificar a relação capturada entre palavras

Como funciona?

Mas afinal de contas, como é possível que um modelo consiga capturar estas relações e obter vetores com estas propriedades? Para responder a esta pergunta, vamos olhar mais detalhadamente para o seu funcionamento.

O Word2Vec pertence a uma classe de modelos conhecidos na literatura como neural language models, pois utiliza redes neurais para aprender as suas representações. Existem dois algoritmos que são utilizados para o seu treinamento: Continuous bag of words (a.k.a. CBOW) e Skip-gram. Vamos entender com um pouco mais de detalhes (de forma gentil) como modelamos o problema e na sequência falar sobre estes dois algoritmos que podem ser utilizados para resolvê-lo.

Modelagem

Suponha a seguinte frase:

A prática da inovação e ousadia faz parte da rotina de trabalho do Magazine Luiza

Podemos interpretar o contexto de uma determinada palavra através das palavras que estão próximas a ela (antes e/ou após) em uma determinada janela de tamanho k. Para exemplificar vamos considerar a palavra inovação com uma janela de tamanho 2:

  • O contexto considerando as palavras que estão antes é “prática da”
  • Já, se considerarmos as palavras que estão após, temos o contexto “e ousadia”
  • Também podemos considerar o contexto com as palavras antes e após, que neste caso seria “da e” (perceba que pegamos a palavra anterior e a seguinte)

Com esta modelagem, foram propostas as duas abordagens comentadas anteriormente: CBOW e Skip-gram.

CBOW: A ideia do algoritmo Continuous bag of words é: prever qual a palavra que estamos buscando a partir de um determinado contexto. Para isto podemos utilizar uma rede neural em que a sua entrada é um vetor one-hot encoded (explicarei a seguir) que represente as palavras do contexto e a sua saída a palavra que estamos buscando.

Skip-gram: Já a abordagem do Skip-gram é a inversa: tomando como ponto de partida uma determinada palavra, o objetivo é prever o contexto do qual esta palavra veio. Para isto também podemos utilizar uma rede neural, porém a sua entrada é um vetor one-hot encoded que represente a palavra que estamos buscando e a sua saída, as palavras do contexto.

One-hot encoding: Vamos considerar o exemplo da palavra inovação, com janela de tamanho 2 e utilizando o contexto que antecede a palavra (“prática da”). Por simplicidade, vamos reduzir o nosso corpus apenas para as três palavras “inovação”, “prática” e “da” (considerando esta ordem). Para representar o contexto teríamos um vetor (0, 1, 1) e para representar a palavra teríamos um vetor (1, 0, 0). Ou seja, utilizamos o valor 1 na coordenada que representa a palavra desejada.

A representação vetorial que utilizamos para a palavra é o vetor de pesos das hidden layers da rede neural obtido após o treinamento utilizando o nosso corpus. Não é escopo deste artigo falar sobre os detalhes da arquitetura das redes neurais utilizadas, para mais detalhes veja este artigo e/ou esta aula.

Encontrando similaridade entre vetores

Agora que já temos uma representação vetorial para nossos tokens, a pergunta natural que deve surgir é: como fazemos para compará-los?

Uma das técnicas possíveis para esta tarefa é conhecida como similaridade de cossenos. Você deve estar se perguntando agora “o que raios trigonometria tem a ver com esses vetores que encontramos?”. Eu explico.

Produto interno

O produto interno entre dois vetores é uma operação algébrica que os transforma em um número escalar. Para mais detalhes, veja este artigo. Considere dois vetores a e b com mesma dimensão. O produto interno entre a e b é dado por:

Equação 1: produto interno entre dois vetores

A partir da fórmula do produto interno entre dois vetores. Isolando cos(a, b), temos:

Equação 2: cosseno do ângulo entre dois vetores

Similaridade de cossenos

Sabemos que o valor do cosseno entre dois ângulos é um número que varia entre -1 e 1. Quando o ângulo entre eles se aproxima de 0°, o cosseno se aproxima de 1. Já quando os vetores são ortogonais (ou seja, ângulo de 90°), o cosseno é igual a 0. E, por fim, quando os vetores são opostos, o cosseno se aproxima de -1.

Assim, podemos considerar que cosseno próximo de 1 indica uma grande similaridade entre os vetores, enquanto que cosseno próximo de -1 indica o oposto. Veja a intuição disto, representado simplificadamente de modo bi-dimensional na figura abaixo.

Fonte: https://www.safaribooksonline.com/library/view/mastering-machine-learning/9781785283451/ba8bef27-953e-42a4-8180-cea152af8118.xhtml

Portanto, a similaridade de cossenos é obtida através do cálculo do cosseno entre os ângulos dos vetores que desejamos comparar utilizando-se a fórmula do produto interno entre dois vetores (equação 2).

Word2Vec na prática

Agora vamos ver na prática como podemos utilizar o Word2Vec para encontrar similaridade entre títulos de produtos. Para isto, vamos considerar estes dois jogos abaixo:

Produto 1 a ser comparado
Produto 2 a ser comparado

Tendo nosso modelo do Word2Vec já treinado, conseguimos obter um vetor para cada um dos tokens dos títulos dos produtos. Como em geral trabalhamos com uma alta dimensionalidade, não é possível fazermos uma representação gráfica destes vetores, mas eles serão coleções (com o mesmo tamanho) de números decimais.

Para representar o título, podemos utilizar a média dos vetores de cada uma das palavras e calcular a similaridade de cossenos entre eles. No caso dos dois produtos acima encontramos uma similaridade 0.89, indicando que de fato estes dois títulos são muito parecidos.

Considerações Finais

O Word2Vec é uma técnica muito versátil e pode ser utilizada para muitas outras tarefas além de encontrar similaridade entre textos. As propriedades semânticas que são obtidas pelas representações vetoriais trazem muitas possibilidades e podem ser aplicadas para problemas como análise de sentimentos, tradução automática dentre outros.