手把手教你用RNN做情感分析—初学者指南(附代码)

  1. 云栖社区>
  2. 专知>
  3. 博客>
  4. 正文

手把手教你用RNN做情感分析—初学者指南(附代码)

技术小能手 2018-07-17 19:50:41 浏览3315
展开阅读全文

A Beginner’s Guide on Sentiment Analysis with RNN

情感分析(Sentiment analysis)可以说是自然语言处理最常见的一个应用了。我不需要再强调对客户服务工具的情感分析变得有多么重要。因此在这里,我们将使用RNN(Recurrent Neural Networks)在 IMDB数据集【】中训练一个电影评论分类器。如果你想要深入学习情感分析,请参考下面论文:
https://arxiv.org/ftp/arxiv/papers/1801/1801.07883.pdf

数据(The data)

我们将使用循环神经网络,特别是LSTM,在Keras中编写情感分析的代码。方便的是,Keras有一个内置的IMDb电影评论数据集,我们可以使用它。

from keras.datasets import imdb

设置词库的大小,加载训练和测试数据。

vocabulary_size = 5000
(X_train, y_train), (X_test, y_test) = imdb.load_data(num_words = 
vocabulary_size)
print('Loaded dataset with {} training samples, {} test samples'.
format(len(X_train), len(X_test)))

加载数据集,包含25000个训练样本,25000个测试样本

检查样本及其标签(打印出某个样本)。
结果如图1所示

print('---review---')
print(X_train[6])
print('---label---')
print(y_train[6])

image

图1


值得注意的是评论被存储为一个整数序列。这个序列中的整数是预先分配给单个单词的单词id,标签是一个整数(0表示消极的,1表示积极的)。

我们可以使用imdb.get_word_index()返回的字典将评论映射回原始单词。如图2所示。

word2id = imdb.get_word_index()
id2word = {i: word for word, i in word2id.items()}
print('---review with words---')
print([id2word.get(i, ' ') for i in X_train[6]])
print('---label---')
print(y_train[6])

image

图2

打印出最长评论的长度和最短评论的长度:

print('Maximumreview length: {}'.format(
len(max((X_train+ X_test), key=len))))

最长评论的长度为2697

print('Minimum review length: {}'.format(
len(min((X_test + X_test), key=len))))

最短评论的长度为14

填充序列(Pad sequences)

为了将这些数据输入到RNN中,所有输入序列都必须具有相同的长度。我们将截断较长的评论,并限制评论的最大长度为max_words,并使用0来填充较短的评论。现在,将max_words设置为500。

from keras.preprocessing import sequence
max_words = 500
X_train = sequence.pad_sequences(X_train, maxlen=max_words)
X_test = sequence.pad_sequences(X_test, maxlen=max_words)

设计情感分析的RNN模型

我们开始在下面的代码单元中构建模型架构。我们已经从Keras中导入了一些layer,你可能需要这些layer,但是也可以自由地使用你喜欢的任何其他layers / transformations。

记住,我们的输入是一个最大长度为 max_words的单词序列(技术上说,序列中的整数为单词id),我们的输出是一个二进制情感标签(0或1)。

from keras import Sequential
from keras.layers import Embedding, LSTM, Dense, Dropout
embedding_size=32
model=Sequential()
model.add(Embedding(vocabulary_size, embedding_size, 
input_length=max_words))
model.add(LSTM(100))
model.add(Dense(1, activation='sigmoid'))
print(model.summary())

结果如图3

image

图3

总而言之,我们的模型是一个简单的RNN模型,具有1个embedding层,1个LSTM层和1个dense层。总共需要训练213,301个参数。

训练和评估我们的模型

我们首先需要通过指定在训练时使用的损失函数和优化器以及我们想要测量的任何评估指标来编译我们的模型。指定适当的参数,至少包括一个度量指标“accuracy”。

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

编译完成后,我们就可以开始训练过程。我们必须指定两个重要的训练参数——批处理大小(batch size)和训练周期的数量(number of training epochs),它们与我们的模型体系结构一起决定了总的训练时间。

训练可能需要一段时间!

batch_size = 64
num_epochs = 3
X_valid, y_valid = X_train[:batch_size], y_train[:batch_size]
X_train2, y_train2 = X_train[batch_size:], y_train[batch_size:]
model.fit(X_train2, y_train2, validation_data=(X_valid, y_valid), 
batch_size=batch_size, epochs=num_epochs)

结果如图4

image

图4


一旦我们训练好了模型,就该看看它在未知的测试数据上的表现如何了。

scores[1]将会对应于评价指标 metrics=[‘accuracy’]。

scores =model.evaluate(X_test, y_test, verbose=0)
print('Testaccuracy:', scores[1])

结果:
Test accuracy: 0.86964

总结

我们可以通过多种方式构建模型。我们可以通过尝试不同的架构,层和参数来继续尝试和提高模型的准确性。如果时间训练不长,我们能做得多好?如何防止过度拟合?

原文发布时间为:2018-07-17
本文作者:Susan Li
本文来自云栖社区合作伙伴“专知”,了解相关信息可以关注“专知

网友评论

登录后评论
0/500
评论
技术小能手
+ 关注
所属云栖号: 专知