Visão geral do Decay RankerCompatible with Milvus 2.6.x
Na pesquisa vetorial tradicional, os resultados são classificados puramente pela similaridade vetorial - a proximidade dos vetores no espaço matemático. Mas em aplicações do mundo real, o que torna o conteúdo verdadeiramente relevante depende muitas vezes de mais do que apenas a semelhança semântica.
Considere estes cenários quotidianos:
Uma pesquisa de notícias em que o artigo de ontem deve ter uma classificação mais elevada do que um artigo semelhante de há três anos
Um localizador de restaurantes que dá prioridade a locais a 5 minutos de distância em vez daqueles que requerem uma viagem de 30 minutos
Uma plataforma de comércio eletrónico que dá prioridade aos produtos mais populares, mesmo quando são ligeiramente menos semelhantes à consulta de pesquisa
Todos estes cenários partilham uma necessidade comum: equilibrar a semelhança de vectores com outros factores numéricos como o tempo, a distância ou a popularidade.
Os Decay Rankers do Milvus respondem a esta necessidade ajustando as classificações de pesquisa com base em valores de campo numéricos. Permitem-lhe equilibrar a semelhança vetorial com a "frescura", a "proximidade" ou outras propriedades numéricas dos seus dados, criando experiências de pesquisa mais intuitivas e contextualmente relevantes.
Notas de utilização
A classificação de decaimento não pode ser utilizada com pesquisas de agrupamento.
O campo utilizado para a classificação de decaimento tem de ser numérico (
INT8,INT16,INT32,INT64,FLOAT, ouDOUBLE).Cada classificador de desvalorização só pode utilizar um campo numérico.
Consistência da unidade de tempo: Ao utilizar a classificação de decaimento baseada no tempo, as unidades dos parâmetros
origin,scaleeoffsetdevem corresponder às unidades utilizadas nos dados da sua coleção:Se a sua coleção armazena carimbos de data/hora em segundos, utilize segundos para todos os parâmetros
Se a sua coleção armazena carimbos de data/hora em milissegundos, utilize milissegundos para todos os parâmetros
Se a sua coleção armazena carimbos de data/hora em microssegundos, utilize microssegundos para todos os parâmetros
Como funciona
A classificação decrescente melhora a pesquisa vetorial tradicional ao incorporar factores numéricos como o tempo ou a distância geográfica no processo de classificação. O processo inteiro segue estas etapas:
Etapa 1: Calcular as pontuações de similaridade normalizadas
Primeiro, o Milvus calcula e normaliza as pontuações de similaridade dos vectores para garantir uma comparação consistente:
Para as métricas de distância L2 e JACCARD (em que valores mais baixos indicam maior semelhança):
normalized_score = 1.0 - (2 × arctan(score))/πIsto transforma as distâncias em pontuações de semelhança entre 0-1, em que quanto maior for, melhor.
Para as métricas IP, COSINE e BM25 (em que pontuações mais altas já indicam melhores correspondências): As pontuações são usadas diretamente sem normalização.
Etapa 2: Calcular as pontuações de decaimento
Em seguida, o Milvus calcula uma pontuação de deterioração com base no valor do campo numérico (como carimbo de data/hora ou distância) utilizando o classificador de deterioração selecionado:
Cada classificador de deterioração transforma valores numéricos brutos em pontuações de relevância normalizadas entre 0-1
A pontuação de deterioração representa o grau de relevância de um item com base na sua "distância" do ponto ideal
A fórmula de cálculo específica varia consoante o tipo de classificador de deterioração. Para obter detalhes sobre como calcular uma pontuação de decaimento, consulte as páginas dedicadas ao Decaimento gaussiano, Decaimento exponencial e Decaimento linear.
Etapa 3: Calcular as pontuações finais
Finalmente, o Milvus combina a pontuação de similaridade normalizada e a pontuação de decaimento para produzir a pontuação de classificação final:
final_score = normalized_similarity_score × decay_score
Nos casos de pesquisa híbrida (combinando múltiplos campos vectoriais), Milvus utiliza a pontuação máxima de similaridade normalizada entre os pedidos de pesquisa:
final_score = max([normalized_score₁, normalized_score₂, ..., normalized_scoreₙ]) × decay_score
Por exemplo, se um artigo de investigação tiver uma pontuação de 0,82 na similaridade vetorial e 0,91 na recuperação de texto com base no BM25 numa pesquisa híbrida, o Milvus utiliza 0,91 como pontuação de similaridade de base antes de aplicar o fator de decaimento.
Classificação decrescente em ação
Vejamos a classificação decrescente num cenário prático - pesquisa de "artigos de investigação de IA" com decrescimento baseado no tempo:
Neste exemplo, as pontuações de decaimento reflectem a forma como a relevância diminui com o tempo - os documentos mais recentes recebem pontuações mais próximas de 1,0, os documentos mais antigos recebem pontuações mais baixas. Estes valores são calculados utilizando um classificador de decaimento específico. Para obter detalhes, consulte Escolher o classificador de deterioração correto.
Artigo |
Similaridade do vetor |
Pontuação de similaridade normalizada |
Data de publicação |
Pontuação de decaimento |
Pontuação final |
Classificação final |
|---|---|---|---|---|---|---|
Papel A |
Alta |
0,85 ( |
2 semanas atrás |
0.80 |
0.68 |
2 |
Papel B |
Muito elevado |
0,92 ( |
6 meses atrás |
0.45 |
0.41 |
3 |
Papel C |
Média |
0.75 ( |
1 dia atrás |
0.98 |
0.74 |
1 |
Papel D |
Médio-Alto |
0.76 ( |
3 semanas atrás |
0.70 |
0.53 |
4 |
Sem o decay reranking, o Documento B teria a classificação mais elevada com base na semelhança vetorial pura (0,92). No entanto, com a classificação decrescente aplicada:
O artigo C salta para a posição #1 apesar da similaridade média porque é muito recente (publicado ontem)
O artigo B desce para a posição #3, apesar da excelente semelhança, porque é relativamente antigo
O artigo D utiliza a distância L2 (em que quanto menor for, melhor), pelo que a sua pontuação é normalizada de 1,2 para 0,76 antes de aplicar a desclassificação
Escolher o classificador de decaimento correto
A Milvus oferece diferentes classificadores de desvalorização - gauss, exp, linear, cada um concebido para casos de utilização específicos:
Classificador de decaimento |
Caraterísticas |
Casos de uso ideais |
Cenário de exemplo |
|---|---|---|---|
Gaussiano ( |
Declínio gradual natural que se estende moderadamente |
|
Numa pesquisa de restaurantes, os locais de qualidade a 3 km de distância permanecem detectáveis, embora com uma classificação inferior às opções mais próximas |
Exponencial ( |
Diminui rapidamente no início, mas mantém uma cauda longa |
|
Numa aplicação de notícias, as histórias de ontem têm uma classificação muito mais elevada do que o conteúdo de uma semana atrás, mas ainda podem aparecer artigos mais antigos altamente relevantes |
Linear ( |
Declínio consistente e previsível com um corte claro |
|
Num localizador de eventos, os eventos para além de uma janela futura de duas semanas simplesmente não aparecem |
Para obter informações detalhadas sobre como cada classificador de decaimento calcula as pontuações e os padrões de declínio específicos, consulte a documentação dedicada:
Exemplo de implementação
Os classificadores de decaimento podem ser aplicados tanto à pesquisa vetorial padrão como às operações de pesquisa híbrida em Milvus. Abaixo estão os principais trechos de código para implementar esse recurso.
Antes de utilizar as funções de decaimento, deve primeiro criar uma coleção com campos numéricos apropriados (como carimbos de data/hora, distâncias, etc.) que serão utilizados para cálculos de decaimento. Para obter exemplos de trabalho completos, incluindo a configuração da coleção, a definição do esquema e a inserção de dados, consulte Tutorial: Implementar classificação baseada no tempo em Milvus.
Criar um classificador de decaimento
Para implementar a classificação de decaimento, primeiro defina um objeto Function com a configuração apropriada:
from pymilvus import Function, FunctionType
# Create a decay function for timestamp-based decay
# Note: All time parameters must use the same unit as your collection data
decay_ranker = Function(
name="time_decay", # Function identifier
input_field_names=["timestamp"], # Numeric field to use for decay
function_type=FunctionType.RERANK, # Must be set to RERANK for decay rankers
params={
"reranker": "decay", # Specify decay reranker. Must be "decay"
"function": "gauss", # Choose decay function type: "gauss", "exp", or "linear"
"origin": int(datetime.datetime(2025, 1, 15).timestamp()), # Reference point (seconds)
"scale": 7 * 24 * 60 * 60, # 7 days in seconds (must match collection data unit)
"offset": 24 * 60 * 60, # 1 day no-decay zone (must match collection data unit)
"decay": 0.5 # Half score at scale distance
}
)
import io.milvus.v2.service.vector.request.ranker.DecayRanker;
import java.time.ZoneId;
import java.time.ZonedDateTime;
ZonedDateTime zdt = ZonedDateTime.of(2025, 1, 25, 0, 0, 0, 0, ZoneId.systemDefault());
DecayRanker ranker = DecayRanker.builder()
.name("time_decay")
.inputFieldNames(Collections.singletonList("timestamp"))
.function("gauss")
.origin(zdt.toInstant().toEpochMilli())
.scale(7 * 24 * 60 * 60)
.offset(24 * 60 * 60)
.decay(0.5)
.build();
import {FunctionType } from "@zilliz/milvus2-sdk-node";
const decayRanker = {
name: "time_decay",
input_field_names: ["timestamp"],
function_type: FunctionType.RERANK,
params: {
reranker: "decay",
function: "gauss",
origin: new Date(2025, 1, 15).getTime(),
scale: 7 * 24 * 60 * 60,
offset: 24 * 60 * 60,
decay: 0.5,
},
};
// go
# restful
Parâmetro |
Necessário? |
Descrição |
Valor/Exemplo |
|---|---|---|---|
|
Sim |
Identificador da sua função utilizado na execução de pesquisas. Escolha um nome descritivo relevante para o seu caso de utilização. |
|
|
Sim |
Campo numérico para cálculo da pontuação de decaimento. Determina que atributo de dados será utilizado para calcular a deterioração (por exemplo, carimbos de data/hora para deterioração baseada no tempo, coordenadas para deterioração baseada na localização). Tem de ser um campo na sua coleção que contenha valores numéricos relevantes. Suporta INT8/16/32/64, FLOAT, DOUBLE. |
|
|
Sim |
Especifica o tipo de função que está a ser criada. Tem de ser definido como |
|
|
Sim |
Especifica o método de classificação a utilizar. Tem de ser definido para |
|
|
Sim |
Especifica qual o classificador matemático de redução a aplicar. Determina a forma da curva de declínio da relevância. Consulte a secção Escolher o classificador de desvalorização correto para obter orientação sobre como selecionar a função adequada. |
|
|
Sim |
Ponto de referência a partir do qual a pontuação de decaimento é calculada. Os itens neste valor recebem pontuações de relevância máxima. Para a desvalorização baseada no tempo, a unidade de tempo deve corresponder aos seus dados de recolha. |
|
|
Sim |
Distância ou tempo em que a relevância cai para o valor Para a diminuição baseada no tempo, a unidade de tempo deve corresponder aos seus dados de recolha. Valores maiores criam um declínio mais gradual na relevância; valores menores criam um declínio mais acentuado. |
|
|
Não |
Cria uma "zona sem decaimento" à volta de Para a deterioração baseada no tempo, a unidade de tempo deve corresponder aos seus dados de recolha. Os itens dentro deste intervalo do |
|
|
Não |
Valor da pontuação na distância Deve estar entre 0 e 1. |
|
Aplicar à pesquisa vetorial padrão
Depois de definir o seu classificador de decaimento, pode aplicá-lo durante as operações de pesquisa, passando-o para o parâmetro ranker:
# Use the decay function in standard vector search
results = milvus_client.search(
collection_name,
data=[your_query_vector], # Replace with your query vector
anns_field="vector_field",
limit=10,
output_fields=["document", "timestamp"], # Include the decay field in outputs to see values
ranker=decay_ranker, # Apply the decay ranker here
consistency_level="Strong"
)
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.data.EmbeddedText;
SearchReq searchReq = SearchReq.builder()
.collectionName(COLLECTION_NAME)
.data(Collections.singletonList(new EmbeddedText("search query")))
.annsField("vector_field")
.limit(10)
.outputFields(Arrays.asList("document", "timestamp"))
.functionScore(FunctionScore.builder()
.addFunction(ranker)
.build())
.build();
SearchResp searchResp = client.search(searchReq);
const result = await milvusClient.search({
collection_name: "collection_name",
data: [your_query_vector], // Replace with your query vector
anns_field: "dense",
limit: 10,
output_fields: ["document", "timestamp"],
rerank: ranker,
consistency_level: "Strong",
});
// go
# restful