Entendendo o algoritmo de busca full-text BM25
(emschwartz.me)- BM25 ainda é amplamente usado em busca full-text quando é necessário correspondência exata de palavras-chave, e se tornou um dos pilares da busca híbrida que complementa a busca por similaridade vetorial
- Sem calcular probabilidades diretamente para ordenar documentos, o BM25 soma pesos por termo da consulta para colocar na frente os documentos que parecem mais relevantes
- A pontuação se divide em IDF, frequência do termo no documento e normalização pelo comprimento do documento; palavras raras têm mais peso, e repetições sucessivas recebem recompensa cada vez menor
k1controla a velocidade da redução no ganho por repetições, ebcontrola a intensidade da normalização pelo comprimento do documento; normalmente usam-sek1=1.2~2eb=0.75- Como a pontuação do BM25 não é uma probabilidade real de relevância, ela é difícil de usar como valor de comparação genérico e só faz sentido quando comparada dentro da mesma coleção de documentos
O problema de busca que o BM25 tenta resolver
- BM25, ou Best Match 25, é um algoritmo amplamente usado em busca full-text
- É usado como padrão em Lucene/Elasticsearch e SQLite, entre outros
- Mais recentemente, a busca híbrida, que combina busca full-text com busca por similaridade vetorial, se tornou comum
- Em feeds de conteúdo personalizados, a busca apenas por similaridade vetorial pode ser insuficiente para tratar palavras-chave exatas
- Se o interesse for
Solid.js, usar só busca por similaridade vetorial pode acabar retornando mais conteúdo relacionado a React do que a Solid
- Se o interesse for
- A pergunta central é se é possível comparar a pontuação BM25 de um documento entre várias consultas para determinar com qual consulta esse documento combina melhor
O princípio de ranqueamento probabilístico e a abordagem do BM25
- O objetivo da busca full-text é encontrar os documentos mais relevantes dentro do conjunto possível de documentos com base em uma consulta
- Como não é possível saber com certeza a relevância real, os sistemas de busca tentam ordenar com base na probabilidade de um documento ser relevante para a consulta
- Essa ideia é chamada de Probability Ranking Principle
- A busca lexical, como o BM25, usa apenas a consulta e as características dos documentos dentro da coleção
- Já a busca por similaridade vetorial pode usar modelos de embeddings treinados em corpora externos para representar o significado da consulta e dos documentos
Os componentes da pontuação BM25
- O BM25 calcula a pontuação combinando vários sinais da consulta e da coleção de documentos
-
Termos da consulta
- Se a consulta for composta por vários termos, calcula-se a pontuação de cada termo e depois tudo é somado
-
Frequência inversa de documento (IDF)
- Indica o quão raro um termo de busca é em toda a coleção de documentos
- Palavras comuns como
theeandsão consideradas pouco informativas, então termos raros ganham mais importância
-
Frequência do termo no documento
- Reflete quantas vezes o termo de busca aparece em um documento específico
- Quanto mais o mesmo termo se repete, maior tende a ser a chance de relevância, mas o BM25 aplica retorno decrescente às repetições
-
Comprimento do documento
- Documentos longos podem conter mais ocorrências do termo de busca simplesmente por serem longos
- O BM25 normaliza o comprimento comparando-o com o comprimento médio dos documentos para evitar que documentos longos recebam pontuação injustamente alta
Cada parte da fórmula do BM25
- A pontuação total do BM25 soma a pontuação de cada termo da consulta
q_ipara um documentoDe uma consultaQD: documento alvoQ: consulta completan: número de termos da consultaq_i: cada termo da consulta
-
IDF: dar mais peso a palavras raras na coleção
- O termo de IDF calcula o quão raro cada termo da consulta é em toda a coleção de documentos
N: número total de documentos da coleçãon(q_i): número de documentos que contêm o termo da consultaN - n(q_i): número de documentos que não contêm o termo da consulta- Termos comuns aparecem em muitos documentos, então têm impacto menor na pontuação
- Termos raros aparecem em poucos documentos, então pesam mais na pontuação
- Os valores
0.5e1na fórmula suavizam o resultado para que ele não oscile demais quando um termo é extremamente raro ou extremamente comum
-
Frequência do termo: conta repetição, mas sem recompensa infinita
- A frequência do termo no documento reflete com que frequência um termo da consulta aparece em um documento específico
f(q_i, D): frequência com que o termo da consultaq_iaparece no documentoDk1: parâmetro de ajuste normalmente definido entre1.2e2- O BM25 leva em conta a repetição do termo na pontuação, mas quanto mais ele se repete, menor é o ganho adicional de pontuação
k1controla quão rápido essa recompensa por repetição diminui
-
Normalização pelo comprimento do documento: ajustando a vantagem de documentos longos
- A normalização pelo comprimento do documento compara o comprimento do documento alvo com o comprimento médio da coleção
|D|: comprimento do documento alvoavgdl: comprimento médio dos documentos da coleçãob: parâmetro de ajuste que controla a intensidade da normalização pelo comprimento do documento- Como documentos maiores têm mais chance de conter o termo de busca com mais frequência, eles sofrem penalização no denominador da fórmula final
- Se
b=0, a normalização pelo comprimento do documento é desativada; seb=1, ela é aplicada por completo bnormalmente é definido como0.75
A ideia central do BM25
- O BM25 se baseia no Probability Ranking Principle, mas é praticamente impossível calcular a probabilidade real de relevância de um documento
- Como, em busca, o mais importante é a ordem dos documentos, e não o valor exato da probabilidade, a fórmula elimina termos que não afetam a ordenação para tornar o cálculo prático
- Por isso, o BM25 calcula pesos, não probabilidades em si
- Robertson/Sparck Jones Weight é uma forma de estimar probabilidades usando a quantidade de documentos relevantes e a quantidade de documentos que contêm o termo da consulta
r: número de documentos relevantes que contêm o termo da consultaN: número total de documentos da coleçãoR: número de documentos relevantes da coleçãon: número de documentos que contêm o termo da consulta
- A grande limitação dessa abordagem é que ela exige saber de antemão quais documentos são relevantes
A hipótese de que “a maioria dos documentos não é relevante”
- Os criadores do BM25 assumem que, para uma consulta arbitrária, a maioria dos documentos não é relevante
- Se o número de documentos relevantes for pequeno a ponto de poder ser ignorado, podemos assumir
R = r = 0 - Ao substituir esses valores na fórmula de Robertson/Sparck Jones Weight, obtém-se uma forma muito próxima do termo de IDF usado no BM25
- Como mantém a mesma base teórica sem exigir informação prévia de relevância, o BM25 se torna muito mais prático
- Victor Lavrenko descreve isso como um "salto de fé muito impressionante"
O escopo de comparação da pontuação BM25
- Em geral, pontuações BM25 não são fáceis de comparar diretamente
- Elas não geram um escore probabilístico entre 0 e 1
- O algoritmo também não tenta estimar a probabilidade real de um documento ser relevante
- O foco é aproximar a ordem de probabilidade de relevância para uma consulta dentro de uma coleção específica
- Uma pontuação BM25 mais alta é um sinal de que o documento provavelmente é mais relevante, mas não representa a probabilidade real de relevância
- Para o mesmo documento dentro da mesma coleção, é possível comparar pontuações BM25 entre várias consultas
- Como o BM25 soma as pontuações de cada termo da consulta, pode-se considerar que não há diferença semântica relevante entre comparar duas pontuações de termos e comparar duas pontuações de consultas completas
- A restrição importante é: mesmo documento, mesma coleção
- O BM25 usa o IDF da coleção e o comprimento médio dos documentos
- Se a coleção mudar, a pontuação também pode mudar, então comparações ao longo do tempo não são garantidas
- Em feeds de conteúdo personalizados, é possível executar busca full-text para cada interesse do usuário e comparar as pontuações BM25 para determinar a qual interesse um conteúdo se ajusta melhor
Leitura adicional
- Para se aprofundar na teoria e na história do BM25, vale ver a apresentação de 2016 da engenheira da Elastic Britta Weber, Improved Text Scoring with BM25
- The Probabilistic Relevance Framework: BM25 and Beyond, de Stephen Robertson e Hugo Zaragoza, trata do framework de relevância probabilística do BM25
- Uma comparação entre BM25 e outros algoritmos de busca full-text pode ser vista em Comparing full text search algorithms: BM25, TF-IDF, and Postgres
1 comentários
Opiniões no Hacker News
Tenho usado https://typesense.org/ para busca geral e, agora que ele também oferece suporte a busca híbrida, fiquei curioso para saber se alguém já testou
Fico feliz em ver o Typesense sendo mencionado aqui; para projetos de RAG de pequeno porte, ele costuma ser uma boa opção, mas por algum motivo é menos conhecido do que deveria
É fácil de implantar, os padrões são razoáveis, a documentação é boa e o clustering também é relativamente simples; ainda assim, quando é preciso se aprofundar mais, ele continua sendo bastante performático e poderoso
Porém, se você usar um modelo de embeddings de um provedor externo, a latência fica absurdamente alta, acima de 500 ms, então é melhor hospedá-lo diretamente dentro do cluster
A qualidade da busca híbrida é boa, mas as opções de ajuste são muito limitadas, e as pontuações também são bastante opacas fora do ranqueamento dentro do conjunto de resultados
Com os avanços recentes da busca semântica baseada em vetores, fico curioso para saber qual é a stack de busca mais atual usada hoje em dia para híbridos de palavra-chave + busca semântica
Recentemente recebemos cerca de 3 milhões de respostas de pesquisas, cada uma com 10 campos de texto livre, e precisávamos encontrar itens sobre os quais a empresa deveria agir
Usamos alguns modelos classificadores pequenos; depois de observar o ruído nos primeiros 10 mil registros, removemos manualmente palavras comuns e atribuímos pesos às respostas dos modelos, e isso funcionou quase perfeitamente
Esse tipo de coisa parece menos “programação” e mais ajustar as saídas de caixa-preta de várias ferramentas até que fiquem boas para os casos de teste e para o cliente
Como referência, processamos tudo em Node.js em um servidor pequeno, encadeando vários modelos pequenos do Hugging Face
Os resultados geralmente são combinados com Reciprocal Rank Fusion (RRF)
O artigo de RRF é impressionante por ser surpreendentemente simples, e tem só 2 páginas: https://plg.uwaterloo.ca/~gvcormac/cormacksigir09-rrf.pdf
Para trabalhos no estilo BM25, dá para usar Elasticsearch; para busca vetorial simples e rápida, Turbopuffer; para pré-computar resultados de determinadas consultas ou lidar com atributos dinâmicos que mudam com frequência, como preços, Redis também pode servir
Acho melhor combinar essas coisas em um modelo scatter/gather
Fora da stack de busca, quase sempre existe uma camada de serviço de inferência para reranking e, idealmente, ela se torna um serviço simples parecido com o restante da infraestrutura de machine learning
Quase sempre também é necessário rotear consultas de usuários, por exemplo entendendo que “buscar por ID” deve ir para um sistema, enquanto “busca semântica fuzzy” deve ir para outro
Essas estruturas de dados são muito diferentes, e busca costuma cobrir uma ampla variedade de casos de uso distintos
Considero um antipadrão empurrar tudo para dentro de um único sistema
Cada sistema se adapta a cargas de trabalho diferentes, e recursos de inferência embutidos dificilmente acompanham a velocidade das ferramentas gerais de machine learning com as quais engenheiros de ML estão acostumados
Tentei fazer isso com Elasticsearch Learning to Rank, mas era uma tarefa sem futuro
Ainda assim, entre as tentativas de resolver um conjunto amplo de casos de uso em uma única stack, Vespa provavelmente é a melhor
Como autor do txtai, o txtai implementa um índice BM25 performático em Python por meio do pacote arrays e armazena vetores de frequência de termos no SQLite
A abordagem de índice híbrido do txtai oferece suporte a combinação convexa quando as pontuações BM25 estão normalizadas e a Reciprocal Rank Fusion (RRF) quando não estão
[1] https://github.com/neuml/txtai
[2] https://neuml.hashnode.dev/building-an-efficient-sparse-keyw...
[3] https://neuml.hashnode.dev/benefits-of-hybrid-search
[4] https://github.com/neuml/txtai/blob/master/src/python/txtai/...
Ela usa várias técnicas de busca: busca lexical (bm25, busca fuzzy), busca semântica (embeddings), reranking (cross-encoder, Reciprocal Rank Fusion) e reranking para garantir diversidade e mitigar o problema de lost-in-the-middle
[1] Langroid - framework multiagente de LLM criado por pesquisadores da CMU/UW-Madison https://github.com/langroid/langroid
[2] Implementação do DocChatAgent -
https://github.com/langroid/langroid/blob/main/langroid/agen...
Basta começar pelo método answer_from_docs e seguir a partir dali
A propósito, se você é o fundador da Kadoa, o Kadoa-snack é uma das ferramentas que uso com prazer todos os dias para encontrar discussões do HN relacionadas a LLMs
É um bom texto.
Para acrescentar um contexto um pouco mais difícil de encontrar: BM25 é a sigla de “Best Matching 25”, e “best matching” significa que é uma fórmula que atribui rankings e pesos aos termos combinando os termos da consulta com os termos do documento.
O 25 é simplesmente um número de sequência: antes dele houve 24 variações da fórmula, e depois também houve outras variações, mas a de número 25 foi publicada porque era a que funcionava melhor.
Foi concebido por Stephen Robertson e Karen Spärck Jones (famosa pelo IDF) e implementado pela primeira vez no sistema de pesquisa em recuperação de informação OKAPI, de Robertson.
O sistema OKAPI foi benchmarkado durante vários anos na TREC (Text Retrieval Conference) anual do NIST dos EUA, algo próximo de um “campeonato mundial” internacional de metodologias de mecanismos de busca.
Porém, o objetivo do evento é mais a comparação e o aprendizado mútuo do que vencer; é um evento recomendável realizado todo mês de novembro em Gaithersburg, Maryland.
Além do modelo de espaço vetorial “saco de palavras” (vetores esparsos de termos) e do modelo probabilístico ao qual o BM25 pertence, há uma quantidade surpreendente — e crescente — de arcabouços teóricos para ranquear um conjunto de documentos dada uma consulta.
Por exemplo, há Divergence from Randomness, modelagem estatística de linguagem, Learning to Rank, recuperação de informação quântica, ranqueamento por redes neurais etc.
Em conferências como ICTIR ou SIGIR, ainda aparecem de vez em quando paradigmas de busca completamente novos.
Aqui, “modelagem estatística de linguagem” não se refere aos grandes modelos de linguagem que estão em alta hoje; estes entram na categoria de “busca neural”.
Além disso, ao pesquisar por “Quantum IR”, você pode acabar vendo espectroscopia no infravermelho ou uma empresa de cimento com o mesmo nome, e não um tutorial de recuperação de informação quântica.
Mesmo no século 21, a tecnologia de busca ainda tem essas sutilezas.
Se quiser comparar diretamente o BM25 com alternativas, recomendo Terrier, um mecanismo de busca open source e plataforma de pesquisa desenvolvido pela University of Glasgow.
O BM25 já tem mais de 25 anos, mas ainda se provou uma baseline difícil de superar e é frequentemente usado como ponto de referência ao comparar novos métodos.
Uma variação mais recente, o BM24F, consegue lidar com vários campos, como título, corpo do texto e hyperlinks, além de hipertexto.
O artigo recomendado é Spärck Jones, K.; Walker, S.; Robertson, S. E. (2000). “A probabilistic model of information retrieval: Development and comparative experiments: Part 1”. Information Processing & Management 36(6): 779–808, além da Part 2 posterior.
Infelizmente, não é open access.
Começou no dia 18 e termina no dia 22.
Mais detalhes: https://trec.nist.gov/
Mesmo procurando no Google e no Google Scholar, não encontrei conteúdo relacionado.
Divulgação sem vergonha: https://github.com/jankovicsandras/plpgsql_bm25
https://github.com/jankovicsandras/bm25opt
https://github.com/softwaredoug/searcharray
Também divulgo o BM25S, do Xing Han Lu, que é muito popular e tem um objetivo parecido.
https://github.com/xhluca/bm25s
Fico curioso se existe algum projeto wrapper em Python puro para gerenciar muitos textos e documentos PDF.
Pensei em Solr ou ElasticSearch, mas eles parecem pesados demais para o que quero fazer agora.
Como o SQLite usa BM25, estou considerando uma abordagem que combine pysqlite3 e PyPDF2.
Fugindo um pouco do tópico, acho que muita gente procura ferramentas para criar aplicações híbridas de BM25 / armazenamento vetorial / LLM.
Fico curioso se o comprimento médio de documento mencionado na normalização por comprimento de documento é a mediana.
Para reduzir corretamente o peso de documentos excessivamente longos, acho que deveria ser a mediana; caso contrário, documentos muito longos não puxariam a média para cima de forma injusta?
Usar a mediana também parece ser um experimento interessante.
Fico curioso se você conhece algum dataset de busca em que o comprimento dos documentos varie muito.
Por exemplo, no MSMarco os comprimentos são bastante uniformes.
É um bom texto.
Eu gostaria sinceramente de aprender a pensar nesse tipo de problema em forma matemática e a testá-lo; há algum material de referência recomendável?
A busca híbrida resolve o velho desafio da relevância dos resultados de busca.
Usando fusão de ranking entre palavras-chave e vetores, é possível criar uma busca híbrida que funcione na maioria das situações.
O BM25 é um algoritmo antigo, desenvolvido na década de 1970
Basicamente é um modelo estatístico rudimentar, e os estatísticos de hoje conseguem fazer muito melhor
Vejo a busca como algo estritamente dominado por métodos baseados em aprendizado
Claro que o aprendizado pode usar a busca como entrada
Ainda há muita gente que não percebeu isso, ou que tem incentivos para manter tecnologias antigas pelo maior tempo possível, mas a pressão do mercado acabará mudando isso
Não foi por causa dessa tecnologia que passamos a acrescentar “+reddit” a cada consulta para escapar da guerra de SEO adversarial?
Ser antigo não significa ser ruim
O que importa é a utilidade de uma invenção, descoberta ou técnica, não sua idade; essa atitude tecnocrática estranha, obcecada pela idade, é preocupante
Quais abordagens estatísticas modernas específicas você considera superiores a ponto de substituir o BM25 em aplicações reais?
Em especial, tenho curiosidade sobre como elas lidam com casos-limite como termos raros e normalização por comprimento do documento, que o BM25 tentou tratar explicitamente
Concordo que abordagens baseadas em aprendizado apresentaram resultados impressionantes, mas também gostaria de ouvir melhor o que exatamente significa dizer que a busca é “estritamente dominada” por métodos de aprendizado
Você está se referindo a benchmarks específicos ou a casos reais em produção?
Acho que muitos especialistas em busca não concordariam
Um excelente podcast de David Tippet (ex-OpenSearch, atualmente no Github) e Nicolay Gerold tem este título:
“BM25 is the workhorse of search; vectors are its visionary cousin”
https://www.youtube.com/watch?v=ENFW1uHsrLM
Durante todo o tempo em que trabalhei na área de busca, houve inúmeras modas e tecnologias relacionadas a IA
Agora, empresas de busca vetorial com enormes investimentos de VC estão empurrando uma determinada visão com um exército de evangelistas técnicos
Por outro lado, em lugares como o Google, é enorme a quantidade de curadoria manual e de taxonomias manuais básicas e tediosas que realmente fazem a “busca semântica” funcionar
Só que essas coisas não são sexy, então quase não são discutidas em conferências