Извлечение темы и анализ тональности Yelp Review с использованием платформы больших данных

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

Формально мы извлекли горячие темы из текстов обзоров Yelp, чтобы быстро понять комментарии потребителей о компаниях, и мы проводим анализ настроений в текстовых обзорах, чтобы определить достоверность оценок клиентов: умеют ли клиенты количественно выражать свои мысли в числовых оценках. Компании и предприниматели могут извлечь огромную пользу из нашей аналитики, потому что это буквально то, как сделать их бизнес лучше! Люди, интересующиеся психологией, также могут увидеть, является ли система числовых оценок хорошим способом представления мыслей людей.

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

Аналитическая платформа, которую мы использовали в этом проекте, — NYU Peel HPC. Мы заполнили наборы данных, загруженные из Yelp (https://www.yelp.com/dataset/documentation/main) в HDFS, а затем использовали задания MapReduce для очистки и профилирования необработанных данных. Затем мы перешли к выполнению алгоритмов извлечения тем, анализа настроений и НЛП на очищенных данных с использованием Spark ML. Только на этапе визуализации мы будем получать выходные данные предыдущих алгоритмов на локальный хост и генерировать графики с помощью Excel и Python Matplotlib.

Мы использовали два набора данных Yelp Open: business.json и review.json. Набор данных business.json включает бизнес-информацию, такую ​​как местоположение, атрибуты и категории, а review.json содержит полные текстовые данные обзора, включая идентификатор пользователя, связанного с обзором, и business_id, относящийся к целевому бизнесу. Ключи в review.json включают review_id (строка), user_id (строка), business_id (строка), звездочки (целое число), дата (строка, в формате ГГГГ-ММ-ДД), текст (строка), полезно (целое число), смешной (целое число), круто (целое число). В частности, ключ business_id также является внешним ключом, который можно использовать для обратной ссылки на файл business.json для получения всей информации об этом бизнесе. На этапе очистки данных мы использовали этот внешний ключ для выполнения операции соединения между записями в review.json и business.json.

Извлечение темы:

Первое задание MapReduce просто подсчитывает количество предприятий в каждом рейтинге, как вы можете видеть, у большинства предприятий на самом деле дела идут неплохо:

После расчета среднего значения и стандартной ошибки бизнес-рейтингов мы решили установить порог как хороших, так и плохих предприятий на одно стандартное отклонение от среднего. В результате предприятия с рейтингом 4,5 и выше переводятся в категорию хороших предприятий. Точно так же предприятия с рейтингом 2,5 или ниже считаются отнесенными к категории неэффективных предприятий.

Затем мы перешли к фазе извлечения темы, выполняемой с помощью модуля LDA в библиотеке Spark ML. Выходные данные этапа очистки данных сначала считываются во фрейм данных Spark. Затем фильтр стоп-слов берет входные данные из начального списка стоп-слов, предоставленного Университетом Глазго, и затем применяется к фрейму данных. Затем кадр данных разделяется на хорошую бизнес-группу и плохую бизнес-группу с помощью Spark SQL. После этого мы векторизовали поле комментариев клиентов и использовали его вместе с монотонно возрастающим столбцом идентификаторов в качестве входных данных для модели LDA. Конечный результат печатается прямо в оболочке Spark.

Несмотря на то, что модуль LDA хорошо инкапсулирован и готов к использованию, нам все еще нужно вручную настроить список стоп-слов и гиперпараметры модели, чтобы добиться оптимизированного вывода. Несмотря на то, что первоначальный список стоп-слов, предоставленный Университетом Глазго, является достаточно полным, в комментариях клиентов все еще остается много слов. Поскольку результат модели LDA не сходится и изменяется при каждом запуске, не существует интуитивно эффективного способа определения потенциальных стоп-слов, вырисовывающихся в огромном наборе данных. Поэтому наш подход прост: мы проводим большое количество прогонов модели LDA одновременно в нескольких оболочках и наблюдаем за результатами. Помимо артиклей, предлогов, местоимений и союзов, мы также добавляем в список стоп-слов те, которые повсеместно встречаются в каждой теме. Что касается гиперпараметров, нас в основном интересует количество тем, которые нужно извлечь из входных данных. Установка слишком большого номера темы приведет к тому, что темы результатов будут однородными. Опять же, после большого количества испытаний мы обнаружили, что общее количество тем, равное 8, приведет к тому, что модель выдаст более диверсифицированный результат. Опять же, поскольку модель LDA не сходится, результаты могут различаться от запуска к запуску. Но в целом наш измененный список стоп-слов и гиперпараметр позволяют модели LDA выводить в значительной степени интерпретируемый набор тем, в котором каждый элемент поддерживает хороший уровень отличия от других.

Темы, извлеченные из комментариев к компаниям с хорошим рейтингом:

Темы, извлеченные из комментариев о компаниях с низким рейтингом:

Имеет смысл, верно? Мы можем непосредственно увидеть, почему предприятия такие, какие они есть. Для хорошо работающих предприятий, помимо упомянутых видов услуг, клиентам в целом нравились качество и профессионализм, а также свежесть и вкус блюд. Для неэффективных предприятий потребители обычно жалуются на «ужасное» и «грубое» отношение «менеджеров» и проблемы, связанные с длительным ожиданием и расположением предприятий.

Тем не менее, некоторые темы довольно неясны. Чтобы определить точные обзоры, относящиеся к каждой теме, мы использовали Spark SQL. Например, код для идентификации отзывов с темой «свежие», отсортированных по убыванию рейтинга, показан следующим образом:

sqlContext.sql("ВЫБЕРИТЕ текст ИЗ df2, где текст типа "%fresh%" упорядочивается по звездочкам desc limit 20").show()

А отзыв такой:

Обратите внимание на мою оболочку в стиле Матрицы, а Матрица 4 уже не за горами :)

