Busca por similaridade de texto com campos vetoriais

Este artigo explora como os embeddings de texto e o novo tipo dense_vector do Elasticsearch podem ser usados para dar suporte à busca por similaridade.

Da busca vetorial às poderosas REST APIs, o Elasticsearch oferece aos desenvolvedores o kit de ferramentas de busca mais abrangente. Mergulhe em notebooks de exemplo no GitHub para experimentar algo novo. Você também pode iniciar seu teste gratuito ou executar o Elasticsearch localmente hoje mesmo.

Desde seus primórdios como um mecanismo de busca de receitas, o Elasticsearch foi projetado para fornecer uma busca de texto completo rápida e poderosa. Dadas essas raízes, aprimorar a busca textual tem sido uma motivação importante para nosso trabalho contínuo com vetores. No Elasticsearch 7.0, introduzimos tipos de campo experimentais para vetores de alta dimensão e, agora, a versão 7.3 traz suporte para o uso desses vetores na pontuação de documentos.

Este artigo aborda uma técnica específica chamada busca por similaridade de texto. Nesse tipo de busca, o usuário insere uma breve consulta em texto livre, e os documentos são classificados com base em sua similaridade com a consulta. A similaridade textual pode ser útil em diversos casos de uso:

  • Resposta a perguntas: Dada uma coleção de perguntas frequentes, encontre perguntas semelhantes àquela que o usuário inseriu.
  • Busca de artigos: Em uma coleção de artigos de pesquisa, retornar artigos com títulos intimamente relacionados à consulta do usuário.
  • Busca por imagem: Em um conjunto de dados de imagens com legendas, encontre imagens cuja legenda seja semelhante à descrição do usuário.

Uma abordagem direta para a busca por similaridade seria classificar os documentos com base em quantas palavras eles compartilham com a consulta. Mas um documento pode ser semelhante à consulta mesmo que tenha pouquíssimas palavras em comum — uma noção mais robusta de similaridade levaria em conta também seu conteúdo sintático e semântico .

A comunidade de processamento de linguagem natural (PLN) desenvolveu uma técnica chamada incorporação de texto que codifica palavras e frases como vetores numéricos. Essas representações vetoriais são projetadas para capturar o conteúdo linguístico do texto e podem ser usadas para avaliar a similaridade entre uma consulta e um documento.

Este artigo explora como os embeddings de texto e o tipo dense_vector do Elasticsearch podem ser usados para dar suporte à busca por similaridade. Primeiramente, apresentaremos uma visão geral das técnicas de incorporação e, em seguida, demonstraremos um protótipo simples de busca por similaridade usando o Elasticsearch.

Nota: O uso de incorporação de texto em pesquisas é uma área complexa e em constante evolução. Este blog não constitui uma recomendação para uma arquitetura ou implementação específica. Comece aqui para aprender como você pode aprimorar sua experiência de busca com o poder da busca vetorial.

O que são embeddings de texto?

Vamos analisar mais de perto os diferentes tipos de incorporação de texto e como eles se comparam às abordagens de busca tradicionais.

Incorporação de palavras

Um modelo de incorporação de palavras representa uma palavra como um vetor numérico denso. Esses vetores visam capturar as propriedades semânticas da palavra — palavras cujos vetores estejam próximos uns dos outros devem ser semelhantes em termos de significado semântico. Numa boa incorporação, as direções no espaço vetorial estão ligadas a diferentes aspectos do significado da palavra. Por exemplo, o vetor para "Canadá" pode estar próximo de "França" em uma direção e próximo de "Toronto" em outra.

As comunidades de PNL (Processamento de Linguagem Natural) e de busca têm demonstrado interesse em representações vetoriais de palavras há bastante tempo. Nos últimos anos, houve um ressurgimento do interesse em word embeddings, quando muitas tarefas tradicionais foram revisitadas usando redes neurais. Alguns algoritmos de incorporação de palavras bem-sucedidos foram desenvolvidos, incluindo o word2vec e o GloVe. Essas abordagens utilizam grandes coleções de texto e examinam o contexto em que cada palavra aparece para determinar sua representação vetorial:

  • O modelo Skip-gram do word2vec treina uma rede neural para prever as palavras de contexto ao redor de uma palavra em uma frase. Os pesos internos da rede fornecem os embeddings de palavras.
  • Em GloVe, a similaridade entre palavras depende da frequência com que elas aparecem em conjunto com outras palavras do mesmo contexto. O algoritmo treina um modelo linear simples com base na contagem de coocorrência de palavras.

Muitos grupos de pesquisa distribuem modelos que foram pré-treinados em grandes corpora de texto, como a Wikipédia ou o Common Crawl, tornando-os convenientes para baixar e usar em tarefas subsequentes. Embora versões pré-treinadas sejam às vezes usadas diretamente, pode ser útil ajustar o modelo para que ele se adeque ao conjunto de dados e à tarefa específicos. Isso geralmente é feito executando uma etapa de "ajuste fino" no modelo pré-treinado.

