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

【导读】情感分析是NLP中最常见的应用之一,作者在博文中把情感分析建模成二分类问题,使用端到端的RNN网络建模,用Keras实现,简洁易懂,是学习RNN文本建模的好文,并附相应的Python代码实现。


作者 | Susan Li

编译 | 专知

整理 | Mandy



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])


图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])


图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

图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

图4


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


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


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


结果:
Test accuracy: 0.86964


总结




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

源代码可以在我们的Github中找到。期待听到大家的反馈或问题。


Github:

https://github.com/susanli2016/NLP-with-Python/blob/master/Sentiment%20Analysis%20with%20RNN.ipynb


原文链接:

https://towardsdatascience.com/a-beginners-guide-on-sentiment-analysis-with-rnn-9e100627c02e

-END-

专 · 知


人工智能领域主题知识资料查看与加入专知人工智能服务群

【专知AI服务计划】专知AI知识技术服务会员群加入人工智能领域26个主题知识资料全集获取欢迎微信扫一扫加入专知人工智能知识星球群,获取专业知识教程视频资料和与专家交流咨询


请PC登录www.zhuanzhi.ai或者点击阅读原文,注册登录专知,获取更多AI知识资料

请加专知小助手微信(扫一扫如下二维码添加),加入专知主题群(请备注主题类型:AI、NLP、CV、 KG等)交流~



关注专知公众号,获取人工智能的专业知识!

点击“阅读原文”,使用专知

展开全文
Top
微信扫码咨询专知VIP会员