IMDB电影评论情感分析(三) 构建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))
执行结果如下:
可以看到,在评估数据集上的准确率是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
执行结果如下:
可以看到,我们增加了一层卷积层和池化层,并使用了dropout来避免过拟合,准确率就达到了88.56%,比上面例子中的仅仅使用LSTM层 有了一定幅度的提升。
预测概率和预测结果
查看输出的概率
probility=model.predict(x_test)probility[:10]
查看输出的结果,大于0.5的为1.小于0.5的为0
predict=model.predict_classes(x_validation)
predict[:10]
查看验证集中的文本及其预测结果
# 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])
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)
- 点赞
- 收藏
- 关注作者
评论(0)