- BrainTools - https://www.braintools.ru -

От текста к смыслу: Embeddings, GPT и многомерные векторы в конкурентном анализе мобильных приложений

Отзывы пользователей — один из самых ценных источников информации о продукте, при этом часто клиенты описывают одну и ту же тему или проблему десятками разных слов. Раньше работать с фидбэком было долго и ресурсоемко, но с появлением Embeddings и LLM это изменилось. 

От текста к смыслу: Embeddings, GPT и многомерные векторы в конкурентном анализе мобильных приложений - 1

Меня зовут Вова Михайлов, я маркетинговый аналитик в Garage Eight. Мы развиваем международные финтех-продукты и стараемся использовать всю информацию для улучшения наших сервисов, в том числе отзывы. 

В этой статье я расскажу, как мы смогли автоматизировать и ускорить аналитику фидбэков с помощью Embeddings и GPT. Наш опыт [1] будет релевантен не только финтеху, но и любым компаниям, которые хотят научиться в реальном времени получать данные из отзывов и сравнивать себя с конкурентами. 

Предыстория: в чём проблема

  • I completed the action, but nothing changed on my side.

  • The information I expected is missing.

  • Still waiting for everything to update.

  • The expected update hasn’t come through.

Все эти отзывы относятся к одной теме, при этом различаются по лексике и тональности. Для человека очевидно, что их связывает, а для компьютера это совершенно разные наборы слов. 

В существующих приложениях, которые мы используем для сбора отзывов (YouScan, AppTweak), аналитика так и собирается по ключевым словам: найти общие темы можно, но это распределение будет некачественным. Чтобы корректно разобрать их по ключевым категориям или фичам, специалисту понадобятся недели или месяцы. Именно поэтому мы решили собрать свой инструмент и автоматизировать работу с отзывами. 

Чтобы разобраться в доступных методах анализа фидбэка, поделюсь ретроспективой — как они менялись с развитием технологий: 

  • Ручной анализ. Сначала аналитики читали фидбэк вручную и раскладывали его по категориям в Excel. Это работало на десятках и сотнях отзывов, но масштабировать дальше было очень ресурсоемко. 

  • Опросы и NPS. Далее компании начали измерять NPS, CSAT и другие метрики удовлетворенности. Это позволило понять уровень лояльности, но не дало объяснений причин проблем.

  • Keyword Analytics. Потом появился поиск по ключевым словам и Word Cloud. Можно было собирать облака тегов, определять ключевые темы, но проблема была в том, что алгоритм выявлял слова, а не смысл. Отзывы на одну тему, написанные разными словами, оказывались в разных категориях. 

  • Classical NLP. С появлением NLP стали использовать TF-IDF, LDA и Topic Modeling для автоматического поиска тем. Это усовершенствовало группировку, но всё еще не помогало справиться с ключевой проблемой.

  • Embeddings. Здесь произошла революция: вместо слов начали использовать многомерное векторное представление смысла. Например:

    • My funds are missing → [0,14, −0,92, 0,33, …].

    • Deposit never arrived → [0,15, −0,90, 0,31, …].

Благодаря этому в многомерном векторном пространстве отзывы оказываются рядом, хотя общих слов почти нет. Так мы наконец научились искать отзывы из одной темы, написанные в разных выражениях. 

  • LLM. Большие языковые модели стали отличным дополнением: Embeddings хорошо находят группы похожих отзывов, а LLM помогают интерпретировать их и превращать в понятные бизнес-темы.

В своем решении я использовал связку инструментов: 

Google Play Scraper → OpenAI Embeddings API → KMeans Clustering → GPT Naming → Meta Clustering → GPT Naming → Business Topics

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

Используем Embeddings: level 1

Перед началом кластеризации отзывов мы обрабатываем данные. С появлением современных Embeddings большая часть этой подготовки стала необязательна: теперь модели достаточно хорошо работают самостоятельно с разными языками, опечатками, разговорными выражениями, эмодзи и сокращениями. Именно поэтому в нашем решении предобработка минимальная. 

