一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

詞嵌入教程

 小世界的野孩子 2022-10-10 發(fā)布于北京

作者|Shraddha Anala
編譯|VK
來(lái)源|Towards Data Science

無(wú)論我們是誰(shuí),閱讀、理解、交流并最終產(chǎn)生新的內(nèi)容是我們?cè)诼殬I(yè)生活中都要做的事情。

當(dāng)涉及到從給定的文本體中提取有用的特征時(shí),所涉及的過(guò)程與連續(xù)整數(shù)向量(詞袋)相比是根本不同的。這是因?yàn)榫渥踊蛭谋局械男畔⑹且越Y(jié)構(gòu)化的順序編碼的,單詞的語(yǔ)義位置傳達(dá)了文本的意思。

因此,在保持文本的上下文意義的同時(shí),對(duì)數(shù)據(jù)進(jìn)行適當(dāng)表示的雙重要求促使我學(xué)習(xí)并實(shí)現(xiàn)了兩種不同的NLP模型來(lái)實(shí)現(xiàn)文本分類的任務(wù)。

詞嵌入是文本中單個(gè)單詞的密集表示,考慮到上下文和其他與之相關(guān)的單詞。

與簡(jiǎn)單的詞袋模型相比,該實(shí)值向量可以更有效地選擇維數(shù),更有效地捕捉詞與詞之間的語(yǔ)義關(guān)系。

簡(jiǎn)單地說(shuō),具有相似含義或經(jīng)常出現(xiàn)在相似上下文中的詞,將具有相似的向量表示,這取決于這些詞在其含義中的“接近”或“相距”有多遠(yuǎn)。

在本文中,我將探討兩個(gè)詞的嵌入-

  1. 訓(xùn)練我們自己的嵌入
  2. 預(yù)訓(xùn)練的GloVe 詞嵌入

數(shù)據(jù)集

對(duì)于這個(gè)案例研究,我們將使用Kaggle的Stack Overflow 數(shù)據(jù)集(https://www./imoore/60k-stack-overflow-questions-with-quality-rate)。這個(gè)數(shù)據(jù)集包含了6萬(wàn)個(gè)用戶在網(wǎng)站上提出的問(wèn)題,主要任務(wù)是將問(wèn)題分為3類。

現(xiàn)在讓我們看看這個(gè)多分類NLP項(xiàng)目的實(shí)際模型本身。

但是,在開(kāi)始之前,請(qǐng)確保你已經(jīng)安裝了這些包/庫(kù)。

pip install gensim            # 用于NLP預(yù)處理任務(wù)
pip install keras             # 嵌入層

1. 訓(xùn)練詞嵌入

如果你希望跳過(guò)解釋,請(qǐng)?jiān)L問(wèn)第一個(gè)模型的完整代碼:https://github.com/shraddha-an/nlp/blob/main/word_embedding_classification.ipynb

1) 數(shù)據(jù)預(yù)處理

在第一個(gè)模型中,我們將訓(xùn)練一個(gè)神經(jīng)網(wǎng)絡(luò)來(lái)從我們的文本語(yǔ)料庫(kù)中學(xué)習(xí)嵌入。具體地說(shuō),我們將使用Keras庫(kù)為神經(jīng)網(wǎng)絡(luò)的嵌入層提供詞標(biāo)識(shí)及其索引。

在訓(xùn)練我們的網(wǎng)絡(luò)之前,必須確定一些關(guān)鍵參數(shù)。這些包括詞匯的大小或語(yǔ)料庫(kù)中唯一單詞的數(shù)量以及嵌入向量的維數(shù)。

以下鏈接是用于訓(xùn)練和測(cè)試的數(shù)據(jù)集?,F(xiàn)在我們將導(dǎo)入它們,只保留問(wèn)題和質(zhì)量列以供分析:https://www./imoore/60k-stack-overflow-questions-with-quality-rate

我還更改了列名并定義了一個(gè)函數(shù)text_clean來(lái)清理問(wèn)題。

# 導(dǎo)入庫(kù)
# 數(shù)據(jù)操作/處理
import pandas as pd, numpy as np

# 可視化
import seaborn as sb, matplotlib.pyplot as plt

# NLP
import re
from nltk.corpus import stopwords
from gensim.utils import simple_preprocess

stop_words = set(stopwords.words('english'))

# 導(dǎo)入數(shù)據(jù)集
dataset = pd.read_csv('train.csv')[['Body', 'Y']].rename(columns = {'Body': 'question', 'Y': 'category'})

ds = pd.read_csv('valid.csv')[['Body', 'Y']].rename(columns = {'Body': 'question', 'Y': 'category'})



