Рубрики
Без рубрики

Python for NLP: Анализ настроений фильмов с использованием глубокого обучения в Keras

Автор оригинала: Usman Malik.

Python for NLP: Анализ настроений фильмов с использованием глубокого обучения в Keras

Это 17 – я статья в моей серии статей по Python для НЛП. В предыдущей статье мы начали обсуждение глубокого обучения для обработки естественного языка.

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

В этой статье мы будем опираться на концепции, которые мы изучали в предыдущей статье, и рассмотрим классификацию более подробно с использованием реального набора данных. Мы будем использовать три различных типа глубоких нейронных сетей: Плотно связанная нейронная сеть (Базовая нейронная сеть), Сверточная нейронная сеть (CNN) и Сеть долговременной кратковременной памяти (LSTM), которая является вариантом Рекуррентных нейронных сетей . Кроме того, мы увидим, как оценить модель глубокого обучения на совершенно невидимых данных.

Примечание : В этой статье используется слой встраивания Keras и встраивания перчаток word для преобразования текста в числовую форму. Важно, чтобы вы уже поняли эти понятия. В противном случае вам следует прочитать мою предыдущую статью , а затем вы можете вернуться и продолжить эту статью.

Набор данных

Набор данных, который можно загрузить по этой ссылке Kaggle .

Если вы загрузите набор данных и распакуете сжатый файл, то увидите CSV-файл. Файл содержит 50 000 записей и две колонки: обзор и тональность. Столбец review содержит текст для обзора, а столбец sentiment содержит sentiment для обзора. Столбец sentiment может иметь два значения, то есть “положительный” и “отрицательный”, что делает нашу задачу проблемой бинарной классификации.

Импорт Необходимых библиотек

Следующий сценарий импортирует необходимые библиотеки:

import pandas as pd
import numpy as np
import re
import nltk
from nltk.corpus import stopwords

from numpy import array
from keras.preprocessing.text import one_hot
from keras.preprocessing.sequence import pad_sequences
from keras.models import Sequential
from keras.layers.core import Activation, Dropout, Dense
from keras.layers import Flatten
from keras.layers import GlobalMaxPooling1D
from keras.layers.embeddings import Embedding
from sklearn.model_selection import train_test_split
from keras.preprocessing.text import Tokenizer

Импорт и анализ набора данных

Теперь давайте импортируем и проанализируем наш набор данных. Выполните следующий сценарий:

movie_reviews = pd.read_csv("E:\Datasets\IMDB Dataset.csv")

movie_reviews.isnull().values.any()

movie_reviews.shape

В приведенном выше скрипте мы используем метод read_csv() библиотеки pandas для чтения CSV-файла, содержащего наш набор данных. В следующей строке мы проверяем, содержит ли набор данных какое-либо нулевое значение или нет. Наконец, мы печатаем форму нашего набора данных.

Теперь давайте напечатаем первые 5 строк набора данных с помощью метода head () .

movie_reviews.head()

В выходных данных вы увидите следующий фрейм данных:

голова

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

movie_reviews["review"][3]

Вы должны увидеть следующий обзор:

"Basically there's a family where a little boy (Jake) thinks there's a zombie in his closet & his parents are fighting all the time.

This movie is slower than a soap opera... and suddenly, Jake decides to become Rambo and kill the zombie.

OK, first of all when you're going to make a film you must Decide if its a thriller or a drama! As a drama the movie is watchable. Parents are divorcing & arguing like in real life. And then we have Jake with his closet which totally ruins all the film! I expected to see a BOOGEYMAN similar movie, and instead i watched a drama with some meaningless thriller spots.

3 out of 10 just for the well playing parents & descent dialogs. As for the shots with Jake: just ignore them."

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

Наконец, давайте посмотрим на распределение положительных и отрицательных настроений в нашем наборе данных.

import seaborn as sns

sns.countplot(x='sentiment', data=movie_reviews)

Выход:

распределение настроений

