IMDB电影评论情感分析(三) 构建LSTM模型

举报
tengyun 发表于 2019/10/30 11:33:32 2019/10/30
【摘要】 在前两篇中,我们探索了IMDB电影评论的数据集,使用卷积神经网络来对IMDB电影评论进行分析,但多层感知机或者卷积神经网络都只能依照当前的状态进行识别,如果处理时间序列的问题,就需要使用LSTM模型了。 LSTM全名是Long Short-Term Memory,长短时记忆网络,可以用来处理时序数据,在自然语言处理和语音识别等领域应用广泛。和原始的循环神经网络RNN相比,LSTM解决了

        在前两篇中,我们探索了IMDB电影评论的数据集,使用卷积神经网络来对IMDB电影评论进行分析,多层感知机或者卷积神经网络都只能依照当前的状态进行识别,如果处理时间序列的问题,就需要LSTM模型了。

        LSTM全名是Long Short-Term Memory,长短时记忆网络,可以用来处理时序数据,在自然语言处理和语音识别等领域应用广泛。和原始的循环神经网络RNN相比,LSTM解决了RNN的梯度消失问题,可以处理长序列数据,成为当前最流行的RNN变体。

具体原理可以参见  LSTM的原理详解及实战(一)  

构建简单LSTM

        我们首先构建一个简单的LSTM模型,来看一下LSTM对IMDB影评的分析效果,模型中包含一个词嵌入层,一个LSTM层和一个输出层,具体如下:

from keras.datasets import imdb

import numpy as np

from keras.preprocessing import sequence

from keras.models import Sequential

from keras.layers.embeddings import Embedding

from keras.layers import LSTM

from keras.layers import Dense

seed = 7

top_words = 5000

max_words = 500

out_dimension = 32

batch_size = 128

epochs = 5

# 构建模型

def build_model():

   model = Sequential()

   model.add(Embedding(top_words, out_dimension, input_length=max_words))

   model.add(LSTM(units=100))

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

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

   # 输出模型的概要信息

   model.summary()

   return model

if __name__ == '__main__':

   np.random.seed(seed=seed)

   # 导入数据

   (x_train, y_train), (x_validation, y_validation) = imdb.load_data(num_words=top_words)

   # 限定数据集的长度

   x_train = sequence.pad_sequences(x_train, maxlen=max_words)

   x_validation = sequence.pad_sequences(x_validation, maxlen=max_words)

   # 生产模型并训练模型

   model = build_model()

   model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=2)

   scores = model.evaluate(x_validation, y_validation, verbose=2)

   print('Accuracy: %.2f%%' % (scores[1] * 100))

执行结果如下:

1.jpg

可以看到,在评估数据集上的准确率是87.38%,准确率还是非常不错的。


混合使用LSTM和CNN

        卷积神经网络对于稀疏结构的数据处理非常有效,能够挑选出不良情绪的不变特征,通过CNN学习后的空间特征,

可以被LSTM层学习为序列。

具体实现为,在词嵌入层后,通过添加一维CNN和最大池化层,在卷积层是有32个特征的滤波器,并将步长设置为3,

池化层步长设置为2,将特征图大小减半,将合并的特征提供给LSTM。

# 构建模型部分代码

def build_model():

model = Sequential()

model.add(Embedding(top_words, out_dimension, input_length=max_words))

model.add(Conv1D(filters=32, kernel_size=3, padding='same', activation='relu'))

model.add(MaxPooling1D(pool_size=2))

model.add(LSTM(units=100))

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

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

# 输出模型的概要信息

model.summary()

return model

执行结果如下:

2.jpg

可以看到,我们增加了一层卷积层和池化层,并使用了dropout来避免过拟合,准确率就达到了88.56%,比上面例子中的仅仅使用LSTM层 有了一定幅度的提升。

预测概率和预测结果

查看输出的概率

probility=model.predict(x_test)probility[:10]

3.png

查看输出的结果,大于0.5的为1.小于0.5的为0

predict=model.predict_classes(x_validation)

predict[:10]

4.png

查看验证集中的文本及其预测结果

# A dictionary mapping words to an integer index

word_index = imdb.get_word_index()

# The first indices are reserved

word_index = {k:(v+3) for k,v in word_index.items()}

word_index["<PAD>"] = 0

word_index["<START>"] = 1

word_index["<UNK>"] = 2  # unknown

word_index["<UNUSED>"] = 3

reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])

def decode_review(text):

   return ' '.join([reverse_word_index.get(i, '?') for i in text])


decode_review(x_validation[2])

5.png


SentimentDict={1:'正面的',0:'负面的'}

def display_test_Sentiment(i):

   #print(x_validation[i])

   print('label:',SentimentDict[y_validation[i]],

         '预测结果:',SentimentDict[predict[i][0]])

display_test_Sentiment(2)

6.png


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。