Анализ вкусов через эмбеддинги LLM: кластеризация фильмов, книг, музыки | AiManual
AiManual Logo Ai / Manual.
04 Янв 2026 Гайд

Data-driven анализ вкусов: как с помощью эмбеддингов LLM кластеризовать фильмы, книги и музыку

Практическое руководство по использованию эмбеддингов LLM для кластеризации культурного контента. Data-driven подход к анализу вкусов.

Ваши вкусы — это данные. Давайте их взломаем

Вы смотрите фильм "Бегущий по лезвию". Слушаете Radiohead. Читаете "Норвежский лес". Что это говорит о вас? Традиционно — ничего. Это просто список. Но если превратить эти названия в числа, а числа — в закономерности, картина меняется.

Эмбеддинги больших языковых моделей (LLM) — это не только про генерацию текста. Это про упаковку смысла в вектор. Фильм, книга, трек — это не просто название. Это сотни измерений настроения, стиля, нарратива. И эти измерения можно сравнить, сгруппировать, проанализировать.

💡
Забудьте про жанры. Жанры — это ярлыки, придуманные людьми. Кластеризация эмбеддингов находит реальные паттерны, которые не укладываются в "фантастика" или "драма". Она может выявить связь между психоделическим роком 70-х и киберпанком. Или между русской классикой и блюзом.

Почему ваши рекомендации в стримингах такие тупые

Netflix советует вам фильмы потому, что другие люди, смотревшие "Игру в кальмара", тоже смотрели "Первому игроку приготовиться". Это коллаборативная фильтрация. Она работает, но примитивно.

Эмбеддинги LLM работают иначе. Они анализируют семантику. Модель читает описание фильма, рецензии, сюжет (если дать доступ) и создает его "отпечаток". Два фильма с разными актерами и бюджетом, но с одинаковой атмосферой безысходности и моральной двусмысленности окажутся рядом в векторном пространстве. Именно так можно найти то, что вы ищете, но не знаете, как сформулировать.

1 Соберите свой культурный след

Начните с данных. Экспортируйте списки из Letterboxd, Goodreads, Last.fm или просто составьте вручную в CSV. Формат простой: тип (movie/book/track), название, автор/режиссер/исполнитель. Можно добавить год.

import pandas as pd

# Пример данных
data = [
    {"type": "movie", "title": "Blade Runner 2049", "creator": "Denis Villeneuve", "year": 2017},
    {"type": "book", "title": "Neuromancer", "creator": "William Gibson", "year": 1984},
    {"type": "track", "title": "Everything in Its Right Place", "creator": "Radiohead", "year": 2000},
    # ... еще сотни записей
]
df = pd.DataFrame(data)
print(df.head())

Не пытайтесь собрать идеальный датасет. Начните с 50-100 объектов. Качество эмбеддингов от OpenAI или даже открытых моделей (например, через Sentence Transformers) настолько высоко, что даже по названию и автору модель уловит много смысла. Хотя, конечно, полное описание было бы лучше. Если хотите глубоко проработать тексты книг, посмотрите мой гайд про тренировку LLM на EPUB.

2 Превратите названия в векторы

Здесь два пути: платный API (OpenAI, Cohere) или бесплатные локальные модели. Для начала используйте OpenAI — это просто и эффективно. Создайте промпт, который описывает контекст.

import openai
from tenacity import retry, stop_after_attempt, wait_exponential

openai.api_key = 'your-key'

@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=4, max=10))
def get_embedding(text, model="text-embedding-3-small"):
    text = text.replace("\n", " ")
    response = openai.embeddings.create(input=[text], model=model)
    return response.data[0].embedding

# Создаем текстовое описание для эмбеддинга
df['text_for_embedding'] = df.apply(
    lambda row: f"{row['title']} by {row['creator']}. Type: {row['type']}. Year: {row['year']}.", axis=1
)

# Генерируем эмбеддинги (осторожно, это может стоить денег при больших объемах)
# Рекомендую кэшировать результаты!
df['embedding'] = df['text_for_embedding'].apply(lambda x: get_embedding(x))

Почему мы добавляем тип и год? Чтобы модель знала контекст. Вектор для "Blade Runner" (фильм) будет отличаться от вектора "Blade Runner" (книга). Год помогает отделить оригинал от ремейка.

3 Упростите пространство и найдите кластеры

Эмбеддинги имеют 1536 измерений (для text-embedding-3-small). Чтобы это визуализировать, нужно уменьшить размерность. UMAP справляется с этим лучше, чем PCA, особенно для нелинейных данных.

import umap
import numpy as np
from sklearn.cluster import KMeans, DBSCAN
from sklearn.preprocessing import StandardScaler

# Преобразуем список эмбеддингов в массив
embeddings_array = np.vstack(df['embedding'].values)

# Нормализуем (важно для многих алгоритмов кластеризации)
scaler = StandardScaler()
embeddings_scaled = scaler.fit_transform(embeddings_array)

# Уменьшаем размерность до 2D для визуализации
reducer = umap.UMAP(n_components=2, random_state=42, n_neighbors=15, min_dist=0.1)
embeddings_2d = reducer.fit_transform(embeddings_scaled)

df['x'] = embeddings_2d[:, 0]
df['y'] = embeddings_2d[:, 1]

# Кластеризация K-Means (заранее задаем число кластеров)
kmeans = KMeans(n_clusters=5, random_state=42, n_init='auto')
df['cluster_kmeans'] = kmeans.fit_predict(embeddings_scaled)

