Decaimento linearCompatible with Milvus 2.6.x
A decomposição linear cria um declínio em linha reta que termina num ponto zero absoluto nos seus resultados de pesquisa. À semelhança de uma contagem decrescente de eventos futuros, em que a relevância diminui gradualmente até que o evento tenha passado, a decomposição linear aplica uma redução previsível e constante da relevância à medida que os itens se afastam do ponto ideal até desaparecerem completamente. Esta abordagem é ideal quando se pretende uma taxa de redução consistente com um limite claro, garantindo que os itens para além de um determinado limite são completamente excluídos dos resultados.
Ao contrário de outras funções de decaimento:
O decaimento gaussiano segue uma curva em forma de sino que se aproxima gradualmente, mas nunca chega a zero
O decaimento exponencial mantém uma cauda longa de relevância mínima que se estende indefinidamente
O decaimento linear cria exclusivamente um ponto final definitivo, tornando-o particularmente eficaz para aplicações com limites naturais ou prazos.
Quando utilizar o decaimento linear
O decaimento linear é particularmente eficaz para:
Caso de utilização |
Exemplo |
Porque é que o linear funciona bem |
|---|---|---|
Listagens de eventos |
Plataformas de bilhetes para concertos |
Cria um limite claro para eventos demasiado distantes no futuro |
Ofertas por tempo limitado |
Vendas rápidas, promoções |
Garante que as ofertas expiradas ou que estão prestes a expirar não aparecem |
Raio de entrega |
Entrega de comida, serviços de correio |
Impõe limites geográficos rígidos |
Conteúdo com restrição de idade |
Plataformas de encontros, serviços multimédia |
Estabelece limites de idade rígidos |
Escolha o decaimento linear quando:
A sua aplicação tem um limite natural, um prazo ou um limiar
Os itens que ultrapassam um determinado ponto devem ser completamente excluídos dos resultados
Necessita de uma taxa de declínio de relevância previsível e consistente
Os utilizadores devem ver uma demarcação clara entre itens relevantes e irrelevantes
Princípio do declínio constante
O declínio linear cria uma queda em linha reta que diminui a uma taxa constante até atingir exatamente zero. Este padrão aparece em muitos cenários quotidianos, como temporizadores de contagem decrescente, esgotamento de inventário e abordagens de prazos em que a relevância tem um ponto de expiração claro.
Todos os parâmetros de tempo (origin, offset, scale) devem utilizar a mesma unidade que os dados da coleção. Se a sua coleção armazena carimbos de data/hora numa unidade diferente (milissegundos, microssegundos), ajuste todos os parâmetros em conformidade.
Decaimento linear
O gráfico acima mostra como o decaimento linear afetaria as listagens de eventos em uma plataforma de emissão de bilhetes:
origin(data atual): O momento atual, onde a relevância está no seu máximo (1,0).offset(1 dia): A "janela de eventos imediatos" - todos os eventos que acontecem no dia seguinte mantêm pontuações de relevância completas (1,0), garantindo que eventos muito iminentes não sejam penalizados por pequenas diferenças de tempo.decay(0.5): A pontuação na distância da escala - este parâmetro controla a taxa de declínio da relevância.scale(10 dias): O período de tempo em que a relevância cai para o valor de decaimento - eventos a 10 dias de distância têm suas pontuações de relevância reduzidas à metade (0,5).
Como pode ver na curva em linha reta, os eventos a mais de 16 dias de distância têm exatamente zero de relevância e não aparecem nos resultados de pesquisa. Isto cria um limite claro que garante que os utilizadores só vêem os próximos eventos relevantes dentro de uma janela de tempo definida.
Este comportamento reflecte a forma como o planeamento de eventos funciona normalmente - os eventos mais recentes são mais relevantes, os eventos nas próximas semanas têm uma importância cada vez menor e os eventos demasiado distantes no futuro (ou já passados) não devem aparecer de todo.
Fórmula
A fórmula matemática para calcular uma pontuação de decaimento linear é:
Onde:
Desdobrando isto em linguagem simples:
Calcule a distância que o valor do campo está da origem:
Subtrair o desvio (se existir) mas nunca abaixo de zero: \max
Determine o parâmetro s a partir dos seus valores de escala e decaimento.
Subtraia a distância ajustada de s e divida por s
Certifique-se de que o resultado nunca é inferior a zero: \max 0
O cálculo de s transforma os seus parâmetros de escala e decaimento no ponto em que a pontuação atinge zero. Por exemplo, com decaimento=0,5 e escala=7, a pontuação atingirá exatamente zero na distância=14 (duas vezes o valor da escala).
Utilizar a atenuação linear
O decaimento linear pode ser aplicado 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 esta funcionalidade.
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 do Decay Ranker.
Criar um classificador de decaimento
Depois de a coleção estar configurada com um campo numérico (neste exemplo, event_date como segundos a partir de agora), crie um classificador de decaimento linear:
Consistência da unidade de tempo: Ao usar o decaimento baseado em tempo, certifique-se de que os parâmetros origin, scale e offset usem a mesma unidade de tempo que os 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 ela usar milissegundos, use milissegundos para todos os parâmetros.
from pymilvus import Function, FunctionType
import time
# Calculate current time
current_time = int(time.time())
# Create a linear decay ranker for event listings
# Note: All time parameters must use the same unit as your collection data
ranker = Function(
name="event_relevance", # Function identifier
input_field_names=["event_date"], # Numeric field to use
function_type=FunctionType.RERANK, # Function type. Must be RERANK
params={
"reranker": "decay", # Specify decay reranker
"function": "linear", # Choose linear decay
"origin": current_time, # Current time (seconds, matching collection data)
"offset": 12 * 60 * 60, # 12 hour immediate events window (seconds)
"decay": 0.5, # Half score at scale distance
"scale": 7 * 24 * 60 * 60 # 7 days (in seconds, matching collection data)
}
)
import io.milvus.v2.service.vector.request.ranker.DecayRanker;
DecayRanker ranker = DecayRanker.builder()
.name("event_relevance")
.inputFieldNames(Collections.singletonList("event_date"))
.function("linear")
.origin(System.currentTimeMillis())
.offset(12 * 60 * 60)
.decay(0.5)
.scale(7 * 24 * 60 * 60)
.build();
import { FunctionType } from "@zilliz/milvus2-sdk-node";
const ranker = {
name: "event_relevance",
input_field_names: ["event_date"],
type: FunctionType.RERANK,
params: {
reranker: "decay",
function: "linear",
origin: new Date(2025, 1, 15).getTime(),
offset: 12 * 60 * 60,
decay: 0.5,
scale: 7 * 24 * 60 * 60,
},
};
// go
# restful
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:
# Apply decay ranker to vector search
result = milvus_client.search(
collection_name,
data=[your_query_vector], # Replace with your query vector
anns_field="dense", # Vector field to search
limit=10, # Number of results
output_fields=["title", "venue", "event_date"], # Fields to return
ranker=ranker, # Apply the decay ranker
consistency_level="Strong"
)
import io.milvus.v2.common.ConsistencyLevel;
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.response.SearchResp;
import io.milvus.v2.service.vector.request.data.FloatVec;
SearchReq searchReq = SearchReq.builder()
.collectionName(COLLECTION_NAME)
.data(Collections.singletonList(new FloatVec(embedding)))
.annsField("dense")
.limit(10)
.outputFields(Arrays.asList("title", "venue", "event_date"))
.functionScore(FunctionScore.builder()
.addFunction(ranker)
.build())
.consistencyLevel(ConsistencyLevel.STRONG)
.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: ["title", "venue", "event_date"],
rerank: ranker,
consistency_level: "Strong",
});
// go
# restful