Decaimiento gaussianoCompatible with Milvus 2.6.x

El decaimiento gaussiano, también conocido como decaimiento normal, crea el ajuste más natural de los resultados de búsqueda. Al igual que la visión humana, que se difumina gradualmente con la distancia, el decaimiento gaussiano crea una curva suave en forma de campana que reduce suavemente la relevancia a medida que los elementos se alejan de su punto ideal. Este enfoque es ideal cuando se desea un decaimiento equilibrado que no penalice duramente los elementos que se encuentran justo fuera del rango preferido, pero que reduzca significativamente la relevancia de los elementos distantes.

A diferencia de otros clasificadores:

  • El decaimiento exponencial cae bruscamente al principio, creando una penalización inicial más fuerte.

  • El decaimiento lineal disminuye a un ritmo constante hasta llegar a cero, creando un límite claro.

El decaimiento gaussiano proporciona un enfoque más equilibrado e intuitivo que resulta natural para los usuarios.

Cuándo utilizar el decaimiento gaussiano

El decaimiento gaussiano es especialmente eficaz para:

Caso práctico

Ejemplo

Por qué funciona bien

Búsquedas basadas en la ubicación

Localizadores de restaurantes y tiendas

Imita la percepción humana natural de la relevancia de la distancia

Recomendaciones de contenido

Sugerencias de artículos basadas en la fecha de publicación

Disminución gradual de la relevancia a medida que el contenido envejece

Listados de productos

Artículos con precios cercanos al objetivo

Disminución suave de la relevancia a medida que los precios se desvían del objetivo

Búsqueda de expertos

Búsqueda de profesionales con experiencia relevante

Evaluación equilibrada de la relevancia de la experiencia

Si su aplicación requiere una sensación natural de disminución de la relevancia sin penalizaciones duras ni límites estrictos, el decaimiento gaussiano es probablemente su mejor opción.

Principio de la curva de Bell

El decaimiento gaussiano crea una curva suave en forma de campana que reduce gradualmente la relevancia a medida que aumenta la distancia desde un punto ideal. Esta distribución, que debe su nombre al matemático Carl Friedrich Gauss, aparece con frecuencia en la naturaleza y la estadística, lo que explica que resulte tan intuitiva para la percepción humana.

Gaussian Decay Decaimiento gaussiano

El gráfico anterior muestra cómo afectaría el decaimiento gaussiano a la clasificación de restaurantes en una aplicación de búsqueda móvil:

  • origin (0 km): Tu ubicación actual, donde la relevancia es máxima (1,0).

  • offset (±300 m): La "zona de puntuación perfecta" que le rodea: todos los restaurantes situados a menos de 300 metros mantienen una puntuación de relevancia completa (1,0), lo que garantiza que las opciones más cercanas no se vean penalizadas innecesariamente por pequeñas diferencias de distancia.

  • scale (±2 km): La distancia a la que la relevancia cae hasta el valor de decaimiento: los restaurantes situados a exactamente 2 kilómetros de distancia ven reducida a la mitad su puntuación de relevancia (0,5).

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

Como se puede ver en la curva, los restaurantes situados a más de 2 km siguen disminuyendo en relevancia, pero nunca llegan a cero. Incluso los restaurantes situados a 4-5 kilómetros conservan una relevancia mínima, lo que permite que restaurantes excelentes pero lejanos sigan apareciendo en los resultados (aunque con una clasificación inferior).

Este comportamiento imita la forma en que la gente piensa de forma natural sobre la relevancia de la distancia: se prefieren los lugares cercanos, pero estamos dispuestos a viajar más lejos para encontrar opciones excepcionales.

Fórmula

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

S(doc)=exp((max(0,fieldvaluedocoriginoffset))22σ2)S(doc) = \exp\left( -\frac{\left( \max\left(0, \left|fieldvalue_{doc} - origin\right| - offset \right) \right)^2}{2\sigma^2} \right)

Donde:

σ2=scale22ln(decay)\sigma^2 = -\frac{scale^2}{2 \cdot \ln(decay)}

Desglosándolo 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. Eleva al cuadrado esta distancia ajustada: (distancia_ajustada)2(distancia_ajustada)^2 2

  4. Dividir por 2σ22\sigma^2 2, que se calcula a partir de sus parámetros de escala y decaimiento.

  5. Tome el exponente negativo, que le da un valor entre 0 y 1: exp(-valor)\exp (-valor)

El σ2\sigma^{2} 2 cálculo convierte sus parámetros de escala y decaimiento en la desviación estándar al cuadrado para la distribución gaussiana. Esto es lo que da a la función su característica forma de campana.

Utilizar el decaimiento gaussiano

El decaimiento gaussiano 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: Implementar la clasificación basada en el tiempo en Milvus.

Crear un clasificador de decaimiento

Después de configurar su colección con un campo numérico (en este ejemplo, distance en metros desde el usuario), cree un clasificador de decaimiento gaussiano:

from pymilvus import Function, FunctionType

# Create a Gaussian decay ranker for location-based restaurant search
ranker = Function(
    name="restaurant_distance_decay",     # Function identifier
    input_field_names=["distance"],       # Numeric field for distance in meters
    function_type=FunctionType.RERANK,    # Function type. Must be RERANK
    params={
        "reranker": "decay",              # Specify decay reranker
        "function": "gauss",              # Choose Gaussian decay
        "origin": 0,                      # Your current location (0 meters)
        "offset": 300,                    # 300m no-decay zone
        "decay": 0.5,                     # Half score at scale distance
        "scale": 2000                     # 2 km scale (2000 meters)
    }
)
import io.milvus.v2.service.vector.request.ranker.DecayRanker;

DecayRanker ranker = DecayRanker.builder()
        .name("restaurant_distance_decay")
        .inputFieldNames(Collections.singletonList("distance"))
        .function("gauss")
        .origin(0)
        .offset(300)
        .decay(0.5)
        .scale(2000)
        .build();
import { FunctionType } from "@zilliz/milvus2-sdk-node";

const ranker = {
  name: "restaurant_distance_decay",
  input_field_names: ["distance"],
  function_type: FunctionType.RERANK,
  params: {
    reranker: "decay",
    function: "gauss",
    origin: 0,
    offset: 300,
    decay: 0.5,
    scale: 2000,
  },
};

// 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 restaurant 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=["name", "cuisine", "distance"],  # 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("italian restaurants")))
        .annsField("vector_field")
        .limit(10)
        .outputFields(Arrays.asList("name", "cuisine", "distance"))
        .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: ["name", "cuisine", "distance"],
  rerank: ranker,
  consistency_level: "Strong",
});
// go
# restful