Введение

Анализ тональности - это тип проблемы обработки естественного языка, который определяет тональность или эмоцию отрывка текста. Например, можно создать алгоритм, чтобы определить, был ли отзыв о продукте положительным, нейтральным или отрицательным. Обработка естественного языка (НЛП) - это область искусственного интеллекта, в которой компьютеры понимают и обрабатывают человеческий язык. Часто цель состоит в том, чтобы извлечь смысл из текста.

Есть много разных приложений НЛП. К ним относятся языковой перевод, создание текста и проверка орфографии / грамматики. Кроме того, существует множество методов, которые можно применять для анализа текста и извлечения смысла. В этом мини-проекте мы сосредоточимся на создании рекуррентной нейронной сети (RNN) для классификации настроений твитов об авиакомпаниях, использующих Keras и предварительно обученное встраивание слов.

Данные

Наш набор данных называется Twitter US Airline Sentiment и был загружен с Kaggle в виде файла csv. Первоисточником была библиотека Данные Crowdflower для всех. В феврале 2015 года из Twitter были скопированы твиты о каждой крупной авиакомпании США. Затем авторы классифицировали каждый твит как положительный, нейтральный или отрицательный и указали причину отрицательной классификации, а также оценку достоверности присвоенного ярлыка.

14 640 строк и 15 столбцов. Включенные функции: идентификатор твита, настроение, оценка уверенности в настроении, отрицательная причина, уверенность в отрицательной причине, авиакомпания, золото настроений, имя, количество ретвитов, текст твита, координаты твита, время твита, дата твита, местоположение твита и пользователь. часовой пояс.

Фон

Рекуррентная нейронная сеть (RNN)

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

Долговременная краткосрочная память (LSTM)

Простые RNN страдают от проблемы исчезающего градиента, которая возникает, когда информация с более ранних уровней исчезает по мере того, как сеть становится глубже. Алгоритм LSTM был создан, чтобы избежать этой проблемы, позволив нейронной сети передавать информацию через несколько временных шагов. Это означает, что он может сохранить важную информацию для последующего использования, предотвращая исчезновение градиентов во время процесса. Кроме того, ячейка LSTM также может определять, какую информацию нужно удалить. Таким образом, он может научиться распознавать важные входные данные и сохранять их для будущего, удаляя ненужную информацию.

Стробируемый рекуррентный блок (ГРУ)

Слой ГРУ был также создан в ответ на проблему исчезающего градиента. Это упрощенная версия ячейки LSTM, но работает так же хорошо.

Двунаправленные RNN

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

Вложения Word

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

Еще одна популярная модель - это Глобальные векторы для представления слов (GloVe), которая является расширением word2vec. Обычно это позволяет лучше встраивать слова, создавая матрицу контекста слова. По сути, он создает меру, чтобы указать, что одни слова с большей вероятностью будут встречаться в контексте других. Например, слово «чип», скорее всего, будет использоваться в контексте «картофель», но не в контексте «облако». Его разработчики создали вложения, используя английские слова, полученные из данных Википедии и Common Crawl.

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

Цель

Цель этого мини-проекта - классифицировать твиты авиакомпаний как положительные, нейтральные или отрицательные с использованием предварительно обученного встраивания слов из GloVe и RNN.

Исследовательский анализ данных

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

Чтобы лучше понять разницу в настроениях к положительным, нейтральным и отрицательным твитам, мы можем создать облако слов для каждой категории. Перед тем, как создать это облако слов, мы должны очистить твиты, удалив маркеры Twitter, специальные символы, числа, знаки препинания и маленькие слова длиной не более 3 символов. Это позволяет нам видеть слова, которые являются репрезентативными для каждого настроения, в отличие от слов, которые, вероятно, встречаются по каждому ярлыку. Мы смотрим на 75 наиболее часто используемых слов в каждой группе тональности.

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

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

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

Очистка данных

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

Мы решили не очищать сами твиты и не удалять дескрипторы твиттера, специальные символы и знаки препинания, потому что наша RNN автоматически изучит эти варианты и шаблоны.

