Анализ отзывов с embeddings и GPT: пошаговый гайд 2026 | AiManual
AiManual Logo Ai / Manual.
08 Июл 2026 Гайд

Автоматизация анализа отзывов с помощью Embeddings и GPT: пошаговое руководство

Научитесь автоматически анализировать тысячи отзывов с помощью embeddings и GPT. Пошаговое руководство с кодом, кластеризацией и генерацией инсайтов.

Каждый день пользователи оставляют тысячи отзывов. Это кладезь идей, но прочитать всё — миссия невыполнима. Большинство компаний закапываются в Excel, ругают маркетплейсы и в итоге пропускают главное: системные боли клиентов. Я покажу, как заставить embeddings и GPT работать на вас, не сломав бюджет.

Мы построим пайплайн, который сам найдёт повторяющиеся проблемы, сгруппирует их по темам и напишет краткий отчёт. Заодно разберёмся, где эмбеддинги спасают, а где GPT вытягивает один.

Ключевая идея: embeddings — быстрый семантический поиск и кластеризация, GPT — умная генерация сводок. Они не конкуренты, а напарники.

Почему старые методы не работают

Тональность через регулярки? Словари ключевых слов? В 2026 году это даже смешно. Отзывы полны сарказма, сленга и опечаток. Попробуйте поймать фразу «ну, норм» — тональность нейтральная, но подтекст — бесит отсутствие фичи. Embeddings улавливают смысл, а не слова. GPT дорисовывает картину.

Проблема: сырых данных много, а времени на ручной анализ нет. К тому же конкуренты не дремлют — их AI-агенты уже читают ваши отзывы. Подробнее про такой сценарий я писал в SERM на автопилоте, но там речь про ответы, а здесь про анализ.

Что будем строить

Пайплайн из трёх этапов: загрузка → векторизация → анализ. В результате — список кластеров с метриками и сгенерированное summary каждого кластера. Вы узнаете, что пользователи пишут про скорость работы, про баги, про дизайн, и сможете приоритизировать фичи.

💡
Вместо GPT можно использовать любую LLM. Но на июль 2026 года GPT-5 даёт лучшее соотношение цена/качество для анализа текста. Для эмбеддингов берём text-embedding-3-small — дёшево и сердито.

Шаг 1: Готовим данные

Пусть у нас есть CSV с колонками text, rating, date. Соберите отзывы с маркетплейсов, App Store, Google Play — любой источник. Пример записи: «Приложение тормозит после обновления, вылетает при загрузке фото».

Очистка обязательна. Удаляем эмодзи (но не всегда: иногда они несут смысл), смайлы, лишние пробелы. Не удаляем стоп-слова — для эмбеддингов они не вредят, а для GPT контекст важен.

Если отзывы на разных языках — нужен перевод. В статье Автоматизация перевода блога я показывал, как перегонять тексты через ChatGPT. Можно адаптировать тот же подход.

1 Загрузка и предобработка

import pandas as pd
import re

df = pd.read_csv('reviews.csv')

def clean_text(text):
    text = re.sub(r'[\U0001F600-\U0001F64F\U0001F300-\U0001F5FF\U0001F680-\U0001F6FF\U0001F1E0-\U0001F1FF]', '', text)
    text = re.sub(r'\s+', ' ', text).strip()
    return text

df['clean_text'] = df['text'].apply(clean_text)
df = df[df['clean_text'].str.len() > 10]  # минимум 10 символов

Шаг 2: Получаем эмбеддинги

Используем модель OpenAI text-embedding-3-small. Она даёт 1536-мерные векторы. Можно взять text-embedding-3-large (3072) — точнее, но дороже. Если хотите локальное решение — посмотрите pplx-embed от Perplexity: квантованные эмбеддинги бегут на CPU.

Обратите внимание: для больших объёмов используйте batch-обработку, чтобы не превысить rate limit. В статье Автономный ИИ-сотрудник я показывал Batch API — он сэкономит вам кучу времени.

from openai import OpenAI
import numpy as np

client = OpenAI(api_key='YOUR_KEY')

def get_embedding(text):
    resp = client.embeddings.create(
        model='text-embedding-3-small',
        input=text
    )
    return resp.data[0].embedding

# Прогресс-бар для наглядности
from tqdm import tqdm
tqdm.pandas()
df['embedding'] = df['clean_text'].progress_apply(get_embedding)

# Сохраняем numpy массивы
embeddings = np.array(df['embedding'].tolist())
np.save('embeddings.npy', embeddings)

Осторожнее с тарификацией: 1000 эмбеддингов через text-embedding-3-small стоят ~$0.0002. Если у вас 50000 отзывов — это $0.01. Копейки. Но GPT дороже: один промпт с отзывом может стоить $0.002 (на модели GPT-4o-mini). Планируйте бюджет.

Шаг 3: Кластеризация — находим темы

Кластеризация на эмбеддингах — стандартный приём. Я предпочитаю HDBSCAN — он не требует заранее задавать число кластеров и помечает шум. Для больших датасетов сначала делаю UMAP для снижения размерности до 50-100, затем HDBSCAN.