Os word embeddings provaram ser bastante robustos e eficazes, e agora é prática comum usar embeddings em vez de tokens individuais em tarefas de PNL, como tradução automática e classificação de sentimentos.

Incorporação de frases

Mais recentemente, os pesquisadores começaram a se concentrar em técnicas de incorporação que representam não apenas palavras, mas também trechos de texto mais longos. A maioria das abordagens atuais baseia-se em arquiteturas complexas de redes neurais e, por vezes, incorpora dados rotulados durante o treinamento para auxiliar na captura de informações semânticas.

Uma vez treinados, os modelos são capazes de pegar uma frase e produzir um vetor para cada palavra em contexto, bem como um vetor para a frase inteira. Assim como no caso do word embedding, versões pré-treinadas de muitos modelos estão disponíveis, permitindo que os usuários ignorem o dispendioso processo de treinamento. Embora o processo de treinamento possa ser bastante intensivo em recursos, a invocação do modelo é muito mais leve — os modelos de incorporação de sentenças são normalmente rápidos o suficiente para serem usados em aplicações em tempo real.

Algumas técnicas comuns de incorporação de sentenças incluem InferSent, Universal Sentence Encoder, ELMo e BERT. A melhoria dos embeddings de palavras e frases é uma área ativa de pesquisa, e é provável que modelos robustos adicionais sejam introduzidos.

Comparação com abordagens de busca tradicionais

Na recuperação de informação tradicional, uma forma comum de representar texto como um vetor numérico é atribuir uma dimensão para cada palavra do vocabulário. O vetor para um trecho de texto é então baseado no número de vezes que cada termo do vocabulário aparece. Essa forma de representar o texto é frequentemente chamada de "saco de palavras", porque simplesmente contamos as ocorrências de palavras sem levar em consideração a estrutura da frase.

Os embeddings de texto diferem das representações vetoriais tradicionais em alguns aspectos importantes:

  • Os vetores codificados são densos e de dimensionalidade relativamente baixa, geralmente variando de 100 a 1.000 dimensões. Em contraste, os vetores de saco de palavras são esparsos e podem conter mais de 50.000 dimensões. Os algoritmos de incorporação codificam o texto em um espaço de menor dimensão como parte da modelagem de seu significado semântico. Idealmente, palavras e frases sinônimas acabam com uma representação semelhante no novo espaço vetorial.
  • Os embeddings de sentenças podem levar em consideração a ordem das palavras ao determinar a representação vetorial. Por exemplo, a expressão "tune in" pode ser representada por um vetor muito diferente de "in tune".
  • Na prática, os embeddings de frases geralmente não se generalizam bem para grandes trechos de texto. Não são comumente usados para representar textos com mais de um parágrafo curto.

Suponhamos que tivéssemos uma grande coleção de perguntas e respostas. Um usuário pode fazer uma pergunta, e queremos recuperar a pergunta mais semelhante em nossa coleção para ajudá-lo a encontrar uma resposta.

Poderíamos usar incorporações de texto para permitir a recuperação de perguntas semelhantes:

  • Durante a indexação, cada pergunta é processada por um modelo de incorporação de sentenças para produzir um vetor numérico.
  • Quando um usuário insere uma consulta, ela é processada pelo mesmo modelo de incorporação de sentenças para produzir um vetor. Para classificar as respostas, calculamos a similaridade vetorial entre cada pergunta e o vetor de consulta. Ao comparar vetores de incorporação, é comum usar a similaridade de cosseno.

Este repositório fornece um exemplo simples de como isso pode ser feito no Elasticsearch. O script principal indexa cerca de 20.000 perguntas do conjunto de dados do StackOverflow e, em seguida, permite que o usuário insira consultas de texto livre no conjunto de dados.

Em breve, analisaremos cada parte do script em detalhes, mas primeiro vamos dar uma olhada em alguns exemplos de resultados. Em muitos casos, o método consegue captar semelhanças mesmo quando não há uma sobreposição significativa de palavras entre a consulta e a pergunta indexada:

  • "Compactar arquivos" retorna "Comprimir/Descomprimir Pastas e Arquivos"
  • "Determinar se algo é um IP" retorna "Como saber se uma string é um IP ou um nome de host?"
  • "Converter bytes em doubles" retorna "Converter bytes em números de ponto flutuante em Python"

Detalhes da implementação

O script começa baixando e criando o modelo de incorporação no TensorFlow. Optamos pelo Universal Sentence Encoder do Google, mas é possível usar muitos outros métodos de incorporação. O script utiliza o modelo de incorporação tal como está, sem qualquer treinamento ou ajuste fino adicional.

