Decaimiento exponencialCompatible with Milvus 2.6.x

El decaimiento exponencial crea una caída inicial pronunciada seguida de una larga cola en los resultados de búsqueda. Al igual que en un ciclo de noticias de última hora, en el que la relevancia disminuye rápidamente al principio pero algunas historias conservan su importancia con el paso del tiempo, el decaimiento exponencial aplica una fuerte penalización a los elementos que se encuentran justo por encima de su rango ideal, al tiempo que mantiene los elementos distantes descubribles. Este enfoque es ideal cuando se quiere dar prioridad a la proximidad o la actualidad, pero sin eliminar por completo las opciones más lejanas.

A diferencia de otras funciones de decaimiento:

  • El decaimiento gaussiano crea un declive más gradual, en forma de campana.

  • El decaimiento lineal disminuye a un ritmo constante hasta llegar exactamente a cero.

El decaimiento exponencial "adelanta" la penalización, aplicando la mayor parte de la reducción de relevancia al principio y manteniendo una larga cola de relevancia mínima pero distinta de cero.

Cuándo utilizar el decaimiento exponencial

El decaimiento exponencial es especialmente eficaz para:

Caso práctico

Ejemplo

Por qué funciona bien el exponencial

Fuentes de noticias

Portales de noticias de última hora

Reduce rápidamente la relevancia de las noticias más antiguas sin dejar de mostrar las historias importantes de hace días

Cronología de redes sociales

Actividad, actualizaciones de estado

Enfatiza el contenido fresco pero permite que salga a la superficie el contenido viral más antiguo

Sistemas de notificación

Priorización de alertas

Aumenta la urgencia de las alertas recientes y mantiene la visibilidad de las importantes.

Ventas flash

Ofertas por tiempo limitado

Disminuye rápidamente la visibilidad a medida que se acerca la fecha límite

Elija el decaimiento exponencial cuando:

  • Los usuarios esperan que los artículos muy recientes o cercanos dominen fuertemente los resultados

  • Los artículos más antiguos o lejanos deben seguir siendo descubiertos si son excepcionalmente relevantes.

  • La disminución de la relevancia debe ser gradual (más pronunciada al principio y más gradual después).

Principio de caída brusca

El decaimiento exponencial crea una curva que cae rápidamente al principio y luego se aplana gradualmente en una larga cola que se aproxima pero nunca llega a cero. Este patrón matemático aparece con frecuencia en fenómenos naturales como la desintegración radiactiva, el declive de la población y la relevancia de la información a lo largo del tiempo.

Todos los parámetros temporales (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.

Exp Decay Decaimiento exponencial

El gráfico anterior muestra cómo afectaría el decaimiento exponencial a la clasificación de los artículos en una plataforma digital de noticias:

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

  • offset (3 horas): La "ventana de noticias de última hora": todas las noticias publicadas en las últimas 3 horas mantienen la máxima puntuación de relevancia (1,0), lo que garantiza que las noticias muy recientes no se vean penalizadas innecesariamente por pequeñas diferencias temporales.

  • decay (0.5): La puntuación a la distancia de escala: este parámetro controla el grado en que las puntuaciones disminuyen con el tiempo.

  • scale (24 horas): El periodo de tiempo en el que la relevancia cae hasta el valor de decaimiento: los artículos de noticias con exactamente 24 horas de antigüedad tienen sus puntuaciones de relevancia reducidas a la mitad (0,5).

Como puede ver en la curva, las noticias de más de 24 horas siguen perdiendo relevancia, pero nunca llegan a cero. Incluso las historias de hace varios días conservan una relevancia mínima, lo que permite que noticias importantes pero antiguas sigan apareciendo en su feed (aunque con una clasificación inferior).

Este comportamiento imita el funcionamiento típico de la relevancia de las noticias: las noticias muy recientes dominan, pero las más antiguas pueden abrirse paso si son excepcionalmente relevantes para los intereses del usuario.

Fórmula

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

S(doc)=exp(λmax(0,fieldvaluedocoriginoffset))S(doc) = \exp\left( \lambda \cdot \max\left(0, \left|fieldvalue_{doc} - origin\right| - offset \right) \right)

Donde:

λ=ln(decay)scale\lambda = \frac{\ln(decay)}{scale}

En pocas palabras:

  1. Calcular a qué distancia se encuentra 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. Multiplica por λ\lambda, que se calcula a partir de tus parámetros de escala y decaimiento.

  4. Toma el exponente, que te da un valor entre 0 y 1: exp(λ⋅valor)\exp (\lambda \cdot valor) .

El cálculo de λ\lambda convierte sus parámetros de escala y decaimiento en el parámetro de tasa de la función exponencial. Un λ\lambda λ más negativo crea una caída inicial más pronunciada.

Utilizar el decaimiento exponencial

El decaimiento exponencial 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 los 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, publish_time), cree un clasificador de decaimiento exponencial:

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 datetime

# Create an exponential decay ranker for news recency
# Note: All time parameters must use the same unit as your collection data
ranker = Function(
    name="news_recency",                  # Function identifier
    input_field_names=["publish_time"],   # Numeric field to use
    function_type=FunctionType.RERANK,    # Function type. Must be RERANK
    params={
        "reranker": "decay",              # Specify decay reranker
        "function": "exp",                # Choose exponential decay
        "origin": int(datetime.datetime.now().timestamp()),  # Current time (seconds, matching collection data)
        "offset": 3 * 60 * 60,            # 3 hour breaking news window (seconds)
        "decay": 0.5,                     # Half score at scale distance
        "scale": 24 * 60 * 60             # 24 hours (in seconds, matching collection data)
    }
)
import io.milvus.v2.service.vector.request.ranker.DecayRanker;

DecayRanker ranker = DecayRanker.builder()
        .name("news_recency")
        .inputFieldNames(Collections.singletonList("publish_time"))
        .function("exp")
        .origin(System.currentTimeMillis())
        .offset(3 * 60 * 60)
        .decay(0.5)
        .scale(24 * 60 * 60)
        .build();


import { FunctionType } from "@zilliz/milvus2-sdk-node";

const ranker = {
  name: "news_recency",
  input_field_names: ["publish_time"],
  type: FunctionType.RERANK,
  params: {
    reranker: "decay",
    function: "exp",
    origin: new Date(2025, 1, 15).getTime(),
    offset: 3 * 60 * 60,
    decay: 0.5,
    scale: 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", "publish_time"], # 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.EmbeddedText;

SearchReq searchReq = SearchReq.builder()
        .collectionName(COLLECTION_NAME)
        .data(Collections.singletonList(new EmbeddedText("market analysis")))
        .annsField("vector_field")
        .limit(10)
        .outputFields(Arrays.asList("title", "publish_time"))
        .functionScore(FunctionScore.builder()
                .addFunction(ranker)
                .build())
        .consistencyLevel(ConsistencyLevel.STRONG)
        .build();
SearchResp searchResp = client.search(searchReq);
import { FunctionType MilvusClient } from "@zilliz/milvus2-sdk-node";

const milvusClient = new MilvusClient("http://localhost:19530");

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", "publish_time"],
  rerank: ranker,
  consistency_level: "Strong",
});

// go
# restful