Линейный распадCompatible with Milvus 2.6.x
Линейный распад создает прямолинейный спад, который заканчивается в абсолютной нулевой точке в результатах поиска. Как и в случае с обратным отсчетом времени, когда актуальность события постепенно снижается до тех пор, пока оно не пройдет, линейный распад обеспечивает предсказуемое, устойчивое снижение актуальности по мере удаления элементов от вашей идеальной точки, пока они полностью не исчезнут. Этот подход идеален, когда вам нужна последовательная скорость распада с четкой границей, гарантирующей, что элементы, выходящие за определенную границу, будут полностью исключены из результатов.
В отличие от других функций распада:
Гауссово распадение следует колоколообразной кривой, которая постепенно приближается, но никогда не достигает нуля.
Экспоненциальный распад поддерживает длинный хвост минимальной релевантности, который тянется бесконечно долго.
Линейное затухание уникальным образом создает определенную конечную точку, что делает его особенно эффективным для приложений с естественными границами или сроками.
Когда использовать линейное затухание
Линейное затухание особенно эффективно для:
Пример использования |
Пример |
Почему линейное затухание хорошо работает |
|---|---|---|
Списки мероприятий |
Платформы по продаже билетов на концерты |
Создает четкую границу для событий, которые произойдут слишком далеко в будущем |
Ограниченные по времени предложения |
Срочные распродажи, акции |
Гарантирует, что предложения с истекшим сроком действия или скоро истекающие предложения не появятся. |
Радиус доставки |
Доставка еды, курьерские службы |
Обеспечивает жесткие географические границы |
Контент с возрастными ограничениями |
Платформы знакомств, медиасервисы |
Устанавливает твердые возрастные пороги |
Выбирайте линейное затухание, когда:
У вашего приложения есть естественная граница, крайний срок или порог.
Объекты, превышающие определенный порог, должны быть полностью исключены из результатов
Вам нужна предсказуемая, последовательная скорость снижения релевантности
Пользователи должны видеть четкую границу между релевантными и нерелевантными элементами.
Принцип равномерного снижения
Линейный спад создает прямую линию, которая уменьшается с постоянной скоростью, пока не достигнет нуля. Эта модель проявляется во многих повседневных сценариях, таких как таймеры обратного отсчета, истощение запасов и приближение сроков, когда актуальность имеет четкую точку истечения.
Все временные параметры (origin, offset, scale) должны использовать ту же единицу измерения, что и данные коллекции. Если ваша коллекция хранит временные метки в других единицах (миллисекунды, микросекунды), настройте все параметры соответствующим образом.
Линейный распад
На графике выше показано, как линейное затухание влияет на объявления о мероприятиях на платформе по продаже билетов:
origin(текущая дата): Текущий момент, когда актуальность максимальна (1.0).offset(1 день): "Окно ближайших событий" - все события, происходящие в течение следующего дня, сохраняют полную релевантность (1,0), гарантируя, что очень скорые события не будут наказаны за небольшую разницу во времени.decay(0.5): Оценка на расстоянии шкалы - этот параметр регулирует скорость снижения релевантности.scale(10 дней): Период времени, в течение которого релевантность падает до значения распада - события, произошедшие через 10 дней, имеют вдвое меньший балл релевантности (0,5).
Как видно из прямолинейной кривой, события, происходящие примерно через 16 дней, имеют нулевую релевантность и вообще не появляются в результатах поиска. Это создает четкую границу, которая гарантирует, что пользователи увидят только релевантные предстоящие события в определенном временном промежутке.
Такое поведение отражает то, как обычно происходит планирование мероприятий: ближайшие события наиболее актуальны, события в ближайшие недели имеют все меньшую значимость, а события слишком далекого будущего (или уже прошедшего) не должны появляться вообще.
Формула
Математическая формула для расчета линейной оценки распада выглядит следующим образом:
Где:
Выражаясь простым языком:
Вычислите, насколько далеко значение поля находится от истока: .
Вычтите смещение (если оно есть), но не опускайтесь ниже нуля: \max
Определите параметр s из значений масштаба и затухания.
Вычтите скорректированное расстояние из s и разделите на s.
Убедитесь, что результат никогда не опускается ниже нуля: \max 0
Вычисление s преобразует ваши параметры масштабирования и затухания в точку, в которой результат достигает нуля. Например, при затухании=0,5 и масштабе=7 оценка достигнет нуля на расстоянии=14 (удвоенное значение масштаба).
Использование линейного затухания
Линейное затухание можно применять как к стандартному векторному поиску, так и к гибридным операциям поиска в Milvus. Ниже приведены ключевые фрагменты кода для реализации этой функции.
Перед использованием функций разложения необходимо создать коллекцию с соответствующими числовыми полями (например, временными метками, расстояниями и т. д.), которые будут использоваться для расчетов разложения. Полные рабочие примеры, включающие настройку коллекции, определение схемы и вставку данных, см. в разделе Decay Ranker Tutorial.
Создание ранжировщика распада
После того как коллекция будет настроена с числовым полем (в данном примере event_date в виде секунд от настоящего момента), создайте линейный ранжировщик распада:
Согласованность единиц времени: При использовании распада на основе времени убедитесь, что параметры origin, scale и offset используют ту же единицу времени, что и данные коллекции. Если коллекция хранит временные метки в секундах, используйте секунды для всех параметров. Если она использует миллисекунды, используйте миллисекунды для всех параметров.
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
Применение к стандартному векторному поиску
Определив свой ранжировщик распада, вы можете применить его в операциях поиска, передав его в параметр 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