選自Toward Data Science,作者:Rohith Gandhi,機器之心編譯。
本文介紹瞭如何構建情感分類器,從介紹自然語言處理開始,一步一步講述構建過程。
自然語言處理簡介
語言把人類聯絡在一起。語言是一種工具,它既可以讓我們把想法和感受傳達給另一個人,也能讓我們理解別人的想法和感受。我們大多數人從 1 歲半到 2 歲開始說話。人腦是如何在如此年幼的時候掌握如此大量知識的,這仍是未解之謎。但是,人們已經發現大部分語言處理功能發生在大腦皮層內。
情感分析背後的動機
人類自己無法理解語言是如何被大腦處理的。那麼,我們能教一臺機器學習我們的語言嗎?通過廣泛研究,人們已經開發了許多方法來幫助機器理解語言。自然語言處理(NLP)是研究人類語言與計算機互動的領域。自然語言處理的一個子問題是情感分析,即把一個語句分類為積極或消極。把語句分類為積極或消極有什麼用呢?以亞馬遜網站為例。在亞馬遜上,使用者可以對一個產品發表評論,說明它是好是壞,甚至可以是中性的。然而,使用人工閱讀所有評論並獲得客戶對產品的總體反饋既昂貴又耗時。再說說我們的機器學習模型。機器學習模型可以通過大量資料進行推斷,對評論進行分類。利用這種機器學習模型,亞馬遜可以通過客戶評論改進其產品,從而為公司帶來更多收入。
情感分析並不像看起來那麼簡單。如果你認為含有「好的」、「很棒」等詞的評論可歸為積極評論,而含有「壞的」、「苦惱的」等詞的評論可歸為消極評論,那你需要三思。例如,「完全沒有好味道」和「一份好的快餐,但沒有什麼特別的」分別代表消極和中立的反饋,即使都有「好」字。因此,這項任務可能沒有看起來那麼簡單。接下來讓我們看看即將使用的資料。
資料集
我們將使用亞馬遜產品評論、IMDB 電影評論和 Yelp 評論來構建情感分析模型。
資料下載連結:www.kaggle.com/marklvl/sen…
所有資料都已經過註釋,0 表示消極反饋,1 表示積極反饋。亞馬遜的資料與下圖相似。
程式碼
我們可以寫一些程式碼:
with open("/Users/rohith/Documents/Datasets/sentiment_labelled_sentences/amazon_cells_labelled.txt") as f1:
lines = f1.readlines()
with open("/Users/rohith/Documents/Datasets/sentiment_labelled_sentences/imdb_labelled.txt") as f1:
temp = f1.readlines()
lines=lines+temp
with open("/Users/rohith/Documents/Datasets/sentiment_labelled_sentences/yelp_labelled.txt") as f1:
temp = f1.readlines()
lines=lines+temp
複製程式碼
資料儲存於不同的文字檔案中。我們開啟每個檔案並閱讀所有的文字行,文字行還包括每個文字的標籤。然後我們將其儲存在一個名為「lines」的列表中。
x = []
y = []
for value in lines:
temp = value.split('\t')
x.append(temp[0])
temp[1].replace('\n','')
y.append(int(temp[1]))
複製程式碼
資料集的每一行都包含文字,文字後是四個字元空間,還有該文字的標籤(0 或 1)。因此,我們先將包含文字的第一部分新增到 features(x) 中,然後獲取標籤,標籤的末尾有「\n」。所以標籤被移除,然後新增到我們的標籤列表 labels(y)。
from keras.preprocessing.text import Tokenizer
tokenizer = Tokenizer(num_words=2500,split=' ')
tokenizer.fit_on_texts(x)
複製程式碼
Keras 有一個內建的 API,使得準備計算文字變得更容易。tokenizer 類共有 4 個屬性,可用於特徵準備。請看下面的示例,瞭解 tokenizer 的實際功能。
## CODE
tokenizer = Tokenizer()
texts = ["The sun is shining in June!","September is grey.","Life is beautiful in August.","I like it","This and other things?"]
tokenizer.fit_on_texts(texts)
print(tokenizer.word_index)
tokenizer.texts_to_sequences(["June is beautiful and I like it!"])
## OUPUT
{'sun': 3, 'september': 4, 'june': 5, 'other': 6, 'the': 7, 'and': 8, 'like': 9, 'in': 2, 'beautiful': 11, 'grey': 12, 'life': 17, 'it': 16, 'i': 14, 'is': 1, 'august': 15, 'things': 10, 'shining': 13, 'this': 18}
[[5, 1, 11, 8, 14, 9, 16]]
複製程式碼
tokenizer 為句子中的每個單詞分配索引值,並且可以使用該索引值表示新句子。由於我們使用的文字語料庫包含大量不同的單詞,因此我們設定了一個上限,只使用最經常出現的 2500 個單詞。
from keras.preprocessing.sequence import pad_sequences
X = tokenizer.texts_to_sequences(x)
X = pad_sequences(X)
複製程式碼
現在,我們將文字轉換為如上所示的數字序列,並填充數字序列。因為句子可以有不同的長度,它們的序列長度也會不同。因此,pad_sequences 會找出最長的句子,並用 0 填充其他較短語句以匹配該長度。
## Pad Sequences Example
pad_sequences([[1, 2, 3], [3, 4, 5, 6], [7, 8]])
array([[0, 1, 2, 3],
[3, 4, 5, 6],
[0, 0, 7, 8]], dtype=int32)
複製程式碼
import numpy as np
from sklearn.model_selection import train_test_split
Y = []
for val in y:
if(val == 0):
Y.append([1,0])
else:
Y.append([0,1])
Y = np.array(Y)
x_train, x_test, y_train, y_test = train_test_split(X,Y,train_size=0.8)
複製程式碼
我們將標籤轉換為 one hot 編碼,這有助於 LSTM 網路預測文字的標籤。現在,我們已經準備好了文字資料,可以把它分為訓練樣本和測試樣本。將 80% 的資料用於訓練,20% 的資料用於測試模型。
import keras
from keras.layers import Embedding, LSTM, Dense
from keras.models import Sequential
model = Sequential()
model.add(Embedding(2500,128,input_length=X.shape[1],dropout=0.2))
model.add(LSTM(300, dropout_U=0.2,dropout_W=0.2))
model.add(Dense(2,activation='softmax'))
model.compile(loss=keras.losses.categorical_crossentropy,optimizer='adam',metrics=['accuracy'])
model.fit(x_train,y_train,epochs=10,verbose=2,batch_size=32)
print(model.evaluate(x_test,y_test)[1])
複製程式碼
我們現在建立了模型,並對其進行編譯、訓練和測試。該模型具有嵌入層。輸入序列是文字的稀疏表徵,因為詞彙表巨大,並且給定單詞將由大向量表示。如果我們能夠構建序列的某種密集表徵,那麼網路將更容易進行預測。2500 個單詞的詞嵌入/密集表徵是通過嵌入層對模型進行訓練獲得的。然後,我們將 LSTM 和密集層新增到模型中。LSTM 單元負責進行上下文推斷,並幫助預測句子是否積極。密集層輸出每個類的概率。本文不詳細介紹 LSTM,若想了解其更多資訊,請參閱此部落格:colah.github.io/posts/2015-…。
輸出
完成!你剛剛用 50 行程式碼構建了一個情感分類器~
原文連結:towardsdatascience.com/sentiment-a…