Анализ настроений

Для анализа настроений в обзорах мы выбрали пакет TextBlob, широко используемый в литературе инструмент обработки естественного языка. Интуиция, лежащая в основе этого анализа, заключается в том, что если прогнозируемые оценки тональности из текста отзыва совпадают с фактическими числовыми оценками, то вполне вероятно, что клиенты могут давать объективные текстовые обзоры с их соответствующими оценками. Если нет, то, вероятно, в основе числовых оценок лежит некоторая предвзятость, и люди, вероятно, не могут количественно выразить свой текст в оправданных рейтинговых оценках.

В PySpark создается определяемая пользователем функция, в которой входные данные представляют собой строку, а выходные данные — показатель позитивности настроений, вычисляемый TextBlob. Оценка настроений колеблется от -1 до 1, где 1 — очень положительное, а -1 — очень отрицательное. В конце концов, обзоры обрабатываются через определяемую пользователем функцию, и каждый из них будет иметь дополнительное поле «predicted_score», которое содержит их оценки тональности. Затем среднее значение оценок настроений сравнивается со средним значением фактических оценок. Окончательный результат показывает, что среднее значение всех оценок отзывов составляет 3,73 по шкале от 1 до 5, а прогнозируемая оценка тональности составляет 0,235 по шкале от -1 до 1.

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

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

Однако текущие данные далеки от окончательных, и для дальнейшего изучения этой темы все еще необходимы более надежные доказательства. В будущем мы хотим заменить TextBlob другими моделями анализа настроений НЛП, такими как различные предварительно обученные модели НЛП Spark, чтобы избежать предвзятости, представленной в аналитике TextBlob. Кроме того, оценки настроений, предсказанные моделями, могут быть объединены в одну путем усреднения и удаления выбросов для получения более точного прогноза. Наконец, статистические T-тесты могут быть выполнены между прогнозируемыми баллами и фактическими рейтингами, чтобы определить значимость результата.

Спасибо, что зашли так далеко! Весь код можно найти в моем репозитории Github. Вы можете ознакомиться с другими моими интересными проектами, подобными этому.