Фактически я почти не делаю классическую NLP-нормализацию: не перевожу отзывы на английский, не делаю лемматизацию, когда все слова приводятся в начальную форму, и не вычищаю агрессивно текст. Изначально мне хотелось проверить, насколько современные Embeddings смогут работать с сырыми данными из стора. Честно говоря, результат оказался лучше ожидаемого: модель достаточно хорошо группирует отзывы по смыслу, даже на смеси разных языков и с опечатками.

Итак, переходим к основной части. В основе Embeddings лежит идея представления текста в виде многомерного вектора признаков. Для этого я использую OpenAI Embeddings API, который преобразует каждый отзыв в вектор размерностью 1536 признаков.

from openai import OpenAI

client = OpenAI(api_key=config.API_KEY)

def get_embedding(text):

   response = client.embeddings.create(

       model="text-embedding-3-small",

       input=text

   )

   return response.data[0].embedding

df["embedding"] = df["Review"].apply(get_embedding)

После построения Embeddings я использую алгоритм KMeans для поиска плотных областей в семантическом пространстве. KMeans я выбрал по нескольким причинам: 

  • это простой и хорошо изученный алгоритм;

  • быстро работает на десятках тысяч записей и легко масштабируется;

  • дает предсказуемый результат;

  • позволяет контролировать количество тем через параметр K.

Единственная сложность — KMeans требует заранее знать количество кластеров. Именно поэтому пришлось экспериментировать с разными значениями K и смотреть на качество получаемых тем.

Кроме KMeans, я рассматривал еще два метода: 

  • DBSCAN/HDBSCAN. Они не требуют заранее задавать число кластеров, хорошо находят выбросы и часто используются для embedding-space. Но в моих тестах они либо давали слишком много мелких кластеров, либо сильно зависели от параметров.

  • Agglomerative Clustering. Он хорошо показывает иерархию тем и удобен для последующего объединения похожих кластеров. В итоге именно его я использовал на втором уровне пайплайна для формирования MetaTopic.

В результате получилось так, что KMeans отвечает за поиск локальных смыслов внутри отзывов, а Agglomerative Clustering помогает находить более крупные бизнес-темы поверх уже найденных кластеров.

Интересный момент — появление LLM сильно изменило требования к кластеризации. Раньше нужно было получить «идеальные» кластеры, потому что именно они были конечным результатом анализа. Теперь кластеризация стала промежуточным этапом. 

Главное — не идеальная математическая точность, а быстрое объединение семантически похожих отзывов, которые затем LLM может качественно проанализировать, назвать темы, выделить проблемы и сформулировать выводы. Это позволяет использовать более простые и быстрые алгоритмы кластеризации, сохраняя высокое качество итоговой аналитики.

Технически кластеризация реализуется следующими строками: 

import numpy as np

from sklearn.cluster import KMeans

X = np.vstack(df["embedding"].values)

kmeans = KMeans(

   n_clusters=15,

   random_state=42,

   n_init="auto"

)

df["ClusterID"] = kmeans.fit [2]_predict(X)

Если на вход KMeans дать 1000 отзывов, то вместо тысячи отдельных комментариев можно получить примерно 10–20 устойчивых тематических кластеров. Например, в нашем случае могут быть такие области:

  • Verification

  • Localization

  • Trust & Security

  • Product Features

На этом этапе мы уже переходим от текста к смыслу, но сами кластеры пока остаются просто математическими группами похожих векторов.

Собираем данные с помощью GPT

Чтобы сделать результаты кластеризации понятными человеку, поверх подключается ChatGPT. Модель анализирует примеры отзывов внутри каждого кластера и формирует базу данных с названием темы, описанием проблемы, тональностью отзывов, их количеством и средним рейтингом. Дополнительно для каждого отзыва в базе данных сохраняются дата публикации, рейтинг и тональность, что позволяет анализировать не только сами темы, но и их динамику во времени.

Для обработки данных используем промпт: 

prompt = f"""

You are a senior product researcher.

Analyze the customer reviews below.

Identify the single dominant customer topic inside this cluster.

Return ONLY valid JSON:

{{

 "cluster_name": "Topic name",

 "description": "Short description",

 "sentiment": "Positive"

}}

Rules:

- Return exactly one topic.

- Choose the dominant theme.

- Sentiment must be only: Positive, Negative, Mixed.

Reviews:

{reviews_text}

"""

