基於LSTM和詞嵌入的tweet文本分類

做者|Emmanuella Anggi
編譯|VK
來源|Towards Data Sciencepython

在這篇文章中,我將詳細介紹如何使用fastText和GloVe做單詞嵌入到LSTM模型上進行文本分類。git

我在寫關於天然語言生成的論文時對詞嵌入產生了興趣。詞嵌入提升了模型的性能。在本文中,我想看看每種方法(有fastText和GloVe以及不使用)對預測的影響。github

在個人Github代碼中,我還將結果與CNN進行了比較。我在這裏使用的數據集來自Kaggle,由tweets組成,標籤是代表推特是不是災難性推特(描述災難的推特)。說實話,在第一次看到這個數據集時,我馬上想到了BERT,它的理解能力比我在本文中提出的更好(進一步閱讀BERT)。架構

但不管如何,在本文中,我將重點介紹fastText和GloVe。app


數據+預處理

數據包括7613條tweet(Text列)和label(Target列),無論他們是否在談論真正的災難。有3271行通知實際災難,有4342行通知非實際災難。若是你想了解更多關於數據的信息,能夠在這裏閱讀。dom

連接:https://www.kaggle.com/c/nlp-...機器學習

文本中真實災難詞的例子:性能

「 Forest fire near La Ronge Sask. Canada 「

使用災難詞而不是關於災難的例子:學習

「These boxes are ready to explode! Exploding Kittens finally arrived! gameofkittens #explodingkittens」

數據將被分紅訓練(6090行)和測試(1523行)集,而後進行預處理。咱們將只使用文本列和目標列。測試

from sklearn.model_selection import train_test_split

data = pd.read_csv('train.csv', sep=',', header=0)

train_df, test_df = train_test_split(data, test_size=0.2, random_state=42, shuffle=True)

此處使用的預處理步驟:

  1. 小寫
  2. 清除停用詞
  3. 標記化
from sklearn.utils import shuffle

raw_docs_train = train_df['text'].tolist()
raw_docs_test = test_df['text'].tolist()
num_classes = len(label_names)

processed_docs_train = []

for doc in tqdm(raw_docs_train):
  tokens = word_tokenize(doc)
  filtered = [word for word in tokens if word not in stop_words]
  processed_docs_train.append(" ".join(filtered))

processed_docs_test = []

for doc in tqdm(raw_docs_test):
  tokens = word_tokenize(doc)
  filtered = [word for word in tokens if word not in stop_words]
  processed_docs_test.append(" ".join(filtered))

tokenizer = Tokenizer(num_words=MAX_NB_WORDS, lower=True, char_level=False)
tokenizer.fit_on_texts(processed_docs_train + processed_docs_test)  

word_seq_train = tokenizer.texts_to_sequences(processed_docs_train)
word_seq_test = tokenizer.texts_to_sequences(processed_docs_test)
word_index = tokenizer.word_index

word_seq_train = sequence.pad_sequences(word_seq_train, maxlen=max_seq_len)

word_seq_test = sequence.pad_sequences(word_seq_test, maxlen=max_seq_len)

詞嵌入

第1步:下載預訓練模型

使用fastText和Glove的第一步是下載每一個預訓練過的模型。我使用google colab來防止個人筆記本電腦使用大內存,因此我用request library下載了它,而後直接在notebook上解壓。

我使用了兩個詞嵌入中最大的預訓練模型。fastText模型給出了200萬個詞向量,而GloVe給出了220萬個單詞向量。

fastText預訓練模型下載
import requests, zipfile, io

zip_file_url = 「https://dl.fbaipublicfiles.com/fasttext/vectors-english/wiki-news-300d-1M.vec.zip"

r = requests.get(zip_file_url)

z = zipfile.ZipFile(io.BytesIO(r.content))

z.extractall()
GloVe預訓練模型下載
import requests, zipfile, io

zip_file_url = 「http://nlp.stanford.edu/data/glove.840B.300d.zip"

r = requests.get(zip_file_url)

z = zipfile.ZipFile(io.BytesIO(r.content))

z.extractall()

第2步:下載預訓練模型

FastText提供了加載詞向量的格式,須要使用它來加載這兩個模型。

embeddings_index = {}

f = codecs.open(‘crawl-300d-2M.vec’, encoding=’utf-8')
# Glove
# f = codecs.open(‘glove.840B.300d.txt’, encoding=’utf-8')

for line in tqdm(f):

    values = line.rstrip().rsplit(‘ ‘)

    word = values[0]

    coefs = np.asarray(values[1:], dtype=’float32')

    embeddings_index[word] = coefs

f.close()

第3步:嵌入矩陣

採用嵌入矩陣來肯定訓練數據中每一個詞的權重。

可是有一種可能性是,有些詞不在向量中,好比打字錯誤、縮寫或用戶名。這些單詞將存儲在一個列表中,咱們能夠比較處理來自fastText和GloVe的詞的性能

words_not_found = []

nb_words = min(MAX_NB_WORDS, len(word_index)+1)
embedding_matrix = np.zeros((nb_words, embed_dim))

for word, i in word_index.items():
  if i >= nb_words:
     continue
  embedding_vector = embeddings_index.get(word)
  
  if (embedding_vector is not None) and len(embedding_vector) > 0:
     embedding_matrix[i] = embedding_vector
  else:
     words_not_found.append(word)

print('number of null word embeddings: %d' % np.sum(np.sum(embedding_matrix, axis=1) == 0))

fastText上的null word嵌入數爲9175,GloVe 上的null word嵌入數爲9186。

LSTM

你能夠對超參數或架構進行微調,但我將使用很是簡單的一個架構,它包含嵌入層、LSTM層、Dense層和Dropout層。

from keras.layers import BatchNormalization
import tensorflow as tf

model = tf.keras.Sequential()

model.add(Embedding(nb_words, embed_dim, input_length=max_seq_len, weights=[embedding_matrix],trainable=False))

model.add(Bidirectional(LSTM(32, return_sequences= True)))
model.add(Dense(32,activation=’relu’))

model.add(Dropout(0.3))
model.add(Dense(1,activation=’sigmoid’))

model.summary()

from keras.optimizers import RMSprop
from keras.callbacks import ModelCheckpoint
from tensorflow.keras.callbacks import EarlyStopping

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

es_callback = EarlyStopping(monitor='val_loss', patience=3)

history = model.fit(word_seq_train, y_train, batch_size=256, epochs=30, validation_split=0.3, callbacks=[es_callback], shuffle=False)

結果

fastText的準確率爲83%,而GloVe的準確率爲81%。與沒有詞嵌入的模型(68%)的性能比較,能夠看出詞嵌入對性能有顯著的影響。

fastText 嵌入的準確度

GloVe 嵌入的準確度

沒有詞嵌入的準確度

若是你想將代碼其應用於其餘數據集,能夠在Github上看到完整的代碼。

Github上完整代碼:https://github.com/emmanuella...

原文連接:https://towardsdatascience.co...

歡迎關注磐創AI博客站:
http://panchuang.net/

sklearn機器學習中文官方文檔:
http://sklearn123.com/

歡迎關注磐創博客資源彙總站:
http://docs.panchuang.net/

相關文章
相關標籤/搜索