在自然語言處理(NLP)任務中,怎么處理數據——即怎么把文字輸入到模型中進行處理? 原創
“ 文本序列化是自然語言處理任務的前置條件,而文本序列化需要經過分詞,構建詞匯表和序列化的幾個步驟”
在神經網絡或者說在機器學習領域中,數據主要以向量的形式存在,表現形式為多維矩陣;但怎么把現實世界中的數據輸入到神經網絡中是機器學習的一個前提。
而現實世界中的數據格式雖然多種多樣,但事實上無非以下幾種主要模態:
- 文字
- 圖片
- 視頻
但我們也知道,計算機只認識數字,而不認識文字和圖片;因此,就需要把這些數據轉換為計算機能夠識別的格式;而在神經網絡模型中就是怎么把這些數據轉換為向量的格式。
簡單來說,就是把現實世界中的數據轉化為用多維矩陣進行表示的過程。圖片是由多個像素點組成,因此天生的就可以用矩陣表示;但文字卻不同,處理起來要復雜得多。至于視頻,就是動起來的多張圖片。
文本處理
在自然語言處理任務中,要想把文本數據輸入到神經網絡中,需要經過大概以下幾個步驟:
- 分詞
- 構建詞匯表
- 文本序列化
但為什么自然語言處理需要經過以下幾個步驟? 下面來介紹一下每個步驟的作用:
分詞
在自然語言體系中,語義是以詞或句子的形態體現的;因此,我們就需要去理解詞或句子的意思;但眾所周知的是,以我們漢語為例常用的詞和字就幾千個;而我們生活中絕大部分的語義都是由重復的字和詞組成的。
因此,從效率的角度來講,我們不可能把每個句子的語義都記下來;我們需要的是找到其中常用的字和詞,然后通過類似排列組合的方式組合成一個個句子。
所以,自然語言處理的第一步就是分詞;也就是說通過某種方式把句子中相同的字或詞挑出來,組成一個字詞列表。而常用的分詞技術根據不同的語言又有不同的實現方式;比如說在英語體系中,很多時候每個單詞就表示單獨的意思;因此最簡單的分詞方式就是把每個不同的單詞都找出來。
但在漢語言中,由于存在多音字,成語等具有復雜語言的形態;因此,漢語分詞就不能使用找不同字的形式。
因此,分詞的難點是怎么對文本數據進行拆分,但又不會影響到詞語本身對意思。
詞匯表
理解了什么是分詞,以及為什么要分詞,那么再理解詞匯表就很簡單了;對句子進行分詞之后,就獲取到了一個字和詞的列表;因此就可以根據這個列表來構建詞匯表,變成讓計算機可以處理的數字格式。
學過計算機原理的應該都知道,計算機無法直接處理文字,因此文字在計算機中是通過編碼的方式來實現的;比如說大名鼎鼎的ASCII碼表,就是用八位二進制表示的。
而ASCII碼表本質上就是一個字典結構,即使用K-V的形式來表示字符;需要計算機處理時就使用二進制表示,需要現實給人看時就使用字符表示;而詞匯表就是類似ASCII碼表的形式,把字或詞作為K,把數字作為V。
這樣一個數字就可以代表一個字或詞;這樣就可以讓計算機處理。
在詞匯表中有兩個比較特殊的詞匯,那就是UNK和PAD;我們知道常用的漢字只有幾千個,但實際上的漢字有上萬個;因此,我們根據文本數據的內容,可能并不能獲取到所有的漢字;因此遇到“沒見過”的漢字該怎么辦呢,這時就使用UNK來表示。
而在矩陣計算中,需要的是相同的矩陣形式;比如說需要5*5的固定矩陣;但在自然語言中,每個句子的長度都不一樣;短的可能就一兩個字,長的可能有幾十個字;這時變換的矩陣維度就不在相同。
dict = { "UNK_TAG": 0, "PAD_TAG": 1}
因此,就可以使用PAD對文字比較少的句子進行補充;而對文字比較長的句子進行截取。
文本序列化
在經過分詞和構建詞匯表之后,就可以對文本進行序列化;在自然語言處理任務中,文本需要轉換為編碼的數字進行表示;也就是把文字變成數字表示。
dict_1 = { "UNK_TAG": 0, "PAD_TAG": 1}
dict_2 = { 0: "UNK_TAG", 1: "PAD_TAG"}
所以就有了一個從文字變成數字和從數字變成文字的過程;本質上其實就是在詞匯表中,根據文本獲取其編碼的數字,以及根據編碼的數字獲取文字。
文本序列化最重要的一步,就是把數字表示的句子轉換成向量表示,也就是多維矩陣;而這就需要通過one-hot或者word embedding的方式來進行序列化。
但是在使用word embedding之前,需要把句子的數字列表轉換為tensor格式。
# 將句子列表轉換為tensor
sentences_tensor = torch.tensor(sentences, dtype=torch.long)
# 定義 Embedding 層
embedding = nn.Embedding(vocab_size, embedding_dim)
# 通過 Embedding 層
embedded_sentences = embedding(sentences_tensor)
本文轉載自公眾號AI探索時代 作者:DFires
