Как вы анализируете embedding geometry для отладки retrieval качества?
Краткий тезис
Анализ embedding geometry (геометрии эмбеддингов) — это набор методов визуализации и количественной оценки того, как векторные представления документов и запросов распределены в пространстве. Используя UMAP/t-SNE для визуализации, метрики intra-cluster vs inter-cluster distance и average pairwise similarity, можно выявить проблемы: плохую кластеризацию по темам, аномалии (выбросы), несоответствие распределений запросов и документов. Это помогает понять, почему retrieval находит нерелевантные чанки, и направить усилия на улучшение эмбеддингов, чанкинга или индексации.
1. Термин: Embedding geometry (геометрия эмбеддингов)
Embedding geometry — это пространственное расположение векторных представлений (эмбеддингов) объектов в многомерном пространстве (обычно 768–1536 измерений). Для RAG это эмбеддинги чанков документов и запросов пользователей.
Почему это важно для отладки retrieval:
- Если эмбеддинги релевантных документов образуют плотные кластеры, а запросы попадают в те же кластеры — retrieval будет точным.
- Если кластеры перемешаны (разные темы сливаются) или запросы оказываются далеко от релевантных документов — retrieval будет плохим.
- Аномалии (выбросы) могут указывать на битые чанки, неправильный чанкинг или шум в данных.
Анализ геометрии позволяет визуально и количественно оценить эти свойства, не запуская полный пайплайн RAG.
2. Визуализация с UMAP/t-SNE
UMAP (Uniform Manifold Approximation and Projection) и t-SNE (t-distributed Stochastic Neighbor Embedding) — методы нелинейного снижения размерности до 2D или 3D для визуализации.
Как интерпретировать графики
- Кластеры: точки одного цвета (одна тема) должны группироваться вместе. Если кластеры размыты или перемешаны — эмбеддинги плохо разделяют темы.
- Аномалии: точки, изолированные от всех кластеров — возможны ошибки в данных или чанках.
- Запросы: нанесите эмбеддинги запросов (другим маркером) и посмотрите, попадают ли они в кластеры релевантных документов.
Пример кода (Python):
import umap
import matplotlib.pyplot as plt
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('all-MiniLM-L6-v2')
doc_embeddings = model.encode(documents)
query_embeddings = model.encode(queries)
reducer = umap.UMAP(n_neighbors=15, min_dist=0.1, random_state=42)
all_embeddings = np.vstack([doc_embeddings, query_embeddings])
reduced = reducer.fit_transform(all_embeddings)
doc_reduced = reduced[:len(documents)]
query_reduced = reduced[len(documents):]
plt.figure(figsize=(10,8))
plt.scatter(doc_reduced[:,0], doc_reduced[:,1], c='blue', label='documents', alpha=0.6)
plt.scatter(query_reduced[:,0], query_reduced[:,1], c='red', label='queries', alpha=0.8)
plt.legend()
plt.title('UMAP projection of document and query embeddings')
plt.show()
Ограничения t-SNE сохраняет локальную структуру, но глобальные расстояния могут быть искажены. UMAP лучше сохраняет глобальную топологию и быстрее. Используйте оба для кросс-проверки.
3. Метрики внутрикластерного и межкластерного расстояния
Для количественной оценки качества кластеризации используются intra-cluster distance (среднее расстояние между точками внутри одного кластера) и inter-cluster distance (среднее расстояние между центрами кластеров).
Формулы
- Intra-cluster distance для кластера ( C ): [ [text](/wiki/text){intra}(C) = \frac{1}{|C|(|C|-1)} \sum_{x_i \in C} \sum_{x_j \in C, j \neq i} d(x_i, x_j) ] где ( d ) — евклидово или косинусное расстояние.
- Inter-cluster distance между кластерами ( C_i ) и ( C_j ): [ [text](/wiki/text){inter}(C_i, C_j) = d(\mu_i, \mu_j) ] где ( \mu_i ) — центроид кластера.
Хорошее разделение низкое intra (точки плотно) и высокое inter (кластеры далеко). Плохое — высокое intra и низкое inter.
Пример расчёта
from sklearn.metrics import pairwise_distances
import numpy as np
def intra_cluster_distance(embeddings, labels):
unique_labels = np.unique(labels)
intra_dists = []
for label in unique_labels:
cluster_emb = embeddings[labels == label]
if len(cluster_emb) > 1:
dists = pairwise_distances(cluster_emb, metric='cosine')
intra_dists.append(np.mean(dists[np.triu_indices_from(dists, k=1)]))
return np.mean(intra_dists) if intra_dists else 0
def inter_cluster_distance(embeddings, labels):
unique_labels = np.unique(labels)
centroids = np.array([embeddings[labels == l].mean(axis=0) for l in unique_labels])
if len(centroids) > 1:
dists = pairwise_distances(centroids, metric='cosine')
return np.mean(dists[np.triu_indices_from(dists, k=1)])
return 0
Интерпретация
- Если intra ≈ inter — кластеры не разделены, эмбеддинги неинформативны.
- Если intra << inter — хорошая кластеризация.
4. Average pairwise similarity в кластерах
Average pairwise similarity — средняя косинусная схожесть между всеми парами документов внутри одного кластера. Высокая схожесть (близкая к 1) означает, что документы очень похожи — это хорошо для релевантности, но может указывать на избыточность (дубликаты). Низкая схожесть (<0.5) — кластер слишком разнороден.
Сравнение с межкластерной схожестью
- Внутрикластерная схожесть должна быть значительно выше, чем средняя схожесть между документами из разных кластеров.
- Если разница мала — эмбеддинги не различают темы.
Пример:
def average_pairwise_similarity(embeddings, labels):
from sklearn.metrics.pairwise import cosine_similarity
unique_labels = np.unique(labels)
sims = []
for label in unique_labels:
cluster_emb = embeddings[labels == label]
if len(cluster_emb) > 1:
sim_matrix = cosine_similarity(cluster_emb)
# берём верхний треугольник без диагонали
sims.append(np.mean(sim_matrix[np.triu_indices_from(sim_matrix, k=1)]))
return np.mean(sims) if sims else 0
5. Анализ распределения запросов относительно документов
Визуализация запросов на UMAP вместе с документами — ключевой шаг. Если запросы систематически попадают в «пустые» области или в кластеры нерелевантных тем, это указывает на mismatch между энкодером запроса и энкодером документа (например, разные модели или несоответствие предобработки).
Метрика query-document alignment
- Для каждого запроса найдите его k ближайших соседей среди документов (по косинусной схожести).
- Посчитайте долю соседей, которые действительно релевантны (по gold standard). Это precision@k для геометрии.
- Если precision@k низкая, но intra-cluster distances хорошие — проблема в том, что запросы «не туда» попадают.
Пример:
from sklearn.neighbors import NearestNeighbors
nn = NearestNeighbors(n_neighbors=10, metric='cosine')
nn.fit(doc_embeddings)
distances, indices = nn.kneighbors(query_embeddings)
# далее сравнить indices с gold_standard_relevant_ids
6. Выявление аномалий и выбросов
Аномалии — точки, которые находятся далеко от всех кластеров. Они могут быть:
- Битые чанки (пустые, мусорные данные).
- Чанки на другом языке.
- Выбросы из-за ошибок чанкинга (например, обрезанные предложения).
Методы обнаружения
- Расстояние до k-го ближайшего соседа: если оно аномально велико (например, >95 перцентиля) — точка-выброс.
- Isolation Forest: unsupervised метод, основанный на случайных деревьях.
- LOF (Local Outlier Factor): оценивает локальную плотность.
Пример с Isolation Forest
from sklearn.ensemble import IsolationForest
iso_forest = IsolationForest(contamination=0.05, random_state=42)
outlier_labels = iso_forest.fit_predict(doc_embeddings)
outliers = documents[outlier_labels == -1]
После выявления аномалий нужно проверить исходные документы и, возможно, удалить или перечанковать их.
7. Инструменты и библиотеки
| Инструмент | Назначение |
|---|---|
sentence-transformers | Получение эмбеддингов |
umap-learn | UMAP для визуализации |
scikit-learn | t-SNE, метрики, Isolation Forest, NearestNeighbors |
matplotlib / plotly | Построение графиков |
faiss | Быстрый поиск ближайших соседей для больших коллекций |
numpy / scipy | Расчёты расстояний |
Рекомендация для больших датасетов (>100k чанков) используйте faiss вместо sklearn.neighbors из-за скорости.
8. Интерпретация результатов и действия
| Наблюдение | Вероятная причина | Действие |
|---|---|---|
| Кластеры плохо разделены (intra ≈ inter) | Модель эмбеддингов не подходит для домена | Сменить модель (например, bge-large-en-v1.5), дообучить (fine-tune) |
| Запросы не попадают в кластеры релевантных документов | Энкодер запроса не согласован с энкодером документа | Использовать одну модель для обоих, проверить предобработку |
| Высокая внутрикластерная схожесть (>0.95) | Избыточность чанков (дубликаты) | Дедупликация, увеличение размера чанка |
| Аномалии (выбросы) | Битые данные, шум | Очистка данных, улучшение чанкинга |
| Кластеры есть, но запросы попадают в несколько кластеров | Запросы многозначные или широкие | Использовать query rewriting или multi-vector retrieval |
9. Связь с другими аспектами RAG
- Качество чанкинга: плохой чанкинг (слишком короткие/длинные чанки) приводит к размытым кластерам.
- Выбор модели эмбеддингов: разные модели дают разную геометрию. Анализ помогает выбрать лучшую.
- Настройка индекса (HNSW, IVF): параметры индекса влияют на recall, но геометрия остаётся той же. Анализ геометрии помогает понять, стоит ли менять индекс.
- Влияние на финальный ответ LLM: если геометрия плохая, LLM получит нерелевантный контекст → ответ будет плохим.
10. Пет-проект для закрепления
Задача Проанализировать геометрию эмбеддингов для датасета из 5000 документов (например, статьи Wikipedia по 5 темам) и 100 запросов. Визуализировать, посчитать метрики, выявить аномалии, сделать выводы.
Инструменты Python, sentence-transformers, umap-learn, scikit-learn, matplotlib, numpy.
Шаги:
- Загрузить датасет (можно взять wikipedia из datasets или сгенерировать синтетические тексты по темам).
- Разбить на чанки по 512 токенов (например, RecursiveCharacterTextSplitter).
- Получить эмбеддинги чанков с помощью all-MiniLM-L6-v2.
- Применить UMAP (n_neighbors=15, min_dist=0.1) для снижения размерности.
- Построить scatter plot, раскрасив точки по темам.
- Рассчитать intra-cluster и inter-cluster distances (по темам как кластеры).
- Рассчитать average pairwise similarity внутри каждой темы.
- Нанести запросы на тот же UMAP, оценить визуально.
- Использовать Isolation Forest для поиска аномалий, вывести 10 самых подозрительных чанков.
- Написать отчёт: графики, метрики, интерпретация, рекомендации.
Ожидаемый результат Отчёт (Jupyter notebook) с визуализациями, таблицами метрик и выводами. Например: «Кластеры тем хорошо разделены (intra=0.3, inter=0.8), но запросы по теме «физика» частично попадают в кластер «математика» — требуется fine-tune энкодера запросов».
11. Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 5 | Как вы оцениваете качество retrieval'а в RAG-системе? |
| 6 | Как выбрать модель эмбеддингов для RAG? |
| 7 | Как уменьшить latency RAG-системы? |
| 8 | Как обрабатывать запросы, на которые нет ответа в документах? |
| 9 | Как обновлять документы в существующей RAG-системе? |
| 10 | Что такое Self-RAG и когда его использовать? |
12. Навигация
- Предыдущий: 284
- Следующий: 286
- Индекс: 00. Индекс разборов
Навигация
- Предыдущий: 284
- Следующий: 286
- Индекс: 00. Индекс разборов