ReviewScope ищет аномалии в отзывах через embeddings и графы на 21 тыс. текстов

Хабраевец переехал, стал искать булочную по отзывам и заметил подозрительные тексты — похоже, написанные нейросетью или скопированные. Решил создать инструмент, который ловит странности в отзывах: необычные всплески активности, резкие сдвиги оценок, повторяющиеся тексты, манипуляции с рейтингом. ReviewScope работает локально, хранит данные в DuckDB, анализирует CSV и JSON. Код в открытом доступе. • **Четыре уровня поиска похожих отзывов**: Exact (точные совпадения), Fuzzy (лексически близкие через RapidFuzz), Near (сильное лексическое сходство через MinHash/LSH), Semantic (смысловое сходство через embeddings) • **Обнаружение всплесков**: rolling median + MAD (медианное абсолютное отклонение) вместо среднего и стандартного отклонения • **Анализ сдвигов рейтинга**: Jensen–Shannon divergence для измерения изменения структуры оценок от 1 до 5 звёзд

AI-обработка оригинала Хабр: Машинное обучение; редакция Hamidun News
ReviewScope ищет аномалии в отзывах через embeddings и графы на 21 тыс. текстов
Источник: Хабр: Машинное обучение. Коллаж: Hamidun News.
Слушать статью
Паспорт материала и цифры
ПараметрДанные
ПервоисточникХабр: Машинное обучение ↗
Главный редактор
Обнаружение всплесковrolling median + MAD (медианное абсолютное отклонение) вместо среднего и стандартного отклонения
Анализ сдвигов рейтингаJensen–Shannon divergence для измерения изменения структуры оценок от 1 до 5 звёзд

Ziverpup переехал и, как обычно, начал искать в картах, где поесть и куда заглянуть. Рейтинг выше четырёх есть почти везде, так что он фильтрует по отрицательным отзывам — там картина меняется. На одной булочной заметил странный отзыв: вместо описания опыта текст напоминал готовый ответ нейросети. Стал искать похожие случаи и нашёл не один. Например, отзыв о шаурмичной начинался с характерного «Это просто бомба!», дальше шёл шаблонный перечень: лаваш, мясо, соус, овощи, размер порции, обещание стать постоянным клиентом.

Одного примера недостаточно ничего доказать, но идея зацепила: создать инструмент для поиска аномалий в отзывах. С этой задачей Ziverpup уже сталкивался — когда был менеджером, разбирал негативные отзывы и иногда связывал их с конкурентами. Его больше интересовали авторы отзывов: человек, написавший пять отзывов о разных барах, кажется полезнее источником информации, чем тот, у кого в истории только шиномонтаж под Тольятти и книжный магазин в Воронеже. Но с логикой рейтинга доверия к авторам оказалось не всё просто: количество отзывов само по себе не делает человека компетентным. Смена города может быть просто поездкой, а один подробный отзыв может рассказать больше, чем сто общих фраз.

Архитектура и данные

В итоге получился ReviewScope — open-source инструмент для анализа отзывов, поиска аномалий, повторяющихся текстов и исследования истории авторов. GitHub: https://github.com/zinverno/reviewscope, демо: https://reviewscope-demo.streamlit.app/.

Инструмент не загружает отзывы сам из Яндекс Карт. Для анализа нужна подготовленная выгрузка в CSV или JSON. Приложение нормализует данные и сохраняет в DuckDB — всё запускается локально без отдельного сервера. Один отзыв содержит поля: review_id, place_id, place_name, place_category, reviewer_id, reviewer_name, rating, text, published_at, city, region, country, latitude, longitude. Не все поля обязательны. Интерфейс на Streamlit показывает N/A, если данных не хватает.

Пipeline: CSV/JSON → Normalization → DuckDB → AnalysisEngine → Streamlit UI. AnalysisEngine включает четыре модуля.

Четыре слоя анализа аномалий

Burst detection (всплески активности). У булочной обычно один-два отзыва в неделю. Если за сутки приходит тридцать, почти все пятёрки — это странно. Но для ресторана с пятьюдесятью отзывами в день те же тридцать ничего не значат. Решение: rolling median + MAD (медианное абсолютное отклонение). MAD измеряет, насколько обычные значения расходятся с типичным. Один экстремальный день на такую оценку почти не влияет — в отличие от среднего и стандартного отклонения, которые сдвигаются от выброса. Порог modified z-score установлен на 3.5, окно истории — 30 дней.

Rating shift anomalies (сдвиги рейтинга). Нашли день с необычно большим числом отзывов. Все ли они пятёрки? Или там единицы? Для этого добавлен Jensen–Shannon divergence — способ измерить различие между двумя распределениями вероятностей. Сравниваются доли оценок от одной до пяти звёзд за исторический период и вокруг события. Алгоритм одинаково ловит положительные и отрицательные всплески.

Duplicate detection — четыре уровня совпадений: Exact (одинаковые нормализованные тексты), Fuzzy (лексически близкие через RapidFuzz), Near (сильное лексическое сходство через MinHash/LSH), Semantic (смысловое через embeddings). Первых трёх казалось достаточно, но если автор полностью перефразировал предложение, лексические методы отказывают. Embeddings решили задачу.

Reviewer metrics, text scoring и topic clustering дополняют картину. Автор оставил отдельные показатели: активность автора, опыт в категории, информативность текстов и необычные закономерности в его истории.

Тестирование прошло на 21 тысяче настоящих отзывов. Часть гипотез не пережила проверку, один убедительный результат оказался ошибкой в расчёте коэффициента роста при нулевом baseline. Сейчас приложение в таких случаях показывает фактическое число отзывов и сообщает, что коэффициент роста здесь не имеет смысла.

Вопросы и ответы по материалу

Что известно по теме: архитектура и данные?

В итоге получился ReviewScope — open-source инструмент для анализа отзывов, поиска аномалий, повторяющихся текстов и исследования истории авторов. GitHub: https://github.com/zinverno/reviewscope, демо: https://reviewscope-demo.streamlit.app/. Инструмент не загружает отзывы сам из Яндекс Карт. Для анализа нужна подготовленная выгрузка в CSV или JSON. Приложение нормализует данные и сохраняет в DuckDB — всё запускается локально без отдельного сервера. Один отзыв содержит поля: review_id, place_id, place_name, place_category, reviewer_id, reviewer_name, rating, text, published

Что известно по теме: четыре слоя анализа аномалий?

Burst detection (всплески активности). У булочной обычно один-два отзыва в неделю. Если за сутки приходит тридцать, почти все пятёрки — это странно. Но для ресторана с пятьюдесятью отзывами в день те же тридцать ничего не значат. Решение: rolling median + MAD (медианное абсолютное отклонение). MAD измеряет, насколько обычные значения расходятся с типичным. Один экстремальный день на такую оценку почти не влияет — в отличие от среднего и стандартного отклонения, которые сдвигаются от выброса. Порог modified z-score установлен на 3.5, окно истории — 30 дней. Rating shift anom

ЖХ
Жемал Хамидун — CPO Alpina Digital, продакт-менеджер AlpinaGPT. Делает AI-продукты с 2019 года. Hamidun News — pet project, который вырос в production-агрегатор с 6000+ читателей.
✦ Единое AI-пространство · Nomad

Протестируйте новые LLM и мультимодальные модели в одном окне

Платформа Nomad AI (nomadnet.ai) даёт прямой доступ к Claude Opus 5.5, GPT-6, Gemini 3.1, DeepSeek и автономным агентам без VPN, зарубежных карт и зоопарка подписок.

Открыть Nomad AI →Автономный Nomad Agent
Что вы думаете?
Загружаем комментарии…