Decaimiento linealCompatible with Milvus 2.6.x

El decaimiento lineal crea un declive en línea recta que termina en un punto cero absoluto en los resultados de búsqueda. Al igual que la cuenta atrás de un evento próximo, en la que la relevancia se desvanece gradualmente hasta que el evento ha pasado, el decaimiento lineal aplica una reducción predecible y constante de la relevancia a medida que los elementos se alejan de su punto ideal hasta que desaparecen por completo. Este enfoque es ideal cuando se desea una tasa de decaimiento consistente con un límite claro, asegurando que los elementos más allá de un cierto límite queden completamente excluidos de los resultados.

A diferencia de otras funciones de descomposición:

  • La descomposición gaussiana sigue una curva de campana que se aproxima gradualmente pero nunca llega a cero.

  • La descomposición exponencial mantiene una larga cola de relevancia mínima que se extiende indefinidamente.

El decaimiento lineal crea de forma única un punto final definitivo, lo que lo hace especialmente eficaz para aplicaciones con límites naturales o fechas límite.

Cuándo utilizar el decaimiento lineal

El decaimiento lineal es particularmente eficaz para:

Caso práctico

Ejemplo

Por qué funciona bien el decaimiento lineal

Listados de eventos

Plataformas de entradas para conciertos

Crea un límite claro para los eventos demasiado lejanos en el tiempo

Ofertas por tiempo limitado

Ventas flash, promociones

Garantiza que no aparezcan ofertas caducadas o a punto de caducar

Radio de entrega

Entrega de comida, servicios de mensajería

Impone límites geográficos estrictos

Contenido restringido por edad

Plataformas de citas, servicios multimedia

Establece umbrales de edad firmes

Elija el decaimiento lineal cuando:

  • Tu aplicación tiene un límite natural, una fecha límite o un umbral

  • Los elementos que superan un determinado punto deben excluirse completamente de los resultados

  • Necesitas una tasa de pérdida de relevancia predecible y constante.

  • Los usuarios deben ver una demarcación clara entre los elementos relevantes y los irrelevantes.

Principio de disminución constante

La decadencia lineal crea una caída en línea recta que disminuye a un ritmo constante hasta llegar exactamente a cero. Este patrón aparece en muchos escenarios cotidianos, como los temporizadores de cuenta atrás, el agotamiento de inventarios y los plazos de entrega, en los que la relevancia tiene un claro punto de caducidad.

Todos los parámetros de tiempo (origin, offset, scale) deben utilizar la misma unidad que los datos de la colección. Si su colección almacena marcas de tiempo en una unidad diferente (milisegundos, microsegundos), ajuste todos los parámetros en consecuencia.

Linear Decay Decaimiento lineal

El gráfico anterior muestra cómo el decaimiento lineal afectaría a los listados de eventos en una plataforma de venta de entradas:

  • origin (fecha actual): El momento actual, donde la relevancia es máxima (1,0).

  • offset (1 día): La "ventana de eventos inmediatos": todos los eventos que se celebren en el día siguiente mantienen una puntuación de relevancia completa (1,0), lo que garantiza que los eventos muy inminentes no se vean penalizados por pequeñas diferencias temporales.

  • decay (0.5): La puntuación a la distancia de escala: este parámetro controla la tasa de disminución de la relevancia.

  • scale (10 días): El periodo de tiempo en el que la relevancia cae hasta el valor de decaimiento-los eventos a 10 días vista tienen sus puntuaciones de relevancia reducidas a la mitad (0,5).

Como puede ver en la curva rectilínea, los eventos que se produzcan en un plazo superior a 16 días tendrán una relevancia cero y no aparecerán en los resultados de búsqueda. Esto crea un límite claro que garantiza que los usuarios sólo vean los próximos eventos relevantes dentro de una ventana temporal definida.

Este comportamiento refleja cómo funciona normalmente la planificación de eventos: los eventos inminentes son los más relevantes, los eventos de las próximas semanas tienen una importancia decreciente y los eventos demasiado lejanos en el tiempo (o ya pasados) no deberían aparecer en absoluto.

Fórmula

La fórmula matemática para calcular una puntuación de decaimiento lineal es:

S(doc)=max(smax(0,fieldvaluedocoriginoffset)s,0)S(doc) = \max\left( \frac{s - \max(0, |fieldvalue_{doc} - origin| - offset)}{s}, 0 \right)

Donde:

s=scale(1.0decay)s = \frac{scale}{(1.0 - decay)}

Desglosando esto en lenguaje sencillo:

  1. Calcular a qué distancia está el valor de campo del origen: ∣fieldvaluedoc-origin∣|fieldvalue_{doc}- origin|

  2. Restar el desplazamiento (si lo hay) pero nunca por debajo de cero: max(0,distancia-desplazamiento)\max (0, distancia - desplazamiento)

  3. Determina el parámetro ss s a partir de tus valores de escala y decaimiento.

  4. Reste la distancia ajustada de ss s y divídala por ss s

  5. Asegúrese de que el resultado nunca sea inferior a cero: max(resultado,0)\max (resultado, 0) 0

El cálculo de ss s transforma sus parámetros de escala y decaimiento en el punto en el que la puntuación llega a cero. Por ejemplo, con decaimiento=0,5 y escala=7, la puntuación llegará exactamente a cero en la distancia=14 (el doble del valor de la escala).

Utilizar el decaimiento lineal

El decaimiento lineal puede aplicarse tanto a la búsqueda vectorial estándar como a las operaciones de búsqueda híbrida en Milvus. A continuación se muestran los fragmentos de código clave para implementar esta función.

Antes de utilizar las funciones de decaimiento, primero debe crear una colección con campos numéricos apropiados (como marcas de tiempo, distancias, etc.) que se utilizarán para los cálculos de decaimiento. Para ver ejemplos de trabajo completos que incluyan la configuración de la colección, la definición del esquema y la inserción de datos, consulte Tutorial del clasificador de decaimiento.

Crear un clasificador de descomposición

Una vez configurada la colección con un campo numérico (en este ejemplo, event_date como segundos a partir de ahora), cree un clasificador de decaimiento lineal:

Consistencia de la unidad de tiempo: Cuando utilice el decaimiento basado en el tiempo, asegúrese de que los parámetros origin, scale y offset utilizan la misma unidad de tiempo que los datos de su colección. Si su colección almacena marcas de tiempo en segundos, utilice segundos para todos los parámetros. Si utiliza milisegundos, utilice milisegundos para todos los 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

Después de definir tu decay ranker, puedes aplicarlo durante las operaciones de búsqueda pasándolo al 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