Использование Support Vector Machines и VADER (словарь Valence Aware Dictionary и sEntiment Reasoner)

Введение

Два месяца назад я закончил CS50 «Введение в искусственный интеллект» с использованием курса Python. Во время курса меня особенно заинтриговала концепция анализа настроений, извлечения функций из текстовых данных и перехода в алгоритмы машинного обучения для определения эмоционального тона. Я решил заняться проектом, который включает в себя классификацию текста и анализ тональности.

Поиск по набору данных

Будучи частью системы образования Сингапура в течение последних 12 лет, субреддит r / SGExams, кажется, всегда был предпочтительной платформой для студентов для дискуссий, начиная от студентов, разглагольствующих о том, насколько сложна конкретная работа на уровне O, до студентов, интересующихся различными университетскими курсами.

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

Извлечение данных

Я использовал PRAW, оболочку Reddit API, чтобы извлечь заголовок поста, текст заголовка, URL, дату, время из 1000 самых популярных постов на r / SGExams. Я извлек данные во вложенный словарь, который затем преобразовал во фрейм данных pandas. Я представил изображения постов мемов в виде текста: «пост мемов», используя функцию цикла с is_self () для добавления в фрейм данных pandas.

Обратите внимание, что для использования PRAW API вам необходимо создать учетную запись и зарегистрироваться для получения ключей OAuth2 (client_id, client_secret, user_agent).

Предварительная обработка данных

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

  • Удаление пустых строк
  • Измените весь текст на нижний регистр
  • Токенизация слов: процесс разбиения потока текста на слова, фразы.
  • Удаление стоп-слов
  • Удаление не буквенно-цифрового текста
  • Лемматизация слов: процесс сокращения флективных форм, а иногда и производных форм слова до общей базовой формы с учетом контекста.

Я применил только лемматизацию, а не стемминг, чтобы токены оставались читаемыми. Для тех, кто не уверен в различиях между ними, Stemming обычно удаляет последние несколько символов слова, что приводит к неправильному значению и написанию, в то время как Lemmatization рассматривает контекст и преобразует слово в его базовую форму, называемую леммой. Вот пример:

Original   Stemming   Lemmatization
Having     Hav        Have
The going  The go     The going
Am         Am         Be

Одна проблема, с которой я столкнулся, заключается в том, что, поскольку слова в предложении часто имеют несколько лемм, они не будут преобразованы правильно. Такие слова, как «учеба», не преобразуются в «учеба». Чтобы решить эту проблему, я добавил функцию get_wordnet_posttag, которая принимает слово и возвращает часть речевого тега (тег POS) и добавляется ко второму аргументу функции lemmatized_word (). Тег POS позволяет функции более точно лемматизировать слово.

Подготовка наборов данных для обучения и тестирования

Корпус будет разделен на два набора данных: обучение и тестирование. Набор обучающих данных будет использоваться для соответствия модели, в то время как для набора данных тестирования будут делаться прогнозы, и все это достигается с помощью функции train_test_split из библиотеки sklearn.

Кодирование

После этого метки строки типа данных в Train_Y и Test_Y преобразуются в числовой формат в процессе, называемом кодированием, для понимания модели. Например: [«JC», «Uni», «Poly», «Sec»] → [0, 1, 2, 3]

Векторизация слов

Существует несколько методов преобразования текстовых данных в векторы, такие как Word2Vec, но для этого проекта я буду использовать самый популярный метод - TF-IDF, который расшифровывается как Term Frequency - Inverse Document Frequency.

  • Частота термина. Как часто слово появляется в документе.
  • Обратная частота в документе: измеряет, насколько редко слово встречается в документах.

Модель TF-IDF сначала адаптируется ко всему корпусу, чтобы пополнить его словарный запас. Train_X и Test_X затем векторизуются в Train_X_tfidf и T est_X_tfidf, оба из которых содержат список уникальных чисел вдоль с их ассоциированной оценкой TF-IDF.

Алгоритм машины опорных векторов

Так что же такое машина опорных векторов (SVM)? Это модель обучения с учителем со связанными алгоритмами обучения, которые анализируют данные для классификации и регрессионного анализа.

Я начну с объяснения нескольких ключевых понятий;

  • Маржа: расстояние между точками данных двух разных классов.
  • Границы принятия решений: также известные как гиперплоскости, они существуют как линия в пространстве двухмерных объектов или как плоскость в трехмерном пространстве объектов. Трудно представить, когда они превышают 4 или более измерения. Границы решения классифицируют точки данных.
  • Перекрестная проверка: определите наименьшее возможное количество ошибок классификации и наблюдений на полях.

Не углубляясь в математику, давайте начнем с рисунка ниже. Есть два класса точек данных, разделенных границей решения вместе с его полем. Чтобы найти ширину поля, введите единичный вектор w, перпендикулярный границе решения.