# Или DBSCAN (находит кластеры автоматически, но сложнее настроить)
# dbscan = DBSCAN(eps=0.5, min_samples=3)
# df['cluster_dbscan'] = dbscan.fit_predict(embeddings_scaled)
💡
Не зацикливайтесь на идеальной кластеризации с первого раза. Поиграйте с параметрами UMAP (n_neighbors, min_dist) и количеством кластеров в K-Means. Цель — не "правильные" кластеры, а осмысленные группы, которые заставят вас сказать: "О, правда, эти вещи похожи!".

4 Визуализируйте и интерпретируйте

Разбросайте точки по графику, раскрасьте по кластерам. Используйте Plotly для интерактивности — чтобы наводить курсор и видеть названия.

import plotly.express as px

fig = px.scatter(
    df, x='x', y='y', color='cluster_kmeans',
    hover_data=['title', 'creator', 'type'],
    title='Ваша культурная вселенная в 2D',
    width=800, height=600
)
fig.update_traces(marker=dict(size=10))
fig.show()

# Сохраняем для веба
fig.write_html("my_culture_map.html")

Теперь самое интересное — интерпретация. Посмотрите, что попало в один кластер. Вы увидите связи, которые не очевидны. Может, у вас есть кластер "ностальгическая меланхолия", где собраны indie-игры, пост-панк и японские мультфильмы 90-х. Или кластер "грандиозный пессимизм" с эпическим фэнтези и дроун-металом.

Где всё ломается: главные подводные камни

Теория гладкая. Практика — колючая. Вот что может пойти не так.

Проблема Почему возникает Как исправить
Все точки сбились в кучу в центре графика Параметр min_dist в UMAP слишком мал или эмбеддинги плохо нормализованы. Увеличьте min_dist до 0.5-1.0. Используйте StandardScaler перед UMAP.
Кластеры не соответствуют интуиции Модель эмбеддингов уловила не те признаки (например, слишком много внимания году выпуска). Измените промпт для эмбеддинга: уберите год, добавьте жанр или ключевые слова. Или попробуйте другую модель эмбеддингов.
Фильмы и книги не смешиваются Модель слишком сильно разделяет типы медиа. В промпте не акцентируйте тип (movie/book/track). Или кластеризуйте каждый тип отдельно, а потом сравните.

Самая частая ошибка — ожидать, что алгоритм сам все поймет. Это не искусственный интеллект, это инструмент. Вы настраиваете его, чтобы он отражал ваше восприятие. Если кластер "драма и хеви-метал" кажется вам абсурдным, но модель упорно их объединяет — возможно, вы просто не замечали их общей агрессии и безысходности.

Не используйте этот метод как замену саморефлексии. Это зеркало, а не оракул. Если вы ненавидите классическую музыку, но алгоритм помещает вас в кластер с любителями Баха — может, стоит послушать Баха? Или пересмотреть промпт. Скорее второе.

Что дальше? За пределами кластеров

Кластеризация — только начало. С эмбеддингами можно:

  • Строить рекомендации: находить ближайших соседей для любимого фильма не по жанру, а по вектору. Это даст более точные советы, чем любой стриминг. Технически это поиск ближайших соседей в векторном пространстве — тема, которую я детально разбирал в статье про гибридный поиск для RAG.
  • Анализировать эволюцию вкусов: разбросать свои любимые альбомы по годам прослушивания и посмотреть, как ваш векторный вкус двигался в пространстве.
  • Сравниваться с другими: вычислить "центроид" ваших вкусов (средний вектор) и сравнить его с центроидом друга. Косинусное сходство покажет, насколько вы близки культурно. (Спойлер: вы скорее всего не близки.)

Главный секрет: эмбеддинги LLM — это не про технологии. Это про новый язык описания культуры. Жанры умирают. На смену приходят многомерные паттерны, которые нельзя назвать словами, но можно увидеть на графике.

Следующий шаг — добавить временную ось. Как менялись ваши кластеры с 15 до 35 лет? Это уже не анализ вкусов, это анализ личности. И здесь уже можно подключить более сложные пайплайны, о которых я писал в гайде по семантическим пайплайнам.

Попробуйте. Создайте карту своего культурного ландшафта. Увидите себя со стороны. И, возможно, следующий фильм, который вы посмотрите, будет выбран не из "похожих", а из "векторно-близких". Это другой уровень.

Вопросы, которые вы хотели задать, но боялись

Это работает с любыми языками?

Да, современные мультиязычные модели эмбеддингов (как от OpenAI) хорошо работают с русскими, английскими и другими названиями. Но если у вас много контента на редком языке, возможно, стоит поискать специализированную модель или дообучить свою.

Сколько это стоит?

Использование OpenAI Embeddings для 1000 объектов обойдется примерно в $0.10-$0.50 в зависимости от модели. Локальные модели (например, через библиотеку sentence-transformers) — бесплатно, но требуют вычислительных ресурсов и немного больше кода.

Можно ли кластеризовать не по названиям, а по описаниям или рецензиям?

Конечно. Это даже лучше. Чем больше текстовой информации вы дадите модели, тем точнее будет эмбеддинг. Вы можете скрейпить описания с Kinopoisk или Goodreads, но проверяйте условия использования. Или используйте API, если есть.

А если я хочу проанализировать только музыку или только книги?

Принцип тот же. Более того, для музыки можно использовать аудио-эмбеддинги (например, от моделей вроде CLAP), но это сложнее. Для старта хватит текстовых описаний треков и альбомов. Кстати, у меня есть отдельная статья про анализ плейлистов ИИ, где этот подход разобран детально.