Кластеризация и визуализация эмбеддингов
Примените кластеризацию методом k-средних к набору эмбеддингов и визуализируйте их в двумерном пространстве с помощью UMAP, чтобы обнаружить естественные тематические группы в данных.
«Кластеризация и визуализация эмбеддингов» — бесплатный урок AI Engineering Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения AI Engineering Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс AI Engineering Academy содержит 4 уроков всего.
Зачем кластеризовать векторные представления?
Если у вас сотни или тысячи документов, часто хочется понять, какие темы в них представлены, не читая всё вручную. Кластеризация векторных представлений автоматически объединяет семантически похожие документы и показывает естественную структуру данных.
Распространённые применения: автоматическая разметка обращений в службу поддержки, выявление категорий содержимого, поиск избыточных документов и анализ наиболее частых запросов пользователей.
Обзор кластеризации методом k-средних
Метод k-средних разделяет n точек данных на k кластеров: на каждой итерации он назначает каждую точку ближайшему центроиду, а затем пересчитывает центроиды как среднее назначенных точек. Алгоритм завершается, когда назначения перестают изменяться.
Для векторных представлений метод k-средних находит близкие точки в многомерном пространстве и фактически группирует документы по семантическому сходству.
from sklearn.cluster import KMeans
import numpy as np
# corpus_embeddings: (n_docs, 1536) — pre-computed
corpus_embeddings = np.random.randn(200, 1536) # placeholder
kmeans = KMeans(n_clusters=5, random_state=42, n_init='auto')
kmeans.fit(corpus_embeddings)
labels = kmeans.labels_
print(f'Cluster assignments: {labels[:10]}')
print(f'Unique clusters: {set(labels)}')Выбор правильного количества кластеров
Выбор k (количества кластеров) — самая сложная часть. Метод локтя строит график инерции (суммы квадратов расстояний до центроидов) для разных значений k и ищет точку, в которой добавление новых кластеров перестаёт существенно уменьшать инерцию.
Коэффициент силуэта показывает, насколько лучше точка соответствует своему кластеру по сравнению с ближайшим другим кластером: значения, близкие к 1, лучше. Попробуйте значения k от 3 до 20 и выберите вариант с лучшим результатом.
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import numpy as np
corpus_embeddings = np.random.randn(200, 50) # placeholder (50D for speed)
best_k, best_score = 2, -1
for k in range(2, 11):
km = KMeans(n_clusters=k, random_state=42, n_init='auto')
labels = km.fit_predict(corpus_embeddings)
score = silhouette_score(corpus_embeddings, labels, sample_size=100)
print(f'k={k}: silhouette={score:.3f}')
if score > best_score:
best_score, best_k = score, k
print(f'Best k: {best_k}')Разметка кластеров с помощью LLM
После кластеризации можно попросить LLM создать понятную человеку метку для каждого кластера, передав модели несколько характерных документов из этого кластера. Так необработанные номера кластеров автоматически превращаются в содержательные названия категорий.
from openai import OpenAI
client = OpenAI()
def label_cluster(cluster_docs, n_examples=3):
examples = '\n'.join(f'- {d}' for d in cluster_docs[:n_examples])
prompt = f'Given these documents, provide a 3-word category label:\n{examples}\nLabel:'
response = client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': prompt}],
max_tokens=20
)
return response.choices[0].message.content.strip()
# Example usage:
# cluster_0_docs = [documents[i] for i in range(len(documents)) if labels[i] == 0]
# print(label_cluster(cluster_0_docs))Снижение размерности с помощью UMAP
Векторы размерностью 1536 нельзя напрямую изобразить на графике. UMAP (Uniform Manifold Approximation and Projection) уменьшает размерность многомерных данных до 2D или 3D, сохраняя структуру локальных соседств. В отличие от PCA, UMAP нелинеен и гораздо лучше сохраняет кластеры.
UMAP — стандартный выбор для визуализации текстовых векторных представлений, поскольку похожие документы остаются близко друг к другу на двумерном графике.
import umap
import numpy as np
corpus_embeddings = np.random.randn(200, 1536) # placeholder
reducer = umap.UMAP(
n_components=2,
metric='cosine', # important for text embeddings
random_state=42
)
embeddings_2d = reducer.fit_transform(corpus_embeddings)
print(f'Reduced shape: {embeddings_2d.shape}') # (200, 2)Визуализация кластеров с помощью Matplotlib
Когда у вас есть двумерные координаты от UMAP и метки кластеров от метода k-средних, простой точечный график позволяет увидеть структуру кластеров. Раскрасьте каждую точку в соответствии с меткой её кластера и добавьте названия характерных документов в виде текстовых аннотаций, чтобы график было легко интерпретировать.
import matplotlib.pyplot as plt
import numpy as np
# Assume: embeddings_2d (n, 2), labels (n,), documents list
# Placeholder data:
np.random.seed(42)
embeddings_2d = np.random.randn(50, 2)
labels = np.random.randint(0, 5, 50)
fig, ax = plt.subplots(figsize=(10, 7))
scatter = ax.scatter(
embeddings_2d[:, 0],
embeddings_2d[:, 1],
c=labels,
cmap='tab10',
s=60,
alpha=0.8
)
plt.colorbar(scatter, label='Cluster')
ax.set_title('Document Embedding Clusters (UMAP)')
plt.tight_layout()
plt.savefig('/tmp/clusters.png', dpi=150)
print('Saved cluster plot')Важные параметры UMAP
Ключевые гиперпараметры UMAP, влияющие на качество визуализации:
- n_neighbors (по умолчанию 15): большие значения отражают более глобальную структуру, меньшие показывают локальные кластеры
- min_dist (по умолчанию 0.1): насколько плотно расположены точки; меньшее значение создаёт более плотные кластеры, но увеличивает их перекрытие
- metric: для текстовых векторных представлений всегда используйте
'cosine'— евклидово расстояние здесь не подходит
Поэкспериментируйте со значениями n_neighbors от 5 до 50, чтобы найти визуализацию, лучше всего показывающую структуру ваших данных.
Иерархическая кластеризация как альтернатива
Агломеративная иерархическая кластеризация строит дерево вложенных кластеров, не требуя заранее задавать k. Чтобы получить итоговые кластеры, дерево обрезают на выбранном пороге расстояния. Это полезно, когда количество естественных тем в данных заранее неизвестно.
from sklearn.cluster import AgglomerativeClustering
import numpy as np
corpus_embeddings = np.random.randn(100, 50) # placeholder
cluster = AgglomerativeClustering(
n_clusters=None,
distance_threshold=1.5,
metric='cosine',
linkage='average'
)
labels = cluster.fit_predict(corpus_embeddings)
n_clusters = len(set(labels))
print(f'Found {n_clusters} natural clusters')Поиск выбросов и почти дубликатов
Векторные представления отлично подходят и для поиска почти дублирующихся документов. Вычислите попарное косинусное сходство всех документов и отметьте пары со сходством выше 0,95 как возможные дубликаты. Этот подход надёжнее сравнения текстов, поскольку обнаруживает и перефразированные дубликаты.
import numpy as np
def find_near_duplicates(corpus_vecs, threshold=0.95):
# corpus_vecs assumed L2-normalized
sim_matrix = corpus_vecs @ corpus_vecs.T # (n, n)
duplicates = []
n = len(corpus_vecs)
for i in range(n):
for j in range(i + 1, n):
if sim_matrix[i, j] >= threshold:
duplicates.append((i, j, float(sim_matrix[i, j])))
return duplicates
# pairs = find_near_duplicates(corpus_embeddings)
# print(f'Found {len(pairs)} near-duplicate pairs')Практический рабочий процесс кластеризации
Практический рабочий процесс кластеризации выполняется в следующем порядке:
- Создайте векторные представления всех документов с помощью
text-embedding-3-small - При необходимости уменьшите размерность до 50D с помощью UMAP перед кластеризацией (это ускоряет метод k-средних)
- Выполните кластеризацию методом k-средних, перебирая k для поиска лучшего коэффициента силуэта
- Присвойте каждому кластеру метку с помощью LLM, используя 5 характерных документов
- Визуализируйте двумерный точечный график UMAP, раскрасив точки по кластерам
- Проверьте выбросы (точки, удалённые от всех центроидов)
Ограничения кластеризации
При использовании кластеризации векторных представлений важно учитывать следующие ограничения:
- Метод k-средних предполагает сферическую форму кластеров — вытянутые или имеющие неправильную форму тематические группы могут быть разделены неверно
- Векторные представления сжимают смысл — два документа могут быть семантически близкими, но относиться к разным категориям, требующим разных действий
- Метки кластеров требуют проверки — всегда выбирайте несколько документов из каждого кластера, чтобы проверить разумность метки, созданной LLM
Используйте кластеризацию как инструмент исследования, а не как систему категоризации, принимаемую за эталон.
Быстрая проверка
Проверьте, насколько хорошо вы поняли концепции разработки ИИ из этого урока.
Итоги урока
В этом уроке Вы узнали, что k-means группирует документы по семантической близости в пространстве эмбеддингов, UMAP уменьшает размерность эмбеддингов до 2D для визуализации, используя косинусное расстояние, а показатель силуэта помогает выбрать правильное количество кластеров без размеченных данных. Далее мы выйдем за пределы поиска в памяти и рассмотрим векторные базы данных для промышленной эксплуатации.
Часто задаваемые вопросы
Урок «Кластеризация и визуализация эмбеддингов» бесплатный?
Да — полный текст урока «Кластеризация и визуализация эмбеддингов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс AI Engineering Academy, подпишись на CoddyKit PRO. Курс AI Engineering Academy содержит 4 уроков всего.
Чему я научусь в уроке «Кластеризация и визуализация эмбеддингов»?
Примените кластеризацию методом k-средних к набору эмбеддингов и визуализируйте их в двумерном пространстве с помощью UMAP, чтобы обнаружить естественные тематические группы в данных. Ты практикуешь AI Engineering Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать AI Engineering Academy?
Предыдущий опыт не требуется. AI Engineering Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Кластеризация и визуализация эмбеддингов»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке AI Engineering Academy?
Да. Каждый урок AI Engineering Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Что такое векторные эмбеддинги
- Создание эмбеддингов с помощью OpenAI
- Семантический поиск с NumPy
- Кластеризация и визуализация эмбеддингов