Из выходных данных видно, что набор данных содержит равное количество положительных и отрицательных отзывов

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

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

def preprocess_text(sen):
    # Removing html tags
    sentence = remove_tags(sen)

    # Remove punctuations and numbers
    sentence = re.sub('[^a-zA-Z]', ' ', sentence)

    # Single character removal
    sentence = re.sub(r"\s+[a-zA-Z]\s+", ' ', sentence)

    # Removing multiple spaces
    sentence = re.sub(r'\s+', ' ', sentence)

    return sentence
TAG_RE = re.compile(r'<[^>]+>')

def remove_tags(text):
    return TAG_RE.sub('', text)

В методе preprocess_text() первым шагом является удаление HTML-тегов. Для удаления HTML-тегов была определена функция remove_tags () . Функция remove_tags просто заменяет все, что находится между открытием и закрытием <> , пустым пространством.

Затем в функции preprocess_text удаляется все, кроме заглавных и строчных английских букв, что приводит к появлению одиночных символов, которые не имеют смысла. Например, когда вы удаляете апостроф из слова “Марка”, апостроф заменяется пустым пробелом. Следовательно, мы остаемся с одним символом “s”.

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

Затем мы предварительно обработаем наши отзывы и сохраним их в новом списке, как показано ниже:

X = []
sentences = list(movie_reviews['review'])
for sen in sentences:
    X.append(preprocess_text(sen))

Давайте теперь еще раз посмотрим четвертый обзор:

X[3]

Вывод выглядит следующим образом:

'Basically there a family where little boy Jake thinks there a zombie in his closet his parents are fighting all the time This movie is slower than soap opera and suddenly Jake decides to become Rambo and kill the zombie OK first of all when you re going to make film you must Decide if its thriller or drama As drama the movie is watchable Parents are divorcing arguing like in real life And then we have Jake with his closet which totally ruins all the film expected to see BOOGEYMAN similar movie and instead watched drama with some meaningless thriller spots out of just for the well playing parents descent dialogs As for the shots with Jake just ignore them '

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

Далее нам нужно преобразовать наши метки в цифры. Поскольку у нас есть только две метки на выходе, то есть “положительный” и “отрицательный”. Мы можем просто преобразовать их в целые числа, заменив “положительный” на цифру 1 и отрицательный на цифру 0, как показано ниже:

y = movie_reviews['sentiment']

y = np.array(list(map(lambda x: 1 if x=="positive" else 0, y)))

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

Мы можем использовать метод train_test_split из модуля sklearn.model.selection , как показано ниже:

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=42)

Приведенный выше сценарий делит наши данные на 80% для обучающего набора и 20% для тестового набора.

Теперь давайте напишем сценарий для нашего слоя встраивания. Слой встраивания преобразует ваши текстовые данные в числовые и используется в качестве первого слоя для моделей глубокого обучения в Keras.

Подготовка слоя встраивания

В качестве первого шага мы будем использовать класс Tokenizer из модуля keras.preprocessing.text для создания словаря word-to-index. В словаре word-to-index каждое слово в корпусе используется в качестве ключа, в то время как соответствующий уникальный индекс используется в качестве значения для ключа. Выполните следующий сценарий:

tokenizer = Tokenizer(num_words=5000)
tokenizer.fit_on_texts(X_train)

X_train = tokenizer.texts_to_sequences(X_train)
X_test = tokenizer.texts_to_sequences(X_test)

Если вы просмотрите переменную X_train в обозревателе переменных, то увидите, что она содержит 40 000 списков, каждый из которых содержит целые числа. Каждый список фактически соответствует каждому предложению в обучающем наборе. Вы также заметите, что размер каждого списка отличается. Это потому, что предложения имеют разную длину.

Мы устанавливаем максимальный размер каждого списка равным 100. Вы можете попробовать другой размер. Списки размером более 100 будут усечены до 100. Для списков, длина которых меньше 100, мы добавим 0 в конце списка, пока он не достигнет максимальной длины. Этот процесс называется заполнением.

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

