0
雷鋒網按:本文為雷鋒網字幕組編譯的技術博客,原標題 Advances in Semantic Textual Similarity,作者為 Google AI 的軟件工程師與技術主管 Yinfei Yang。
翻譯 | 陳濤 整理 | 孔令雙
原文鏈接:
https://towardsdatascience.com/a-beginners-guide-on-sentiment-analysis-with-rnn-9e100627c02e

圖片來源:Unsplash
情感分析可能是最常見的 自然語言處理 的應用之一。我無需去額外強調在客服工具中情感分析的重要性。本文將利用循環神經網絡,訓練出一個基于 IMDB 數據集的電影評論分類器。如果你想了解更多關于深度學習在情感分析中的應用,這里推薦一篇很棒的論文。
我們將采用循環神經網絡,具體地說應該是 LSTM,去實現基于 Keras 的情感分析。Keras 已經將 IMBD 電影評論數據內置其中,我們可以很方便地調用。
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 個測試樣本。
查看一條評論樣本及其標簽。
print('---review---')
print(X_train[6])
print('---label---')
print(y_train[6])

圖 1
請注意,評論是以一串整數的形式進行存儲的,它們表示預先分配給每個詞語的 ID。標簽則用一個整數表示,0 代表消極的評價,1 代表積極的評價。
我們可以利用imdb.get_word_index()函數返回的字典,從而將評論映射回原有的文字。
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('Maximum review 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 個詞
為了讓數據能夠輸入 RNN 模型,所有的輸入文檔必須有相同的長度。我們需要設置max_words變量來限制評論的最大長度,超過該長度的評論將被截斷,不足該長度的評論將被填充空值(0)。在 Keras 中,我們可以使用pad_sequences()函數來達到此目標。現在設置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)
我們開始在下面的代碼單元中創建模型架構。我們已經從 Keras 中導入了一些你可能會用到的網絡層,當然你也可以使用任何你喜歡的網絡層或者轉換器。
記住,我們的輸入是一串詞語,從學術上講,是整數形式的詞語 ID,其最大長度等于max_words變量值。而我們的輸出是二進制形式的情感標簽(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
總結一下,我們創建了一個簡單的 RNN 模型,其擁有一個嵌入層,一個 LSTM 層和一個全連接層。這其中一共有 233301 個待訓練的參數。
我們需要先對模型進行編譯,包括指定損失函數,訓練中想采用的優化器和用于測量的評價指標。設置好合適的參數,其中包含至少一個度量指標:準確率。
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
編譯完成后,就可以開啟訓練過程了。我們需要指定兩個很重要的訓練參數:每一批量中的樣本數和訓練迭代次數,它們和我們的模型架構一起決定了總體的訓練時間。
訓練可能需要一段時間,所以可以去喝杯咖啡,或者更好地去跑會步吧。
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
訓練完成后,接下來就可以看下模型在未處理過的測試數據上的表現了。
我們設置了metrics=['accuracy'],scores[1]就代表此次評估的準確率。
scores = model.evaluate(X_test, y_test, verbose=0)
print('Test accuracy:', scores[1])
測試準確率為 0.86964
創建模型的方法有很多種。我們可以嘗試不同的架構,網絡層及參數,從而不斷提高模型的準確率。在這一過程中,我們可以思考,在避免消耗長時間訓練的前提下,我們還能做怎樣的提升?我們應該如何避免過擬合?
本文的代碼可以從 Github 上下載。非常期待能聽到大家的反饋和問題。
雷鋒網字幕組編譯。

雷峰網版權文章,未經授權禁止轉載。詳情見轉載須知。