Гауссово распадениеCompatible with Milvus 2.6.x

Гауссово распадение, также известное как нормальное распадение, создает наиболее естественную корректировку результатов поиска. Подобно человеческому зрению, которое постепенно размывается с расстоянием, гауссово затухание создает плавную, колоколообразную кривую, которая плавно снижает релевантность по мере удаления объектов от вашей идеальной точки. Такой подход идеален, когда вам нужен сбалансированный распад, который не будет сильно наказывать объекты, находящиеся за пределами предпочтительного диапазона, но при этом значительно снизит релевантность удаленных объектов.

В отличие от других ранжировщиков распада:

  • Экспоненциальный распад сначала резко снижается, создавая более сильное начальное наказание.

  • Линейный спад уменьшается с постоянной скоростью, пока не достигнет нуля, создавая четкую границу

Гауссово распадение обеспечивает более сбалансированный, интуитивный подход, который кажется естественным для пользователей.

Когда использовать гауссово затухание

Гауссово затухание особенно эффективно для:

Пример использования

Пример

Почему гауссово разложение хорошо работает

Поиск по местоположению

Поиск ресторанов, локаторы магазинов

Имитирует естественное человеческое восприятие релевантности расстояния

Рекомендации по содержанию

Предложения статей на основе даты публикации

Постепенное снижение релевантности по мере старения контента

Объявления о товарах

Товары, цены на которые близки к целевым

Плавное снижение релевантности по мере отклонения цены от целевой

Подбор специалистов

Поиск профессионалов с соответствующим опытом

Сбалансированная оценка релевантности опыта

Если вашему приложению требуется естественное ощущение снижения релевантности без жестких наказаний или строгих отсечек, то гауссово затухание, скорее всего, будет лучшим выбором.

Принцип колоколообразной кривой

Гауссово затухание создает плавную, колоколообразную кривую, которая постепенно снижает релевантность по мере удаления от идеальной точки. Названное в честь математика Карла Фридриха Гаусса, это распределение часто встречается в природе и статистике, что объясняет, почему оно так интуитивно понятно для человеческого восприятия.

Gaussian Decay Гауссово распадение

На графике выше показано, как гауссово затухание повлияет на рейтинг ресторанов в мобильном поисковом приложении:

  • origin (0 км): Ваше текущее местоположение, где релевантность максимальна (1,0).

  • offset (±300 m): "Зона идеальной оценки" вокруг вас - все рестораны в радиусе 300 метров сохраняют полную оценку релевантности (1,0), гарантируя, что очень близкие варианты не будут подвергаться ненужному наказанию за крошечную разницу в расстоянии.

  • scale (±2 км): Расстояние, на котором релевантность снижается до значения распада - рестораны, расположенные на расстоянии ровно 2 км, получают вдвое меньше баллов релевантности (0,5).

  • decay (0.5): Оценка на расстоянии шкалы - этот параметр, по сути, управляет тем, как быстро снижаются оценки с расстоянием.

Как видно из кривой, рестораны, расположенные дальше 2 км, продолжают снижать свою релевантность, но так и не достигают нуля. Даже рестораны, расположенные на расстоянии 4-5 километров, сохраняют минимальную релевантность, что позволяет отличным, но удаленным ресторанам по-прежнему появляться в результатах (хотя и занимать более низкие места).

Такое поведение имитирует естественное восприятие людьми релевантности расстояния - близлежащие заведения предпочтительнее, но мы готовы отправиться дальше, чтобы получить исключительные варианты.

Формула

Математическая формула для расчета показателя гауссова распада выглядит следующим образом:

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)

Где:

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

Выражаясь простым языком:

  1. Вычислите, как далеко значение поля находится от начала: ∣fieldvaluedoc-origin∣|fieldvalue_{doc} - origin| .

  2. Вычтите смещение (если оно есть), но никогда не опускайтесь ниже нуля: max(0,расстояние-смещение)\max (0, расстояние - смещение)

  3. Возведите в квадрат это скорректированное расстояние: (скорректированное_расстояние)2(скорректированное\расстояние)^2 2

  4. Разделите на 2σ22\sigma^2 2, которая рассчитывается из параметров масштаба и распада.

  5. Возьмите отрицательную экспоненту, которая дает значение между 0 и 1: exp(-value)\exp (-value).

Расчет σ2\sigma^{2} 2 преобразует ваши параметры масштаба и затухания в квадрат стандартного отклонения для гауссова распределения. Именно это придает функции характерную колоколообразную форму.

Использование гауссова затухания

Гауссово затухание можно применять как к стандартному векторному поиску, так и к гибридным операциям поиска в Milvus. Ниже приведены ключевые фрагменты кода для реализации этой функции.

Прежде чем использовать функции распада, необходимо создать коллекцию с соответствующими числовыми полями (например, временными метками, расстояниями и т. д.), которые будут использоваться для расчетов распада. Полные рабочие примеры, включающие настройку коллекции, определение схемы и вставку данных, см. в разделе Учебник: Реализация ранжирования по времени в Milvus.

Создание ранжировщика распада

После того как коллекция настроена с числовым полем (в данном примере distance в метрах от пользователя), создайте ранжировщик с гауссовым распадом:

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

Определив ранжировщик распада, вы можете применить его во время поисковых операций, передав его в параметр 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