作者|Emmanuella Anggi
編譯|VK
來源|Towards Data Science

在這篇文章中,我將詳細介紹如何使用fastText和GloVe作單詞嵌入到LSTM模型上進行文本分類,
我在寫關于自然語言生成的論文時對詞嵌入產生了興趣,詞嵌入提高了模型的性能,在本文中,我想看看每種方法(有fastText和GloVe以及不使用)對預測的影響,
在我的Github代碼中,我還將結果與CNN進行了比較,我在這里使用的資料集來自Kaggle,由tweets組成,標簽是表明推特是否是災難性推特(描述災難的推特),說實話,在第一次看到這個資料集時,我立刻想到了BERT,它的理解能力比我在本文中提出的更好(進一步閱讀BERT),
但無論如何,在本文中,我將重點介紹fastText和GloVe,
資料+預處理
資料包括7613條tweet(Text列)和label(Target列),不管他們是否在談論真正的災難,有3271行通知實際災難,有4342行通知非實際災難,如果你想了解更多關于資料的資訊,可以在這里閱讀,
鏈接:https://www.kaggle.com/c/nlp-getting-started

文本中真實災難詞的例子:
“ 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 = https://www.cnblogs.com/panchuangai/p/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)
此處使用的預處理步驟:
-
小寫
-
清除停用詞
-
標記化
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/emmanuellaanggi/disaster_tweet_sentiment,
原文鏈接:https://towardsdatascience.com/text-classification-on-disaster-tweets-with-lstm-and-word-embedding-df35f039c1db
歡迎關注磐創AI博客站:
http://panchuang.net/
sklearn機器學習中文官方檔案:
http://sklearn123.com/
歡迎關注磐創博客資源匯總站:
http://docs.panchuang.net/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/39771.html
標籤:其他
上一篇:使用深度學習識別狗的品種
下一篇:主機亮了,顯示幕沒亮