Мы должны преобразовать наши данные для ввода в RNN. Наш текст изначально закодирован как строки, поэтому мы должны преобразовать его в вектор целых чисел. В идеале мы хотим, чтобы каждое уникальное слово в нашем наборе данных имело собственное целочисленное представление. Затем каждый твит будет представлен в виде вектора, каждый элемент которого содержит целое число, которое можно сопоставить с определенным словом. Это можно сделать с помощью класса Keras Tokenizer. Это превращает кусок текста в последовательность целых чисел, каждое из которых является индексом токена в словаре. В общем, токенизация - это процесс преобразования предложений в слова. Мы обнаружили, что объем словарного запаса нашего набора данных составляет 15 769 слов.

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

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

Набор поездов и тестов был создан с использованием разделения 80:20. Затем наши обучающие данные были сокращены на 20%, чтобы создать набор для проверки.

Перчатка

GloVe определяется как алгоритм обучения без учителя для получения векторных представлений слов. Мы загрузили данные со связанного веб-сайта и специально использовали 100-мерные вложения 400 тысяч слов из английской Википедии в 2014 году. Это представлено в текстовом файле, который мы должны проанализировать, чтобы создать индекс, который отображает слова в их векторное представление.

Затем мы должны построить нашу матрицу внедрения или нашу матрицу контекста слова, как обсуждалось ранее. Размеры матрицы - это размер нашего словаря на 100, который является нашим размером встраивания, как указано ранее. Каждая строка этой матрицы является векторным представлением слова из нашего словаря GloVe.

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

Каждая из следующих RNN начинается со слоя внедрения, который можно рассматривать как словарь, который отображает целочисленные индексы, представляющие определенные слова, в плотные векторы. Он использует эти целые числа, чтобы найти связанный с ними вектор в слове, определенном GloVe. Входное измерение для этого слоя - это размер нашего словаря, а выходное - 100 для измерения встраивания. Веса определяются матрицей внедрения, и мы получаем trainable = False, потому что мы хотим использовать уже предварительно обученное встраивание слов. Мы хотим избежать обновления предварительно обученных весов при обучении модели. Входная длина равна 30, потому что мы решили дополнить все наши последовательности этим значением, чтобы гарантировать, что все векторы имеют одинаковую длину.

Общая архитектура

Входными данными для каждой из следующих моделей являются наши обучающие данные, которые состоят из 11712, из которых 20% удерживаются для проверки. Каждое из этих наблюдений содержит 30 «характеристик», соответствующих каждому слову в твите. Любые 0 указывают на отсутствие слова.

Каждая модель заканчивается плотным слоем с 3 узлами, потому что у нас есть 3 возможных метки: положительная, нейтральная или отрицательная. Поскольку мы закодировали наши метки в горячем режиме, мы используем softmax для этой задачи мультиклассовой классификации, чтобы получить вероятность для каждого класса. Кроме того, мы используем точность в качестве нашей метрики, потому что это проблема классификации. Когда мы используем метод прогнозирования из Keras, мы получаем трехэлементный вектор-строку для каждого ввода. Каждый элемент соответствует вероятности одной из 3 меток. Следовательно, метка с наибольшей вероятностью - это прогнозируемый результат.

Мы составляем каждую модель с адамом и категориальной кроссэнтропией.

Первая модель: простой LSTM с отсеиванием и высокой размерностью

Первая RNN, которую мы создаем для этой задачи классификации, использует только 1 слой LSTM в дополнение к ранее заданному внедрению и плотному слою softmax. Размер вывода для слоя LSTM равен 256, что означает, что мы увеличиваем размерность со 100, что является выходом из слоя внедрения. Кажется, не существует общего практического правила для определения количества единиц в слое RNN, поэтому мы изначально выбрали 256, чтобы увеличить размерность и посмотреть, как работает модель. Мы также включили регуляризацию с отсевом и повторяющимся отсевом. Первый - это коэффициент отсева для входных единиц уровня, а второй определяет процент отсева для повторяющихся единиц. Мы устанавливаем их на 0,2 и 0,5 соответственно. Мы обучили эту модель для 100 эпох с размером пакета 256.

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

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

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

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

Вторая модель: простой LSTM с выпадением и низкой размерностью

Модель 2 идентична модели 1, за исключением того, что теперь мы уменьшаем размерность. Поэтому мы устанавливаем количество единиц для нашего единственного уровня LSTM равным 64. Отметим, что количество обучаемых параметров во второй модели значительно ниже, чем в первой модели.