Почему не K-Means? Он делит данные на сферы, а реальные темы in the wild всегда асимметричны. HDBSCAN находит кластеры любой формы.

import umap
import hdbscan

reducer = umap.UMAP(n_components=50, random_state=42)
embeddings_reduced = reducer.fit_transform(embeddings)

clusterer = hdbscan.HDBSCAN(min_cluster_size=5, metric='euclidean')
cluster_labels = clusterer.fit_predict(embeddings_reduced)

df['cluster'] = cluster_labels

Метка -1 означает шум — отзывы, которые не попали ни в один кластер. Их тоже стоит проанализировать отдельно: возможно, там редкие, но важные баги.

Кстати, если вам нужно извлечь из отзывов конкретные сущности (названия функций, версии), попробуйте GLiNER2 — он запускается на CPU и неплохо вытягивает NER без GPU.

Шаг 4: GPT генерирует инсайты для каждого кластера

Теперь у нас есть группы похожих отзывов. В каждой группе — десятки или сотни фраз. Человеку лень читать всё, а GPT — нет. Мы попросим LLM написать краткое саммари кластера: о чём говорят, какие эмоции, что предлагают.

Важный нюанс: не пихайте в один промпт все отзывы кластера — токены кончатся. Стратегия: взять 5-10 самых репрезентативных (ближайших к центроиду кластера) плюс случайную выборку. Или используйте подход RAG: подайте в контекст только те, чья косинусная близость к центру выше порога.

from sklearn.metrics.pairwise import cosine_similarity
import random

def get_representative_reviews(cluster_df, embeddings_cluster, n=10):
    centroid = np.mean(embeddings_cluster, axis=0).reshape(1, -1)
    sims = cosine_similarity(embeddings_cluster, centroid).flatten()
    top_indices = np.argsort(sims)[-n:][::-1]
    return cluster_df.iloc[top_indices]['text'].tolist()

def generate_summary(cluster_id):
    cluster_df = df[df['cluster'] == cluster_id]
    emb_cluster = embeddings[cluster_df.index]
    texts = get_representative_reviews(cluster_df, emb_cluster)
    prompt = f"""Ты аналитик отзывов. Вот несколько отзывов из одного тематического кластера.
Напиши краткое саммари (3-4 предложения) на русском: что общего, какие проблемы или пожелания, тональность.

Отзывы:
{chr(10).join(f'- {t}' for t in texts)}
"""
    resp = client.chat.completions.create(
        model='gpt-4o-mini',  # или gpt-5, если нужно глубже
        messages=[{"role": "user", "content": prompt}],
        temperature=0.3
    )
    return resp.choices[0].message.content

summaries = {}
for cluster_id in set(cluster_labels) - {-1}:
    summaries[cluster_id] = generate_summary(cluster_id)
    print(f'Кластер {cluster_id}: {summaries[cluster_id][:80]}...')

Осторожно с качеством генерации. Исследования показывают, что GPT может галлюцинировать и усреднять стиль — это подтверждает статья ChatGPT заливает вас шаблонами. Всегда проверяйте summary на реальных примерах. Не верьте LLM на слово.

Шаг 5: Собираем отчёт и визуализируем

Теперь у нас есть таблица: кластер → количество отзывов → средний рейтинг → саммари. Можно построить scatter plot (UMAP проекция) с раскраской по кластерам. Или вывести дашборд в Streamlit.

Финальный результат: за 10 минут вы знаете, что 30% отзывов — жалобы на скорость загрузки, 20% — просьбы добавить тёмную тему, 15% — восторг от нового UI. Дальше продуктовая команда решает, что фиксить.

Как не наступать на грабли

  • Слишком много кластеров. Не гоняйтесь за микротемами. 10-20 крупных кластеров полезнее, чем 100 мелких. Настройте min_cluster_size.
  • Дорогой GPT. Для больших объёмов используйте GPT-4o-mini или GPT-4.1-mini. GPT-5 — только для самых сложных саммари.
  • Утечка данных. Не отправляйте конфиденциальную информацию в облачные API. Если отзывы содержат персональные данные — анонимизируйте их через GLiNER или регулярки.
  • Игнорирование шума. Отзывы с меткой -1 могут быть единичными выбросами, а могут — сигналом о новой проблеме. Делайте выборочную проверку.

Бонус-совет: Если вам нужно не просто проанализировать, но и ответить на отзывы, комбинируйте этот пайплайн с техникой из SERM на автопилоте. Сначала кластеризуйте, потом для каждого кластера генерируйте шаблон ответа.

Неочевидный вывод: почему количество отзывов важнее качества одного?

Один отзыв — это шум. Кластер из 50 похожих отзывов — это сигнал. Embeddings + GPT превращают гору шума в чёткую карту продуктовых проблем. И да, этот подход можно масштабировать на конкурентный анализ: стяните отзывы конкурентов, запустите тот же пайплайн и смотрите, где их хвалят, а где ругают. Увидите их слабые места — и свои точки роста. В эпоху AI-поиска и AI Overviews отзывы становятся ещё важнее для видимости. Не упустите момент.

Подписаться на канал