# 清理符號(hào)和HTML標(biāo)簽
symbols = re.compile(pattern = '[/<>(){}\[\]\|@,;]')
tags = ['href', 'http', 'https', 'www']

def text_clean(s: str) -> str:
    s = symbols.sub(' ', s)
    for i in tags:
        s = s.replace(i, ' ')

    return ' '.join(word for word in simple_preprocess(s) if not word in stop_words)

dataset.iloc[:, 0] = dataset.iloc[:, 0].apply(text_clean)
ds.iloc[:, 0] = ds.iloc[:, 0].apply(text_clean)

# 訓(xùn)練和測(cè)試集
X_train, y_train = dataset.iloc[:, 0].values, dataset.iloc[:, 1].values.reshape(-1, 1)
X_test, y_test = ds.iloc[:, 0].values, ds.iloc[:, 1].values.reshape(-1, 1)

# one-hot編碼
from sklearn.preprocessing import OneHotEncoder as ohe
from sklearn.compose import ColumnTransformer

ct = ColumnTransformer(transformers = [('one_hot_encoder', ohe(categories = 'auto'), [0])],
                       remainder = 'passthrough')

y_train = ct.fit_transform(y_train)
y_test = ct.transform(y_test)

# 設(shè)置參數(shù)
vocab_size = 2000
sequence_length = 100

如果你瀏覽原始數(shù)據(jù)集,你會(huì)發(fā)現(xiàn)HTML標(biāo)記中包含的問(wèn)題,例如,

…question

。此外,還有一些詞,如href,https等,在整個(gè)文本中都有,所以我要確保從文本中刪除這兩組不需要的字符。

Gensim的simple_preprocess方法返回一個(gè)小寫(xiě)的標(biāo)記列表,去掉重音符號(hào)。

在這里使用apply方法將通過(guò)預(yù)處理函數(shù)迭代運(yùn)行每一行,并在繼續(xù)下一行之前返回輸出。對(duì)訓(xùn)練和測(cè)試數(shù)據(jù)集應(yīng)用文本預(yù)處理功能。

因?yàn)樵谝蜃兞肯蛄恐杏?個(gè)類別,我們將應(yīng)用one-hot編碼并初始化一些參數(shù)以備以后使用。

2) 標(biāo)識(shí)化

接下來(lái),我們將使用Keras Tokenizer類將單詞組成的問(wèn)題轉(zhuǎn)換成一個(gè)數(shù)組,用它們的索引表示單詞。

因此,我們首先必須使用fit_on_texts方法,從數(shù)據(jù)集中出現(xiàn)的單詞構(gòu)建索引詞匯表。

在建立詞匯表之后,我們使用text_to_sequences方法將句子轉(zhuǎn)換成表示單詞的數(shù)字列表。

pad_sequences函數(shù)確保所有觀察值的長(zhǎng)度相同,可以設(shè)置為任意數(shù)字或數(shù)據(jù)集中最長(zhǎng)問(wèn)題的長(zhǎng)度。

我們先前初始化的vocab_size參數(shù)只是我們?cè)~匯表的大?。ㄓ糜趯W(xué)習(xí)和索引)。

# Keras的標(biāo)識(shí)器
from keras.preprocessing.text import Tokenizer

tk = Tokenizer(num_words = vocab_size)
tk.fit_on_texts(X_train)

X_train = tk.texts_to_sequences(X_train)
X_test = tk.texts_to_sequences(X_test)

# 用0填充所有
from keras.preprocessing.sequence import pad_sequences

X_train_seq = pad_sequences(X_train, maxlen = sequence_length, padding = 'post')
X_test_seq = pad_sequences(X_test, maxlen = sequence_length, padding = 'post')

3) 訓(xùn)練嵌入層

最后,在這一部分中,我們將構(gòu)建和訓(xùn)練我們的模型,它由兩個(gè)主要層組成,一個(gè)嵌入層將學(xué)習(xí)上面準(zhǔn)備的訓(xùn)練文檔,以及一個(gè)密集的輸出層來(lái)實(shí)現(xiàn)分類任務(wù)。

嵌入層將學(xué)習(xí)單詞的表示,同時(shí)訓(xùn)練神經(jīng)網(wǎng)絡(luò),需要大量的文本數(shù)據(jù)來(lái)提供準(zhǔn)確的預(yù)測(cè)。在我們的例子中,45000個(gè)訓(xùn)練觀察值足以有效地學(xué)習(xí)語(yǔ)料庫(kù)并對(duì)問(wèn)題的質(zhì)量進(jìn)行分類。我們將從指標(biāo)中看到。

# 訓(xùn)練嵌入層和神經(jīng)網(wǎng)絡(luò)
from keras.models import Sequential
from keras.layers import Embedding, Dense, Flatten

