中文翻译暂不可用,显示俄语原文。
Что такое hybrid search с весами (weighted hybrid) и как оптимизировать веса?
Краткий тезис
Hybrid search с весами (поиск|weighted hybrid) — это метод объединения результатов двух разных поисковых систем (обычно векторного поиска и BM25) в единую ранжированную выдачу с помощью взвешенной суммы их скоринговых функций. Вес w (от 0 до 1) управляет балансом между семантическим сходством и лексическим совпадением. Оптимизация весов — это процесс подбора w, максимизирующего метрики качества retrieval (например, Recall@k, MRR) на валидационном датасете, с помощью методов Grid Search, Random Search или Bayesian Optimization.
1. Термин: Hybrid Search (гибридный поиск)
Hybrid search — это подход, который комбинирует два или более метода поиска для улучшения качества retrieval. В контексте RAG чаще всего объединяют:
- поиск|Векторный поиск (dense retrieval) — поиск по эмбеддингам, измеряющий семантическую близость (например, cosine similarity). Хорош для парафраз, синонимов, общих концепций.
- Лексический поиск (sparse retrieval) — поиск по точным совпадениям слов (например, BM25, TF-IDF). Хорош для ключевых терминов, идентификаторов, редких слов.
Гибридный поиск берёт лучшее из двух миров: семантику плотных эмбеддингов и точность лексического совпадения.
2. Weighted Hybrid: взвешенная сумма скоров
Формула взвешенного гибрида:
score_total(doc, query) = w * score_vector(doc, query) + (1 - w) * score_bm25(doc, query)
Где:
w— вес векторного поиска (0 ≤ w ≤ 1).score_vector— нормализованный score от векторного поиска (например, cosine similarity, scaled to [0,1]).score_bm25— нормализованный score от BM25 (обычно также приводится к [0,1]).
Важно скоры должны быть нормализованы, иначе один метод может доминировать из-за масштаба. Типичные способы нормализации:
- Min-max scaling: score_norm = (score - min) / (max - min) по всей коллекции или по top-k результатам.
- Softmax / sigmoid для приведения к вероятностям.
- Rank-based normalization: замена скоров на обратные ранги (1/rank) и их взвешенное суммирование (похоже на RRF, но с весами).
3. Почему нужна оптимизация весов?
Вес w — гиперпараметр, который сильно влияет на качество поиска:
w = 1— чистый векторный поиск (семантика, но может пропускать точные термины).w = 0— чистый BM25 (точные совпадения, но теряет смысловые связи).- Оптимальное
wзависит от домена, типа запросов, качества эмбеддингов и настроек BM25.
Оптимизация весов — это поиск w, при котором метрики retrieval (Recall@k, MRR, NDCG) максимальны на репрезентативном валидационном наборе запросов с размеченными релевантными документами (gold standard).
4. Методы оптимизации весов
4.1 Grid Search (полный перебор)
Самый простой метод: задать сетку значений w (например, 0.0, 0.1, 0.2, ..., 1.0), для каждого вычислить метрику на валидации и выбрать лучшее.
Плюсы простота, воспроизводимость.
Минусы неэффективен при большом числе гиперпараметров; для одного w — приемлем.
import numpy as np
from your_retrieval_system import hybrid_search, evaluate_retrieval
best_w = None
best_recall = 0
for w in np.linspace(0, 1, 11):
scores = hybrid_search(queries, w=w)
recall = evaluate_retrieval(scores, ground_truth, k=10)
if recall > best_recall:
best_recall = recall
best_w = w
print(f"Best w: {best_w}, Recall@10: {best_recall}")
4.2 Random Search
Случайная выборка значений w из непрерывного диапазона [0,1]. Часто эффективнее Grid Search при малом числе итераций.
import random
best_w = None
best_recall = 0
for _ in range(50):
w = random.uniform(0, 1)
scores = hybrid_search(queries, w=w)
recall = evaluate_retrieval(scores, ground_truth, k=10)
if recall > best_recall:
best_recall = recall
best_w = w
4.3 Bayesian Optimization (BO)
Более продвинутый метод, строящий вероятностную модель (например, Gaussian Process) зависимости метрики от w и выбирающий следующую точку для оценки с учётом exploration/exploitation. Библиотеки: scikit-optimize, Optuna, Hyperopt.
Плюсы меньше итераций для сходимости, учитывает неопределённость. Минусы сложнее в реализации, оверхед на построение модели.
from skopt import gp_minimize
def objective(w):
scores = hybrid_search(queries, w=w[0])
recall = evaluate_retrieval(scores, ground_truth, k=10)
return -recall # минимизируем отрицательный recall
result = gp_minimize(objective, [(0.0, 1.0)], n_calls=20)
best_w = result.x[0]
5. Метрики для оптимизации весов
Выбор метрики зависит от бизнес-требований:
| Метрика | Что измеряет | Когда использовать |
|---|---|---|
| Recall@k | Доля релевантных документов в top-k | Важно не пропустить ни одного релевантного документа |
| MRR | Средний обратный ранг первого релевантного | Важна позиция первого хорошего результата |
| NDCG@k | Взвешенная сумма релевантности с учётом позиции (логарифмический штраф) | Когда релевантность не бинарна, а градуальная |
| Hit Rate@k | Доля запросов с хотя бы одним релевантным в top-k | Простейшая метрика наличия |
Обычно оптимизируют Recall@k (например, k=10) или MRR, так как они напрямую влияют на качество финального ответа LLM.
6. Практические соображения
- Нормализация скоров — критична. Если не нормализовать, BM25 (который может давать scores от 0 до 20+) задавит векторный (cosine ~0.5–0.9). Используйте min-max по top-100 результатам каждого метода.
- Переобучение — если оптимизировать
wна слишком маленьком датасете, можно подогнаться под шум. Используйте кросс-валидацию или отдельный тестовый набор. - Стабильность — оптимальный
wможет меняться со временем (при добавлении новых документов, смене эмбеддингов). Рекомендуется периодически переоценивать. - Многомерный случай — иногда добавляют отдельные веса для разных полей документа (title, body) или для разных типов запросов. Тогда оптимизация становится многомерной (Grid Search уже неэффективен, нужен Bayesian).
7. Альтернативы взвешенной сумме
- RRF (Reciprocal Rank Fusion) — комбинирует ранги, а не скоры: score = sum(1/(k + rank_i)). Не требует нормализации, но не даёт гибкости весов.
- Обучение ранжированию (Learning to Rank) — использует ML-модель (например, LambdaMART) для предсказания релевантности на основе множества фич (включая scores от BM25 и векторного поиска). Позволяет нелинейные комбинации, но требует больше данных и вычислительных ресурсов.
Weighted hybrid — простой и эффективный компромисс между RRF и полноценным LTR.
8. Пример полного пайплайна оптимизации
import numpy as np
from sklearn.metrics import recall_score # для примера
from skopt import gp_minimize
# Предположим, у нас есть функции:
# vector_search(query) -> list of (doc_id, score)
# bm25_search(query) -> list of (doc_id, score)
# normalize(scores) -> list of (doc_id, norm_score)
def hybrid_search(query, w, top_k=10):
vec_results = normalize(vector_search(query))
bm25_results = normalize(bm25_search(query))
# объединяем по doc_id
combined = {}
for doc_id, score in vec_results:
combined[doc_id] = w * score
for doc_id, score in bm25_results:
combined[doc_id] = combined.get(doc_id, 0) + (1 - w) * score
# сортируем по убыванию и берём top_k
ranked = sorted(combined.items(), key=lambda x: x[1], reverse=True)[:top_k]
return [doc_id for doc_id, _ in ranked]
def evaluate(queries, ground_truth, w, k=10):
recalls = []
for q, relevant in zip(queries, ground_truth):
retrieved = hybrid_search(q, w, top_k=k)
hits = len(set(retrieved) & set(relevant))
recalls.append(hits / len(relevant))
return np.mean(recalls)
# Оптимизация Bayesian
def objective(w):
return -evaluate(val_queries, val_ground_truth, w[0], k=10)
result = gp_minimize(objective, [(0.0, 1.0)], n_calls=30, random_state=42)
best_w = result.x[0]
print(f"Optimal w: {best_w:.3f}, Recall@10: {-result.fun:.3f}")
Пет-проект для закрепления
Задача Реализовать weighted hybrid search для небольшого корпуса текстов (например, 1000 статей из Википедии) и оптимизировать вес w.
Инструменты
sentence-transformersдля эмбеддингов (например,all-MiniLM-L6-v2).rank_bm25для BM25.scikit-optimizeилиoptunaдля Bayesian Optimization.numpy,pandas.
Шаги:
- Загрузить корпус и разбить на чанки.
- Построить векторный индекс (FAISS или
chromadb). - Построить BM25 индекс.
- Создать валидационный набор: 50 запросов с вручную размеченными релевантными документами (gold standard).
- Реализовать функцию
hybrid_search(query, w)с нормализацией скоров (min-max по top-100). - Оптимизировать
wпо Recall@10 с помощью Bayesian Optimization (20–30 итераций). - Визуализировать зависимость Recall от
w. - Сравнить с чистыми BM25 и векторным поиском.
Ожидаемый результат Вы получите оптимальный вес w (например, 0.6) и увидите, что гибрид даёт Recall@10 на 5–15% выше, чем каждый метод по отдельности.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 375 | Что такое hybrid search и какие методы комбинирования существуют? |
| 377 | Что такое RRF (Reciprocal Rank Fusion) и чем он отличается от weighted hybrid? |
| 378 | Как работает Learning to Rank для retrieval? |
| 374 | Как работает векторный поиск (dense retrieval)? |
| 373 | Как работает BM25 и его параметры? |
| 380 | Как оценивать качество retrieval в RAG? |
Навигация
- Предыдущий: 375
- Следующий: 377
- Индекс: 00. Индекс разборов