# Adding 1 because of reserved 0 index
vocab_size = len(tokenizer.word_index) + 1

maxlen = 100

X_train = pad_sequences(X_train, padding='post', maxlen=maxlen)
X_test = pad_sequences(X_test, padding='post', maxlen=maxlen)

Теперь , если вы просмотрите X_train или X_test , вы увидите, что все списки имеют одинаковую длину, то есть 100. Кроме того, переменная vocabulary_size теперь содержит значение 92547, что означает, что наш корпус содержит 92547 уникальных слов.

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

from numpy import array
from numpy import asarray
from numpy import zeros

embeddings_dictionary = dict()
glove_file = open('E:/Datasets/Word Embeddings/glove.6B.100d.txt', encoding="utf8")

for line in glove_file:
    records = line.split()
    word = records[0]
    vector_dimensions = asarray(records[1:], dtype='float32')
    embeddings_dictionary [word] = vector_dimensions
glove_file.close()

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

embedding_matrix = zeros((vocab_size, 100))
for word, index in tokenizer.word_index.items():
    embedding_vector = embeddings_dictionary.get(word)
    if embedding_vector is not None:
        embedding_matrix[index] = embedding_vector

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

Классификация текста с помощью простой нейронной сети

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

model = Sequential()
embedding_layer = Embedding(vocab_size, 100, weights=[embedding_matrix], input_length=maxlen , trainable=False)
model.add(embedding_layer)

model.add(Flatten())
model.add(Dense(1, activation='sigmoid'))

В приведенном выше скрипте мы создаем модель Sequential () . Затем мы создаем наш слой встраивания. Слой встраивания будет иметь входную длину 100, размер выходного вектора также будет равен 100. Объем словарного запаса составит 92547 слов. Поскольку мы не тренируем наши собственные вложения и используем встраивание перчаток, мы устанавливаем trainable в False и в атрибуте weights передаем нашу собственную матрицу встраивания.

Затем в нашу модель добавляется слой встраивания. Далее, поскольку мы непосредственно соединяем наш слой встраивания с плотно связанным слоем, мы выравниваем слой встраивания. Наконец, мы добавляем плотный слой с функцией активации sigmoid .

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

model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])

print(model.summary())

Вывод выглядит следующим образом:

Layer (type)                 Output Shape              Param #
=================================================================
embedding_1 (Embedding)      (None, 100, 100)          9254700
_________________________________________________________________
flatten_1 (Flatten)          (None, 10000)             0
_________________________________________________________________
dense_1 (Dense)              (None, 1)                 10001
=================================================================
Total params: 9,264,701
Trainable params: 10,001
Non-trainable params: 9,254,700

Поскольку в нашем корпусе 92547 слов и каждое слово представлено в виде 100-мерного вектора, то число обучаемых параметров будет 92547x100 в слое вложения. В слое выравнивания мы просто умножаем строки и столбцы. Наконец, в плотном слое число параметров равно 10000 (от выравнивающего слоя) и 1 для параметра смещения, в общей сложности 10001.

Давайте теперь потренируем нашу модель:

history = model.fit(X_train, y_train, batch_size=128, epochs=6, verbose=1, validation_split=0.2)

В приведенном выше сценарии мы используем метод fit для обучения нашей нейронной сети. Обратите внимание, что мы тренируемся только на нашем поезде. Значение validation_split 0.2 означает, что для определения точности обучения алгоритма используется 20% обучающих данных.

В конце тренировки вы увидите, что точность тренировки составляет около 85,52%.

Чтобы оценить производительность модели, мы можем просто передать тестовый набор в метод evaluate нашей модели.

score = model.evaluate(X_test, y_test, verbose=1)

Чтобы проверить точность теста и потери, выполните следующий сценарий:

print("Test Score:", score[0])
print("Test Accuracy:", score[1])