model = Sequential()
model.add(Embedding(input_dim = vocab_size, output_dim = 5, input_length = sequence_length))
model.add(Flatten())

model.add(Dense(units = 3, activation = 'softmax'))

model.compile(loss = 'categorical_crossentropy',
              optimizer = 'rmsprop',
              metrics = ['accuracy'])

model.summary()

history = model.fit(X_train_seq, y_train, epochs = 20, batch_size = 512, verbose = 1)

# 完成訓(xùn)練后保存模型
#model.save("model.h5")

4) 評(píng)估和度量圖

剩下的就是評(píng)估我們的模型的性能,并繪制圖來(lái)查看模型的準(zhǔn)確性和損失指標(biāo)是如何隨時(shí)間變化的。

我們模型的性能指標(biāo)顯示在下面的屏幕截圖中。

代碼與下面顯示的代碼相同。

# 在測(cè)試集上評(píng)估模型的性能
loss, accuracy = model.evaluate(X_test_seq, y_test, verbose = 1)
print("\nAccuracy: {}\nLoss: {}".format(accuracy, loss))

# 畫(huà)出準(zhǔn)確度和損失
sb.set_style('darkgrid')

# 1) 準(zhǔn)確度
plt.plot(history.history['accuracy'], label = 'training', color = '#003399')
plt.legend(shadow = True, loc = 'lower right')
plt.title('Accuracy Plot over Epochs')
plt.show()

# 2) 損失
plt.plot(history.history['loss'], label = 'training loss', color = '#FF0033')
plt.legend(shadow = True, loc = 'upper right')
plt.title('Loss Plot over Epochs')
plt.show()

以下是訓(xùn)練中準(zhǔn)確度的提高

20個(gè)epoch的損失圖

2.預(yù)訓(xùn)練的GloVe詞嵌入

如果你只想運(yùn)行模型,這里有完整的代碼:https://github.com/shraddha-an/nlp/blob/main/pretrained_glove_classification.ipynb

代替訓(xùn)練你自己的嵌入,另一個(gè)選擇是使用預(yù)訓(xùn)練好的詞嵌入,比如GloVe或Word2Vec。在這一部分中,我們將使用在Wikipedia+gigaword5上訓(xùn)練的GloVe詞嵌入;從這里下載:https://nlp./projects/glove/

i) 選擇一個(gè)預(yù)訓(xùn)練的詞嵌入,如果

你的數(shù)據(jù)集是由更“通用”的語(yǔ)言組成的,一般來(lái)說(shuō)你沒(méi)有那么大的數(shù)據(jù)集。

由于這些嵌入已經(jīng)根據(jù)來(lái)自不同來(lái)源的大量單詞進(jìn)行了訓(xùn)練,如果你的數(shù)據(jù)也是通用的,那么預(yù)訓(xùn)練的模型可能會(huì)做得很好。

此外,通過(guò)預(yù)訓(xùn)練的嵌入,你可以節(jié)省時(shí)間和計(jì)算資源。

ii)選擇訓(xùn)練你自己的嵌入,如果

你的數(shù)據(jù)(和項(xiàng)目)是基于一個(gè)利基行業(yè),如醫(yī)藥、金融或任何其他非通用和高度特定的領(lǐng)域。

在這種情況下,一般的詞嵌入表示法可能不適合你,并且一些單詞可能不在詞匯表中。

需要大量的領(lǐng)域數(shù)據(jù)來(lái)確保所學(xué)的詞嵌入能夠正確地表示不同的單詞以及它們之間的語(yǔ)義關(guān)系

此外,它需要大量的計(jì)算資源來(lái)瀏覽你的語(yǔ)料庫(kù)和建立詞嵌入。

最終,是根據(jù)已有的數(shù)據(jù)訓(xùn)練你自己的嵌入,還是使用預(yù)訓(xùn)練好的嵌入,將取決于你的項(xiàng)目。

顯然,你仍然可以試驗(yàn)這兩種模型,并選擇一種精度更高的模型,但上面的教程只是一個(gè)簡(jiǎn)化的教程,可以幫助你做出決策。

過(guò)程

前面的部分已經(jīng)采取了所需的大部分步驟,只需進(jìn)行一些調(diào)整。

我們只需要構(gòu)建一個(gè)單詞及其向量的嵌入矩陣,然后用它來(lái)設(shè)置嵌入層的權(quán)重。

所以,保持預(yù)處理、標(biāo)識(shí)化和填充步驟不變。

一旦我們導(dǎo)入了原始數(shù)據(jù)集并運(yùn)行了前面的文本清理步驟,我們將運(yùn)行下面的代碼來(lái)構(gòu)建嵌入矩陣。