Мы видим, что потери на обучение и тестирование ниже, чем в Модели 1, но они гораздо ближе друг к другу. Однако мы действительно видим некоторые свидетельства переобучения на графике потерь при обучении и проверке. Потеря валидации, кажется, выходит на плато примерно через 60 эпох, в то время как потеря тренировки продолжает уменьшаться. Несмотря на то, что количество параметров в Модели 2 уменьшилось, мы все еще видим некоторые признаки переобучения.

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

Третья модель: LSTM Layer Stacking

Поскольку Модель 1, похоже, не страдает от переобучения, мы можем увеличить сложность или емкость RNN, добавив несколько повторяющихся слоев.
Таким образом, наша третья модель добавляет второй уровень LSTM со 128 единицами с выпадением 0,2 и повторным выпадением 0,5. Он был скомпилирован и подогнан с теми же параметрами, что и в наших предыдущих моделях.

Мы видим, что количество обучаемых параметров увеличилось по сравнению с моделью 1.

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

Когда мы сравниваем матрицы путаницы для Модели 3 с матрицами для Модели 1, мы видим, что они почти идентичны. Это означает, что добавление второго уровня LSTM существенно не улучшило нашу сеть. Вместо использования слоев LSTM мы можем переключиться на ГРУ и посмотреть, как это влияет на производительность нашей модели.

Четвертая модель: наложение слоев GRU

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

Мы можем отметить, что общее количество обучаемых параметров в Модели 4 меньше, чем в Модели 3, несмотря на использование тех же выходных размеров для 2 слоев RNN. Это показывает, насколько GRU проще, чем LSTM.

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

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

Чтобы бороться с проблемой переобучения, мы могли бы уменьшить выходные размеры для слоев ГРУ и немного увеличить параметр выпадения в 1-м слое.

Пятая модель: сокращение ГРУ с большей регуляризацией

Чтобы уменьшить переоснащение, которое мы видим в Модели 4, мы уменьшаем выходные размеры для обоих уровней ГРУ до 64 и 32 соответственно. Кроме того, мы увеличиваем отсев в первом слое ГРУ до 0,3. Остальные параметры остаются прежними.

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

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

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

Шестая модель: двунаправленная RNN

Наша последняя модель включает двунаправленные рекуррентные слои, чтобы исследовать, улучшит ли двунаправленная обработка данных производительность модели. Отметим, что использование двунаправленных слоев значительно увеличивает количество параметров в модели, поэтому нам сначала нужно беспокоиться о переобучении. Поэтому в этом случае мы включим только один двунаправленный слой с 64 модулями. Мы также используем выпадение и периодическое выпадение при 0,2 и 0,5 соответственно.

Точность испытаний для Model 6 аналогична тому, что мы видели ранее. Мы видим малейшие признаки переобучения к концу тренировки примерно в 90–100 эпох.

Матрицы путаницы для модели 6 очень похожи на матрицы моделей 5, 3 и 1. Таким образом, использование двунаправленного уровня, похоже, не улучшает производительность сети. Это может иметь смысл, потому что анализ коротких твитов на двунаправленном уровне, скорее всего, не выявит каких-либо новых важных закономерностей или тенденций.

Резюме

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

Код

Https://github.com/frlim/data2040_final/tree/master/project_1

Ссылки

Джеффри Пеннингтон, Ричард Сочер и Кристофер Д. Мэннинг. 2014. Перчатка: глобальные векторы для представления слов

Создание облака слов в Python. GeeksforGeeks. Https://www.geeksforgeeks.org/generating-word-cloud-python/

Франсуа Шоле. Использование предварительно обученных встраиваний слов в модель Keras. Блог Кераса. 2016. https://blog.keras.io/using-pre-trained-word-embeddings-in-a-keras-model.html

Николай Джанакиев. Практическая классификация текста с помощью Python и Keras. Настоящий Python. 2018. https://realpython.com/python-keras-text-classification/

Джейсон Браунли. Как использовать слои встраивания слов для глубокого обучения с Keras. Мастерство машинного обучения. 2017. https://machinelearningmaster.com/use-word-embedding-layers-deep-learning-keras/

Франсуа Шоле. Глубокое обучение с помощью Python. Остров Укрытия: Мэннинг. 2018.