Целью SVM является максимальное увеличение разницы между точками данных и границей решения. Это иначе известно как классификатор мягкого поля или классификатор опорных векторов (SVC). SVC - это граница принятия решения с более высоким смещением и более низкой дисперсией, векторы поддержки которой исходят из точек данных, лежащих в мягком поле или на границе, полученной посредством перекрестной проверки. Классификатор максимальной маржи (MMC) не будет работать в этом случае, поскольку он снижает порог маржи между точками данных и границей решения, особенно при наличии выбросов, увеличивая вероятность переобучения.

Однако и SVC, и MMC не могут работать с нелинейными данными, которые имеют массу перекрывающихся классификаций, и здесь в игру вступает SVM. Проще говоря, SVM работает с данными в относительно низкой размерности, преобразует данные в более высокую размерность и находит SVC, который может различать данные высокой размерности. Но преобразование таких данных требует больших вычислений. Таким образом, SVM использует функции ядра для поиска SVC в более высоких измерениях, вычисляя отношения между каждой парой точек, как если бы они находятся в высоких измерениях, без преобразования данных в более высокое измерение, обычно известное как трюк с ядром .

Имея некоторое представление о SVM, мы можем изучить наш набор данных и построить модель SVM.

Результаты

Результаты более или менее соответствуют моим ожиданиям. Ради экономии времени я не обучил модель всем данным, доступным в сабреддите. Фактически, я использовал только 1000 самых популярных постов за все время, чтобы протестировать весь поток. Модель имела невысокую точность 58,3% и определенно не соответствовала требованиям. Кроме того, поскольку все сообщения посвящены одной и той же теме: образование, может быть очень сложно дифференцировать каждый уровень образования из-за множества общих терминов, используемых взаимозаменяемо.

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

Я запустил инструмент анализа настроений на том же наборе данных, принимая во внимание категории (средняя школа, неполный колледж, политехнический институт и университет).

Я использовал VADER (Valence Aware Dictionary и sEntiment Reasoner), лексикон и инструмент анализа настроений на основе правил для этого проекта, поскольку он специально настроен на настроения, выраженные в социальных сетях. Кроме того, он чувствителен как к полярности (положительный / отрицательный), так и к интенсивности эмоций. Рубрики VADER рассчитывают свое настроение по значению: 1 - самый положительный, -1 - самый отрицательный, от -0,05 до 0,05 - нейтральный. Я протестировал инструмент, чтобы проверить, может ли он понимать интенсивность языка и обнаруживать двойные полярности:

from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
def sentiment_analyzer(sentence):
    score = analyser.polarity_scores(sentence)
    return score['compound']
sentence = "I dislike mushroom"
sentiment_analyzer(sentence)
OUTPUT: -0.3818
sentence = "I really hate mushroom"
sentiment_analyzer(sentence)
OUTPUT: -0.6115

sentence = "I dislike mushroom but I love fried chicken" 
sentiment_analyzer(sentence)
OUTPUT: 0.7184
sentence = "I dislike mushroom but I like fried chicken"
sentiment_analyzer(sentence)
OUTPUT: 0.3506

Кроме того, я обновил его лексикон, добавив «мем» в качестве положительного элемента, так как r / SGExams содержит довольно много сообщений о мемах по текущим вопросам образования.

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

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

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

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

Оценка диаграмм

Как правило, настроения на всех уровнях образования в течение года в основном отрицательные, как и прогнозируется на гистограмме. Я заметил, что для младшего колледжа и средней школы их настроения наиболее негативны с июня по февраль следующего года, что соответствует тенденции приближения экзаменов последнего года обучения с последующим выпуском результатов уровня O и A, что заставляет учащихся выражать свое мнение. их стресс, тревога и сомнения по поводу попадания на платформу в школу / курс своей мечты.

Что касается Политехнического института и университета, то, возможно, нельзя сделать никаких выводов из-за их модульной академической системы по сравнению с JC и системой Final Secondary. Более глубокий анализ показал, что их посты в основном представляют собой запросы о различных специализированных курсах, AMA, тирадах, стипендиях, а не об экзаменах и результатах, что объясняет непредсказуемые колебания постов с разными настроениями.

Конечные заметки

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

К результатам, полученным в моем проекте, следует по возможности относиться легкомысленно

Было довольно много вещей, которые можно было бы сделать лучше.

Например, классифицируя текст, я в основном различал их по их чутью. Такие навыки, как META, Rant и Advice, относятся ко всем уровням образования. Эта форма классификации может быть неточной, поскольку некоторые должности, хотя и являются общими, ориентированы на определенный уровень образования, что приводит к неточностям.

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

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

Все коды доступны в моем Github здесь:



Профиль в LinkedIn: Шон Яп

Ваше здоровье!

использованная литература

[1] Профессор Патрик Генри Уинстон, Машины опорных векторов (2014), MITOpenCourseWare по искусственному интеллекту.

[2] Фелиппе Родригес, Очистите Reddit с помощью Python (2018), storybench.org из Школы журналистики Северо-Восточного университета.