深度學習技術已廣泛應用於自然語言處理領域,其中文字分類別是重要的應用之一。本文將以推文情感分析為例,示範如何利用 PyTorch 和 Torchtext 這個方便的函式庫來構建文字分類別模型。我們會逐步介紹資料預處理、詞嵌入的應用、模型的建立與訓練,以及如何使用訓練好的模型進行推文情感分類別。此外,我們還會探討一些常見的資料增強技術,例如隨機插入、刪除、交換和回譯,以及如何在 PyTorch 中應用這些技術來提升模型的效能。透過這些技術,我們可以有效地擴充訓練資料,提升模型的泛化能力,使其在面對未見資料時表現更佳。
使用 PyTorch 進行文字分類別:詞嵌入與 Torchtext
在深度學習的自然語言處理(NLP)領域中,文字分類別是一項重要的任務。PyTorch 提供了一個強大的函式庫 torchtext,用於處理文字資料的預處理和載入。在本章中,我們將探討如何使用 PyTorch 和 torchtext 來建立一個情感分析模型。
詞嵌入(Word Embeddings)
詞嵌入是一種將單詞表示為向量空間中的向量的方法。這種表示方法能夠捕捉單詞之間的語義關係。一個著名的詞嵌入例子是 word2vec,它由 Google 在 2013 年發布。Word2vec 使用淺層神經網路訓練詞向量,從而揭示了詞向量似乎捕捉到了單詞背後的概念。
在 PyTorch 中,使用詞嵌入非常簡單:
embed = nn.Embedding(vocab_size, dimension_size)
這將建立一個大小為 vocab_size x dimension_size 的張量,每個單詞在詞彙表中對應一個 dimension_size 維的向量。
內容解密:
nn.Embedding是 PyTorch 中的一個模組,用於建立詞嵌入層。vocab_size是詞彙表的大小,即資料集中不同單詞的數量。dimension_size是每個單詞向量的維度。
Torchtext 簡介
Torchtext 是 PyTorch 的官方函式庫,用於處理文字資料的預處理和載入。雖然它不如 torchvision 那樣成熟,但仍然是一個強大的工具,可以幫助我們處理文字資料。
安裝 torchtext 可以使用 pip 或 conda:
pip install torchtext
或
conda install -c derickl torchtext
我們還需要安裝 spaCy(一款 NLP 函式庫)和 pandas(用於資料處理)。
取得資料:推文情感分析
在本文中,我們將建立一個情感分析模型,使用 Sentiment140 資料集。該資料集包含來自 Twitter 的推文,每條推文都被標記為 0(負面)、2(中立)或 4(正面)。
下載資料集並解壓縮後,我們可以使用 pandas 載入資料:
import pandas as pd
tweetsDF = pd.read_csv("training.1600000.processed.noemoticon.csv", engine="python", header=None)
內容解密:
pd.read_csv用於載入 CSV 檔案。engine="python"指定使用 Python 引擎解析 CSV 檔案,因為預設的 C 引擎可能無法正確處理某些 Unicode 字元。
資料預處理
檢視資料的前五行:
>>> tweetsDF.head(5)
我們發現資料集沒有標題行,但透過檢視網站和憑直覺,我們可以確定最後一列是推文文字,第一列是標籤。
內容解密:
tweetsDF.head(5)用於顯示資料的前五行。- 我們需要根據資料的結構進行相應的處理。
定義欄位(Fields)
Torchtext 提供了一種直接的方法來生成資料集:定義欄位(Fields)。欄位類別有多個引數,可以用於控制資料的預處理。
內容解密:
- 欄位(Fields)用於指定如何處理資料中的不同欄位。
Field類別有多個引數,例如sequential、use_vocab和init_token,可以用於控制資料的預處理。
使用 Torchtext 處理文字資料
在進行文字分類別任務時,資料的預處理是非常重要的一步。Torchtext 是 PyTorch 中用於處理文字資料的函式庫,提供了一系列工具來簡化資料的載入、預處理和批次化。
定義欄位
首先,我們需要定義資料中的欄位。Torchtext 中的 Field 物件用於指定如何處理資料中的每個欄位。
from torchtext import data
LABEL = data.LabelField()
TWEET = data.Field(tokenize='spacy', lower=True)
在這裡,我們定義了兩個欄位:LABEL 和 TWEET。LABEL 是一個 LabelField,用於表示分類別標籤;TWEET 是一個 Field,用於表示文字資料,並指定使用 spaCy 進行分詞和轉換為小寫。
內容解密:
data.LabelField():建立一個標籤欄位,用於分類別任務。data.Field(tokenize='spacy', lower=True):建立一個文字欄位,使用 spaCy 分詞並轉為小寫。
定義資料集
接下來,我們需要將欄位對映到 CSV 檔案中的列。
fields = [('score', None), ('id', None), ('date', None), ('query', None),
('name', None), ('tweet', TWEET), ('category', None), ('label', LABEL)]
這裡,我們定義了一個列表 fields,其中每個元素都是一個 tuple,包含欄位名稱和對應的 Field 物件。如果某個欄位不需要被處理,則對應的 Field 物件設為 None。
內容解密:
- 將 CSV 中的欄位對映到對應的
Field物件。 - 將不需要處理的欄位設為
None。
載入資料集
使用 TabularDataset 載入 CSV 檔案。
twitterDataset = torchtext.data.TabularDataset(
path="training-processed.csv",
format="CSV",
fields=fields,
skip_header=False)
內容解密:
path:指定 CSV 檔案的路徑。format:指設定檔案格式為 CSV。fields:指定欄位對映。skip_header:指定是否跳過檔案頭。
分割資料集
將資料集分割為訓練集、測試集和驗證集。
(train, test, valid) = twitterDataset.split(split_ratio=[0.8, 0.1, 0.1])
內容解密:
- 使用
split方法分割資料集。 split_ratio:指定分割比例。
建立詞彙表
建立詞彙表並限制詞彙表大小。
vocab_size = 20000
TWEET.build_vocab(train, max_size=vocab_size)
內容解密:
build_vocab:根據訓練集建立詞彙表。max_size:限制詞彙表大小。
建立資料迭代器
建立資料迭代器用於訓練模型。
train_iterator, valid_iterator, test_iterator = data.BucketIterator.splits(
(train, valid, test),
batch_size=32,
device=device)
內容解密:
BucketIterator.splits:建立多個資料迭代器。batch_size:指定批次大小。device:指定運算裝置。
深度學習在文字分類別中的應用:以推文情感分析為例
在深度學習的領域中,文字分類別是一項重要的任務,尤其是在社交媒體監控、市場研究和客戶服務等領域。本篇文章將介紹如何使用PyTorch和torchtext函式庫來建立一個簡單的文字分類別模型,以對推文進行情感分析。
資料處理
首先,我們需要處理資料。我們使用torchtext函式庫中的TabularDataset類別來載入和預處理資料。
import torch
from torchtext import data
from torchtext import datasets
# 設定裝置(GPU或CPU)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# 定義資料欄位
fields = [('tweet', TWEET), ('label', LABEL)]
# 載入資料集
twitterDataset = data.TabularDataset(
path='path_to_your_dataset.csv',
format='CSV',
fields=fields,
skip_header=False
)
# 分割資料集為訓練集、測試集和驗證集
(train, test, valid) = twitterDataset.split(split_ratio=[0.8, 0.1, 0.1])
# 建立詞彙表
vocab_size = 20002
TWEET.build_vocab(train, max_size=vocab_size)
# 建立迭代器
train_iterator, valid_iterator, test_iterator = data.BucketIterator.splits(
(train, valid, test),
batch_size=32,
device=device
)
內容解密:
- 資料載入與分割:使用
TabularDataset載入CSV格式的資料集,並將其分割為訓練集、測試集和驗證集。 - 詞彙表建立:使用
build_vocab方法建立詞彙表,將文字資料轉換為數值表示。 - 迭代器建立:使用
BucketIterator建立迭代器,以便於批次處理資料。
建立模型
接下來,我們需要建立一個簡單的文字分類別模型。我們使用PyTorch中的nn.Module類別來定義模型。
import torch.nn as nn
class OurFirstLSTM(nn.Module):
def __init__(self, hidden_size, embedding_dim, vocab_size):
super(OurFirstLSTM, self).__init__()
self.embedding = nn.Embedding(vocab_size, embedding_dim)
self.encoder = nn.LSTM(input_size=embedding_dim, hidden_size=hidden_size, num_layers=1)
self.predictor = nn.Linear(hidden_size, 2)
def forward(self, seq):
output, (hidden, _) = self.encoder(self.embedding(seq))
preds = self.predictor(hidden.squeeze(0))
return preds
model = OurFirstLSTM(100, 300, 20002)
model.to(device)
內容解密:
- 嵌入層:使用
nn.Embedding將輸入的文字資料轉換為向量表示。 - LSTM層:使用
nn.LSTM對向量表示進行序列建模。 - 預測層:使用
nn.Linear將LSTM的輸出轉換為預測結果。
訓練模型
import torch.optim as optim
# 定義最佳化器和損失函式
optimizer = optim.Adam(model.parameters(), lr=2e-2)
criterion = nn.CrossEntropyLoss()
def train(epochs, model, optimizer, criterion, train_iterator, valid_iterator):
for epoch in range(1, epochs + 1):
training_loss = 0.0
valid_loss = 0.0
model.train()
for batch_idx, batch in enumerate(train_iterator):
optimizer.zero_grad()
predict = model(batch.tweet)
loss = criterion(predict, batch.label)
loss.backward()
optimizer.step()
training_loss += loss.data.item() * batch.tweet.size(0)
training_loss /= len(train_iterator)
model.eval()
for batch_idx, batch in enumerate(valid_iterator):
predict = model(batch.tweet)
loss = criterion(predict, batch.label)
valid_loss += loss.data.item() * batch.tweet.size(0)
valid_loss /= len(valid_iterator)
print('Epoch: {}, Training Loss: {:.2f}, Validation Loss: {:.2f}'.format(epoch, training_loss, valid_loss))
內容解密:
- 最佳化器和損失函式定義:使用Adam最佳化器和交叉熵損失函式。
- 訓練迴圈:在訓練集中進行前向傳播、計算損失、反向傳播和引數更新。
- 驗證集評估:在驗證集中評估模型的效能。
分類別推文
def classify_tweet(tweet):
categories = {0: "Negative", 1: "Positive"}
processed = TWEET.process([TWEET.preprocess(tweet)])
return categories[model(processed).argmax().item()]
內容解密:
- 推文預處理:使用
preprocess方法對推文進行預處理。 - 模型預測:使用訓練好的模型對預處理後的推文進行預測。
- 類別對映:將預測結果對映到對應的類別標籤。
資料增強技術在文字分類別中的應用
在處理文字分類別任務時,資料增強(Data Augmentation)是一種常見且有效的技術,能夠提升模型的效能和泛化能力。本篇文章將探討幾種常見的文字資料增強技術,包括隨機插入、隨機刪除、隨機交換和回譯等方法。
隨機插入
隨機插入技術會檢視一個句子,然後隨機插入現有非停止詞(non-stop-words)的同義詞到句子中 n 次。假設我們有辦法取得一個詞的同義詞和消除停止詞(如 “and”、“it”、“the” 等),以下是一個簡單的實作:
def random_insertion(sentence, n):
words = remove_stopwords(sentence)
for _ in range(n):
new_synonym = get_synonyms(random.choice(words))
sentence.insert(randrange(len(sentence)+1), new_synonym)
return sentence
內容解密:
remove_stopwords(sentence):移除句子中的停止詞,傳回一個詞列表。get_synonyms(random.choice(words)):從現有的詞中隨機選擇一個,並取得其同義詞。sentence.insert(randrange(len(sentence)+1), new_synonym):將取得的同義詞隨機插入到句子中的某個位置。
舉例來說,原句 “The cat sat on the mat” 可能會變成 “The cat mat sat on feline the mat”,其中 “feline” 是 “cat” 的同義詞。
隨機刪除
隨機刪除技術根據給定的機率引數 p,遍歷句子並決定是否刪除某個詞。
def random_deletion(words, p=0.5):
if len(words) == 1:
return words
remaining = list(filter(lambda x: random.uniform(0,1) > p, words))
if len(remaining) == 0:
return [random.choice(words)]
else:
return remaining
內容解密:
- 如果句子中只有一個詞,則直接傳回該詞。
filter(lambda x: random.uniform(0,1) > p, words):根據機率 p 過濾詞,保留那些隨機數大於 p 的詞。- 如果過濾後沒有詞剩下,則隨機傳回原句子中的一個詞。
隨機交換
隨機交換技術會對句子中的詞進行 n 次隨機交換。
def random_swap(sentence, n=5):
length = range(len(sentence))
for _ in range(n):
idx1, idx2 = random.sample(length, 2)
sentence[idx1], sentence[idx2] = sentence[idx2], sentence[idx1]
return sentence
內容解密:
random.sample(length, 2):從句子長度範圍內隨機選取兩個不同的索引。sentence[idx1], sentence[idx2] = sentence[idx2], sentence[idx1]:交換這兩個索引對應的詞。
回譯
回譯(Back Translation)是另一種流行的資料增強方法。它涉及將句子從目標語言翻譯成一種或多種其他語言,然後再翻譯回原來的語言。可以使用 Python 函式庫 googletrans 來實作。
import googletrans
from googletrans import Translator
translator = Translator()
sentences = ['The cat sat on the mat']
translation_fr = translator.translate(sentences, dest='fr')
fr_text = [t.text for t in translation_fr]
translation_en = translator.translate(fr_text, dest='en')
en_text = [t.text for t in translation_en]
print(en_text)
內容解密:
- 將句子從英文翻譯成法文。
- 再將法文翻譯回英文,從而得到增強的句子。
為了進一步增強,可以隨機選擇一種語言進行翻譯:
available_langs = list(googletrans.LANGUAGES.keys())
tr_lang = random.choice(available_langs)
translations = translator.translate(sentences, dest=tr_lang)
t_text = [t.text for t in translations]
translations_en_random = translator.translate(t_text, src=tr_lang, dest='en')
en_text = [t.text for t in translations_en_random]
內容解密:
- 隨機選擇一種語言進行翻譯。
- 將句子翻譯成該語言,然後再翻譯回英文。
資料增強與 torchtext
目前為止討論的資料增強技術並未直接涉及 torchtext。由於 torchtext 不提供像 torchvision 或 torchaudio 那樣的轉換管道,因此建議在 PyTorch 外部進行資料增強,然後將增強的資料輸入模型。