Em seguida, criamos o índice do Elasticsearch, que inclui mapeamentos para o título da pergunta, tags e também o título da pergunta codificado como um vetor:

No mapeamento para dense_vector, é necessário especificar o número de dimensões que os vetores conterão. Ao indexar um campo title_vector, o Elasticsearch verificará se ele possui o mesmo número de dimensões especificado no mapeamento.

Para indexar os documentos, aplicamos o modelo de incorporação ao título da pergunta para obter uma matriz numérica. Essa matriz é adicionada ao documento no campo title_vector.

Quando um usuário insere uma consulta, o texto é primeiro processado pelo mesmo modelo de incorporação e armazenado no parâmetro `query_vector`. A partir da versão 7.3, o Elasticsearch fornece uma função de similaridade de cosseno em sua linguagem de script nativa. Para classificar as perguntas com base na sua similaridade com a consulta do usuário, utilizamos uma consulta `script_score`:

Garantimos passar o vetor de consulta como um parâmetro de script para evitar recompilar o script() em cada nova consulta. Como o Elasticsearch não permite pontuações negativas, é necessário adicionar um à similaridade de cosseno.

Nota: esta publicação no blog usava originalmente uma sintaxe diferente para funções vetoriais , disponível no Elasticsearch 7.3, mas que foi descontinuada na versão 7.6.
|

Limitações importantes

A consulta script_score foi projetada para encapsular uma consulta restritiva e modificar as pontuações dos documentos retornados. No entanto, fornecemos uma consulta match_all, o que significa que o script será executado em todos os documentos do índice. Essa é uma limitação atual da similaridade vetorial no Elasticsearch — vetores podem ser usados para pontuar documentos, mas não na etapa inicial de recuperação. O suporte para recuperação baseada na similaridade vetorial é uma importante área de trabalho em andamento.

Para evitar a varredura de todos os documentos e manter um desempenho rápido, a consulta match_all pode ser substituída por uma consulta mais seletiva. A consulta correta a ser usada para recuperação de dados provavelmente dependerá do caso de uso específico.

Embora tenhamos visto alguns exemplos encorajadores acima, é importante notar que os resultados também podem ser inconsistentes e pouco intuitivos. Por exemplo, "compactar arquivos" também atribui pontuações altas a ".csproj parcial". Arquivos" e "Como evitar arquivos .pyc" arquivos?". E quando o método retorna resultados inesperados, nem sempre é claro como depurar o problema — o significado de cada componente do vetor costuma ser opaco e não corresponde a um conceito interpretável. Com as técnicas tradicionais de pontuação baseadas na sobreposição de palavras, muitas vezes é mais fácil responder à pergunta "por que este documento está bem classificado?".

Conforme mencionado anteriormente, este protótipo serve como um exemplo de como os modelos de incorporação podem ser usados com campos vetoriais, e não como uma solução pronta para produção. Ao desenvolver uma nova estratégia de busca, é fundamental testar o desempenho da abordagem em seus próprios dados, certificando-se de compará-la com uma base de referência sólida, como uma consulta de correspondência. Pode ser necessário fazer mudanças significativas na estratégia antes que ela alcance resultados sólidos, incluindo o ajuste fino do modelo de incorporação para o conjunto de dados alvo ou a tentativa de diferentes maneiras de incorporar embeddings, como a expansão de consultas em nível de palavra.

Conclusões

As técnicas de incorporação oferecem uma maneira poderosa de capturar o conteúdo linguístico de um texto. Ao indexar representações vetoriais e atribuir pontuações com base na distância vetorial, podemos comparar documentos usando uma noção de similaridade que vai além da sobreposição em nível de palavras.

Estamos ansiosos para introduzir mais funcionalidades baseadas no tipo de campo vetorial. O uso de vetores para busca é uma área complexa e em constante desenvolvimento — como sempre, adoraríamos saber mais sobre seus casos de uso e experiências no Github e nos fóruns de discussão!

Perguntas frequentes

O que é uma busca por similaridade de texto?

A busca por similaridade de texto é um tipo de busca em que o usuário insere uma breve consulta em texto livre, e os documentos são classificados com base em sua similaridade com a consulta. Pode ser útil em diversos casos de uso, como perguntas e respostas, busca de artigos e busca de imagens.

Conteúdo relacionado

Pronto para criar buscas de última geração?

Uma pesquisa suficientemente avançada não se consegue apenas com o esforço de uma só pessoa. O Elasticsearch é impulsionado por cientistas de dados, especialistas em operações de aprendizado de máquina, engenheiros e muitos outros que são tão apaixonados por buscas quanto você. Vamos nos conectar e trabalhar juntos para construir a experiência de busca mágica que lhe trará os resultados desejados.

Experimente você mesmo(a)