response = client.chat [3].completions.create(

   model=config.MODEL_TOPICS,

   response_format={"type": "json_object"},

   messages=[

       {"role": "user", "content": prompt}

   ],

   temperature=0

)

result = json.loads(response.choices[0].message.content)

Таким образом тысячи комментариев превращаются в полноценную модель Voice of Customer. Анализируя модель, мы поняли, что можем использовать ее не только на собственных отзывах, но и на отзывах конкурентов. Так мы смогли выявить их сильные и слабые стороны, а также определить наше положение на рынке с точки зрения [4] клиентов.

От текста к смыслу: Embeddings, GPT и многомерные векторы в конкурентном анализе мобильных приложений - 2

Всё получилось: Embeddings определили векторы отзывов, KMeans кластеризовал их, а GPT собрал понятную БД. И тут появилась новая проблема: оказалось, что одинаковые темы могут иметь разные названия:

  • Need English Language

  • English Language Request

  • Lack of English Support

По сути это та же проблема, которую мы решали с помощью векторов: бизнес понимает, что это одна сущность, а модель — нет. Именно поэтому я добавил второй уровень анализа и кластеризации.

Используем Embeddings и GPT: level 2

На этом этапе для уже найденных GPT тем мы повторно строим Embeddings и с помощью Agglomerative Clustering применяем иерархическую кластеризацию. Это позволяет объединять похожие темы разных компаний в общие группы.

from sklearn.cluster import AgglomerativeClustering

from sklearn.metrics.pairwise import cosine_distances

topic_texts = (

   topics["ClusterName"] + "n" + topics["Description"]

).tolist()

topic_embeddings = [

   get_embedding(text)

   for text in topic_texts

]

X_topics = np.vstack(topic_embeddings)

distance_matrix = cosine_distances(X_topics)

clustering = AgglomerativeClustering(

   metric="precomputed",

   linkage="average",

   distance_threshold=0.35,

   n_clusters=None

)

topics["MetaClusterID"] = clustering.fit [5]_predict(distance_matrix)

Затем GPT снова обрабатывает данные и формирует более высокий уровень абстракции — MetaTopic. После этого похожие MetaTopic дополнительно консолидируются в бизнес-категории.

prompt = f"""

You are a product analytics expert.

Below are similar customer topics from different apps.

Create one concise MetaTopic name that represents them.

Return ONLY valid JSON:

{{

 "meta_topic": "Meta topic name"

}}

Topics:

{topics_text}

"""

response = client.chat [3].completions.create(

   model=config.MODEL_TOPICS,

   response_format={"type": "json_object"},

   messages=[

       {"role": "user", "content": prompt}

   ],

   temperature=0

)

result = json.loads(response.choices[0].message.content)

В результате получается многоуровневая карта смыслов:

Review (Отзыв) → Cluster (Общая тема) → MetaTopic (Более крупная тема) → BusinessTopic (Бизнес-задача).

Например: Need English Language → English Language Support → Multilingual App Support → Localization.

Как поэтапно выглядят все шаги нашего решения

Как поэтапно выглядят все шаги нашего решения

Фактически система перестает работать со словами и начинает работать со смыслами: на входе — тысяча неструктурированных отзывов, на выходе — десяток бизнес-категорий, их тональность, объем обсуждения и динамика изменений во времени. Именно это позволяет использовать отзывы не как набор комментариев, а как источник знаний о продукте, клиентах и рынке.

Вместо итогов

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

Сейчас мы активно пользуемся внутри инструментом и планируем внедрить чат-бота, который будет дополнительно анализировать и комментировать результаты в модели Voice of Customer. 

Огромное преимущество современных возможностей в том, что стоимость такого решения минимальна: мы используем только OpenAI Embeddings API. Адаптировать наше решение под себя можете и вы — я буду рад обсудить фидбэк и ответить на ваши вопросы, задавайте их в комментариях.

Автор: Vladimir_Mihailov

Источник [6]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/32832

URLs in this post:

[1] опыт: http://www.braintools.ru/article/6952

[2] kmeans.fit: http://kmeans.fit

[3] client.chat: http://client.chat

[4] зрения: http://www.braintools.ru/article/6238

[5] clustering.fit: http://clustering.fit

[6] Источник: https://habr.com/ru/companies/garage8/articles/1057100/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1057100

www.BrainTools.ru

Rambler's Top100