Как только вы выполните описанный выше сценарий, вы увидите, что мы получаем точность теста 74,68%. Точность наших тренировок составила 85,52%. Это означает, что наша модель переобучается на тренировочном наборе. Переобучение происходит, когда ваша модель работает лучше на тренировочном наборе, чем на тестовом. В идеале разница в производительности между тренировочными и тестовыми наборами должна быть минимальной.

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

plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train','test'], loc='upper left')
plt.show()

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])

plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train','test'], loc='upper left')
plt.show()

Выход:

Вы можете ясно видеть различия в потерях и точности между тренировочными и тестовыми наборами.

Классификация текста с помощью сверточной нейронной сети

Сверточная нейронная сеть-это тип сети, который в основном используется для 2D-классификации данных, таких как изображения. Сверточная сеть пытается найти определенные особенности в изображении в первом слое. В следующих слоях первоначально обнаруженные объекты соединяются вместе, образуя более крупные объекты. Таким образом, обнаруживается весь образ.

Оказалось, что сверточные нейронные сети хорошо работают и с текстовыми данными. Хотя текстовые данные одномерны, мы можем использовать 1D сверточные нейронные сети для извлечения объектов из наших данных. Чтобы узнать больше о сверточных нейронных сетях, пожалуйста, обратитесь к этой статье .

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

model = Sequential()

embedding_layer = Embedding(vocab_size, 100, weights=[embedding_matrix], input_length=maxlen , trainable=False)
model.add(embedding_layer)

model.add(Conv1D(128, 5, activation='relu'))
model.add(GlobalMaxPooling1D())
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])

В приведенном выше скрипте мы создаем последовательную модель, за которой следует слой встраивания. Этот шаг похож на то, что мы делали ранее. Затем мы создаем одномерный сверточный слой со 128 объектами, или ядрами. Размер ядра равен 5, а используемая функция активации – сигмовидная . Затем мы добавим глобальный максимальный слой пула, чтобы уменьшить размер объекта. Наконец, мы добавляем плотный слой с сигмовидной активацией. Процесс компиляции такой же, как и в предыдущем разделе.

Давайте теперь посмотрим краткое изложение нашей модели:

print(model.summary())
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
embedding_2 (Embedding)      (None, 100, 100)          9254700
_________________________________________________________________
conv1d_1 (Conv1D)            (None, 96, 128)           64128
_________________________________________________________________
global_max_pooling1d_1 (Glob (None, 128)               0
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 129
=================================================================
Total params: 9,318,957
Trainable params: 64,257
Non-trainable params: 9,254,700

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

Давайте теперь потренируем нашу модель и оценим ее на тренировочном наборе. Процесс обучения и тестирования нашей модели остается прежним. Для этого мы можем использовать методы fit и evaluate соответственно.

history = model.fit(X_train, y_train, batch_size=128, epochs=6, verbose=1, validation_split=0.2)

score = model.evaluate(X_test, y_test, verbose=1)

Следующий сценарий печатает результаты:

print("Test Score:", score[0])
print("Test Accuracy:", score[1])

Если вы сравните точность обучения и тестирования, то увидите, что точность обучения для CNN составит около 92%, что больше, чем точность обучения простой нейронной сети. Точность теста составляет около 82% для CNN, что также больше, чем точность теста для простой нейронной сети, которая составляла около 74%.

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

import matplotlib.pyplot as plt

plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])

plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train','test'], loc = 'upper left')
plt.show()

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])

plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train','test'], loc = 'upper left')
plt.show()

Выход:

Вы можете ясно видеть разницу в потерях и точности между поездом и тестовыми наборами.

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

Классификация текста с помощью рекуррентной нейронной сети (LSTM)

Рекуррентная нейронная сеть-это тип нейронных сетей, который, как доказано, хорошо работает с последовательными данными. Поскольку текст на самом деле представляет собой последовательность слов, рекуррентная нейронная сеть является автоматическим выбором для решения связанных с текстом задач. В этом разделе мы будем использовать LSTM (Long Short Term Memory network), который является вариантом RNN, для решения задачи классификации настроений.

