Decaimento gaussianoCompatible with Milvus 2.6.x

O decaimento gaussiano, também conhecido como decaimento normal, cria o ajuste mais natural aos seus resultados de pesquisa. Tal como a visão humana que se vai esbatendo gradualmente com a distância, a decomposição gaussiana cria uma curva suave, em forma de sino, que reduz suavemente a relevância à medida que os itens se afastam do seu ponto ideal. Esta abordagem é ideal quando se pretende uma redução equilibrada que não penalize severamente os itens fora do seu intervalo preferido, mas que reduza significativamente a relevância dos itens distantes.

Ao contrário de outros classificadores de decaimento:

  • A desvalorização exponencial diminui acentuadamente no início, criando uma penalização inicial mais forte

  • A decomposição linear diminui a uma taxa constante até chegar a zero, criando um corte claro

A decomposição gaussiana fornece uma abordagem mais equilibrada e intuitiva que parece natural para os utilizadores.

Quando utilizar o decaimento gaussiano

O decaimento gaussiano é particularmente eficaz para:

Caso de utilização

Exemplo

Porque é que a Gaussian funciona bem

Pesquisas baseadas em localização

Localizadores de restaurantes, localizadores de lojas

Imita a perceção humana natural da relevância da distância

Recomendações de conteúdo

Sugestões de artigos com base na data de publicação

Diminuição gradual da relevância à medida que o conteúdo envelhece

Listagens de produtos

Itens com preços próximos de um objetivo

Diminuição suave da relevância à medida que os preços se desviam do objetivo

Correspondência de competências

Encontrar profissionais com experiência relevante

Avaliação equilibrada da relevância da experiência

Se a sua aplicação requer uma sensação natural de declínio da relevância sem penalizações severas ou cortes rigorosos, o decaimento gaussiano é provavelmente a sua melhor escolha.

Princípio da curva de sino

O decaimento gaussiano cria uma curva suave, em forma de sino, que reduz gradualmente a relevância à medida que a distância aumenta em relação a um ponto ideal. Nomeada em homenagem ao matemático Carl Friedrich Gauss, essa distribuição aparece com frequência na natureza e nas estatísticas, o que explica por que ela é tão intuitiva para a perceção humana.

Gaussian Decay Decaimento Gaussiano

O gráfico acima mostra como o decaimento gaussiano afectaria as classificações dos restaurantes numa aplicação de pesquisa móvel:

  • origin (0 km): A sua localização atual, onde a relevância está no máximo (1,0).

  • offset (±300 m): A "zona de pontuação perfeita" à sua volta - todos os restaurantes num raio de 300 metros mantêm pontuações de relevância total (1,0), garantindo que as opções muito próximas não são penalizadas desnecessariamente por pequenas diferenças de distância.

  • scale (±2 km): A distância a que a relevância cai para o valor de decaimento - os restaurantes a exatamente 2 quilómetros de distância têm as suas pontuações de relevância reduzidas para metade (0,5).

  • decay (0.5): A pontuação na distância da escala - este parâmetro controla essencialmente a rapidez com que as pontuações diminuem com a distância.

Como pode ver na curva, os restaurantes a mais de 2 km continuam a diminuir a sua relevância, mas nunca chegam a zero. Mesmo os restaurantes a 4-5 quilómetros de distância mantêm alguma relevância mínima, permitindo que restaurantes excelentes mas distantes ainda apareçam nos resultados (embora com uma classificação inferior).

Este comportamento imita a forma como as pessoas pensam naturalmente sobre a relevância da distância - os locais próximos são preferidos, mas estamos dispostos a viajar mais longe para opções excepcionais.

Fórmula

A fórmula matemática para calcular uma pontuação de decaimento gaussiano é:

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)

Onde:

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

Desdobrando isso em linguagem simples:

  1. Calcule a distância que o valor do campo está da origem: ∣fieldvaluedoc-origin∣|fieldvalue_{doc} - origin|

  2. Subtrair o desvio (se existir) mas nunca abaixo de zero: max(0,distance-offset)\max (0, distance - offset)

  3. Elevar esta distância ajustada ao quadrado: (distância_ajustada)2(distância\ajustada)^2 2

  4. Divida por 2σ22\sigma^2 2, que é calculado a partir dos seus parâmetros de escala e decaimento

  5. Tome o expoente negativo, que lhe dá um valor entre 0 e 1: exp(-value)\exp (-value)

O cálculo σ2\sigma^{2} 2 converte os parâmetros de escala e decaimento no desvio padrão ao quadrado da distribuição gaussiana. É isto que dá à função a sua forma de sino caraterística.

Utilizar o decaimento gaussiano

O decaimento gaussiano pode ser aplicado tanto à pesquisa vetorial padrão como às operações de pesquisa híbrida no 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

Depois que sua coleção for configurada com um campo numérico (neste exemplo, distance em metros do usuário), crie um classificador de decaimento 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

Depois de definir seu classificador de decaimento, você pode aplicá-lo durante as operações de pesquisa, passando-o para o 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