以下決定要嵌入多少個(gè)維度(50、100、200),并將其名稱包含在下面的路徑變量中。

# # 導(dǎo)入嵌入
path = 'Full path to your glove file (with the dimensions)'
embeddings = dict()

with open(path, 'r', encoding = 'utf-8') as f:
    for line in f:
      # 文件中的每一行都是一個(gè)單詞外加50個(gè)數(shù)(表示這個(gè)單詞的向量)
      values = line.split()  
      # 每一行的第一個(gè)元素是一個(gè)單詞,其余的50個(gè)是它的向量
      embeddings[values[0]] = np.array(values[1:], 'float32')  
     
# 設(shè)置一些參數(shù)
vocab_size = 2100
glove_dim = 50
sequence_length = 200
    
# 從語(yǔ)料庫(kù)中的單詞構(gòu)建嵌入矩陣
embedding_matrix = np.zeros((vocab_size, glove_dim))

for word, index in word_index.items():
    if index < vocab_size:
        try:
          # 如果給定單詞的嵌入存在,檢索它并將其映射到單詞。
          embedding_matrix[index] = embeddings[word] 
        except:
          pass  

構(gòu)建和訓(xùn)練嵌入層和神經(jīng)網(wǎng)絡(luò)的代碼應(yīng)該稍作修改,以允許將嵌入矩陣用作權(quán)重。

# 神經(jīng)網(wǎng)絡(luò)
from keras.models import Sequential
from keras.layers import Embedding, Dense, Flatten

model = Sequential()

model.add(Embedding(input_dim = vocab_size,
                    output_dim = glove_dim,
                    input_length = sequence))

model.add(Flatten())
model.add(Dense(units = 3, activation = 'softmax'))
model.compile(optimizer = 'adam', metrics = ['accuracy'], loss = 'categorical_crossentropy')

# 加載我們預(yù)訓(xùn)練好的嵌入矩陣到嵌入層
model.layers[0].set_weights([embedding_matrix])
model.layers[0].trainable = False          # 訓(xùn)練時(shí)權(quán)重不會(huì)被更新

# 訓(xùn)練模型
history = model.fit(X_train_seq, y_train, epochs = 20, batch_size = 512, verbose = 1)

下面是我們預(yù)訓(xùn)練的模型在測(cè)試集中的性能指標(biāo)。

結(jié)論

從兩個(gè)模型的性能指標(biāo)來(lái)看,訓(xùn)練嵌入層似乎更適合這個(gè)數(shù)據(jù)集。

一些原因可能是

1) 關(guān)于堆棧溢出的大多數(shù)問(wèn)題都與IT和編程有關(guān),也就是說(shuō),這是一個(gè)特定領(lǐng)域的場(chǎng)景。

2) 45000個(gè)樣本的大型訓(xùn)練數(shù)據(jù)集為我們的嵌入層提供了一個(gè)很好的學(xué)習(xí)場(chǎng)景。


希望本教程對(duì)你有幫助,謝謝你的閱讀,下一篇文章再見(jiàn)。

原文鏈接:https:///a-guide-to-word-embeddings-8a23817ab60f

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    爱在午夜降临前在线观看| 午夜色午夜视频之日本| 国产日韩精品欧美综合区| 欧美性猛交内射老熟妇| 亚洲性生活一区二区三区| 久久综合亚洲精品蜜桃| 色婷婷丁香激情五月天| 亚洲中文字幕视频在线播放| 国产一区二区三区色噜噜| 国产欧美亚洲精品自拍| 亚洲国产av一二三区| 免费在线观看激情小视频 | 免费黄片视频美女一区| 国产精品99一区二区三区| 综合久综合久综合久久| 冬爱琴音一区二区中文字幕| 成年人黄片大全在线观看| 中文字幕区自拍偷拍区| 日本熟妇熟女久久综合| 香蕉尹人视频在线精品| 亚洲国产性感美女视频| 99久久人妻中文字幕| 久久久免费精品人妻一区二区三区| 激情三级在线观看视频| 日韩一区二区三区久久| 少妇福利视频一区二区| 黑人巨大精品欧美一区二区区 | 国产欧美日韩精品一区二| 日本深夜福利视频在线| 久久香蕉综合网精品视频| 亚洲一区二区三区精选| 国产又粗又猛又爽色噜噜| 亚洲精品一区二区三区日韩| 又色又爽又黄的三级视频| 亚洲中文字幕有码在线观看| 亚洲国产一区精品一区二区三区色| 六月丁香六月综合缴情| 国产精品免费视频久久| 最新国产欧美精品91| 中文字幕欧美视频二区| 日韩欧美一区二区亚洲|