Еще раз выполните код до раздела встраивания слова и после этого запустите следующий фрагмент кода.

model = Sequential()
embedding_layer = Embedding(vocab_size, 100, weights=[embedding_matrix], input_length=maxlen , trainable=False)
model.add(embedding_layer)
model.add(LSTM(128))

model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['acc'])

В приведенном выше сценарии мы начинаем с инициализации последовательной модели, за которой следует создание слоя встраивания. Затем мы создаем слой LSTM со 128 нейронами (вы можете поиграть с количеством нейронов). Остальная часть кода такая же, как и для Си-Эн-эн.

Давайте построим краткое изложение нашей модели.

print(model.summary())

Краткое описание модели выглядит следующим образом:

_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
embedding_3 (Embedding)      (None, 100, 100)          9254700
_________________________________________________________________
lstm_1 (LSTM)                (None, 128)               117248
_________________________________________________________________
dense_3 (Dense)              (None, 1)                 129
=================================================================
Total params: 9,372,077
Trainable params: 117,377
Non-trainable params: 9,254,700

Наш следующий шаг состоит в том, чтобы обучить модель на обучающем наборе и оценить ее производительность на тестовом наборе.

history = model.fit(X_train, y_train, batch_size=128, epochs=6, verbose=1, validation_split=0.2)

score = model.evaluate(X_test, y_test, verbose=1)

Приведенный выше сценарий обучает модель на тестовом наборе. Размер партии-128, а количество эпох-6. В конце тренировки вы увидите, что точность тренировки составляет около 85,40%.

Как только модель обучена, мы можем увидеть результаты модели на тестовом наборе со следующим сценарием:

print("Test Score:", score[0])
print("Test Accuracy:", score[1])

На выходе вы увидите, что точность нашего теста составляет около 85,04%. Точность теста лучше, чем у CNN и плотно связанной нейронной сети. Кроме того, мы видим, что существует очень небольшая разница между точностью обучения и точностью тестирования, что означает, что наша модель не является чрезмерной.

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

import matplotlib.pyplot as plt

plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])

plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train','test'], loc='upper left')
plt.show()

plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])

plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train','test'], loc='upper left')
plt.show()

Выход:

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

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

Составление прогнозов на одном экземпляре

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

Давайте сначала случайным образом выберем любой отзыв из нашего корпуса:

instance = X[57]
print(instance)

Выход:

I laughed all the way through this rotten movie It so unbelievable woman leaves her husband after many years of marriage has breakdown in front of real estate office What happens The office manager comes outside and offers her job Hilarious Next thing you know the two women are going at it Yep they re lesbians Nothing rings true in this Lifetime for Women with nothing better to do movie Clunky dialogue like don want to spend the rest of my life feeling like had chance to be happy and didn take it doesn help There a wealthy distant mother who disapproves of her daughter new relationship sassy black maid unbelievable that in the year film gets made in which there a sassy black maid Hattie McDaniel must be turning in her grave The woman has husband who freaks out and wants custody of the snotty teenage kids Sheesh No cliche is left unturned

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

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

instance = tokenizer.texts_to_sequences(instance)

flat_list = []
for sublist in instance:
    for item in sublist:
        flat_list.append(item)

flat_list = [flat_list]

instance = pad_sequences(flat_list, padding='post', maxlen=maxlen)

model.predict(instance)

Вывод выглядит следующим образом:

array([[0.3304276]], dtype=float32)

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

Вывод

Классификация текста-одна из наиболее распространенных задач обработки естественного языка. В этой статье мы рассмотрели, как выполнить анализ настроений, который представляет собой тип классификации текста с использованием библиотеки глубокого обучения Keras. Мы использовали три различных типа нейронных сетей для классификации общественных настроений по поводу различных фильмов. Результаты показывают, что LSTM, являющийся вариантом RNN, превосходит как CNN, так и простую нейронную сеть.