一文搞懂Tokenization!
語(yǔ)言模型是對(duì)文本進(jìn)行推理,文本通常是字符串形式,但是模型的輸入只能是數(shù)字,因此需要將文本轉(zhuǎn)換成數(shù)字形式。
Tokenization是NLP的基本任務(wù),按照特定需求能把一段連續(xù)的文本序列(如句子、段落等)切分為一個(gè)字符串序列(如單詞、短語(yǔ)、字符、標(biāo)點(diǎn)等多個(gè)單元),其中的元素稱(chēng)為token或詞語(yǔ)。
具體流程如下圖所示,首先將文本句子切分成一個(gè)個(gè)單元,然后將子單元數(shù)值化(映射為向量),再將這些向量輸入到模型進(jìn)行編碼,最后輸出到下游任務(wù)進(jìn)一步得到最終的結(jié)果。
文本切分
按照文本切分的粒度可以將Tokenization分為詞粒度Tokenization、字符粒度Tokenization、subword粒度Tokenization三類(lèi)。
1.詞粒度Tokenization
詞粒度Tokenization是最直觀的分詞方式,即是指將文本按照詞匯words進(jìn)行切分。例如:
The quick brown fox jumps over the lazy dog.
詞粒度Tokenized結(jié)果:
['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog', '.']
在這個(gè)例子中,文本被切分為一個(gè)個(gè)獨(dú)立的單詞,每個(gè)單詞作為一個(gè)token,標(biāo)點(diǎn)符號(hào)'.'也被視為獨(dú)立的token。
如若是中文文本,則通常是按照詞典收錄的標(biāo)準(zhǔn)詞匯或是通過(guò)分詞算法識(shí)別出的短語(yǔ)、成語(yǔ)、專(zhuān)有名詞等進(jìn)行切分。例如:
我喜歡吃蘋(píng)果。
詞粒度Tokenized結(jié)果:
['我', '喜歡', '吃', '蘋(píng)果', '。']
這段中文文本被切分成五個(gè)詞語(yǔ):“我”、“喜歡”、“吃”、“蘋(píng)果”和句號(hào)“?!?,每個(gè)詞語(yǔ)作為一個(gè)token。
2.字符粒度Tokenization
字符粒度Tokenization將文本分割成最小的字符單元,即每個(gè)字符被視為一個(gè)單獨(dú)的token。例如:
Hello, world!
字符粒度Tokenized結(jié)果:
['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']
字符粒度Tokenization在中文中是將文本按照每個(gè)獨(dú)立的漢字進(jìn)行切分。
我喜歡吃蘋(píng)果。
字符粒度Tokenized結(jié)果:
['我', '喜', '歡', '吃', '蘋(píng)', '果', '。']
3.subword粒度Tokenization
subword粒度Tokenization介于詞粒度和字符粒度之間,它將文本分割成介于單詞和字符之間的子詞(subwords)作為token。常見(jiàn)的subword Tokenization方法包括Byte Pair Encoding (BPE)、WordPiece等。這些方法通過(guò)統(tǒng)計(jì)文本數(shù)據(jù)中的子串頻率,自動(dòng)生成一種分詞詞典,能夠有效應(yīng)對(duì)未登錄詞(OOV)問(wèn)題,同時(shí)保持一定的語(yǔ)義完整性。
helloworld
假設(shè)經(jīng)過(guò)BPE算法訓(xùn)練后,生成的子詞詞典包含以下條目:
h, e, l, o, w, r, d, hel, low, wor, orld
子詞粒度Tokenized結(jié)果:
['hel', 'low', 'orld']
這里,“helloworld”被切分為三個(gè)子詞“hel”,“l(fā)ow”,“orld”,這些都是詞典中出現(xiàn)過(guò)的高頻子串組合。這種切分方式既能處理未知詞匯(如“helloworld”并非標(biāo)準(zhǔn)英語(yǔ)單詞),又保留了一定的語(yǔ)義信息(子詞組合起來(lái)能還原原始單詞)。
在中文中,subword粒度Tokenization同樣是將文本分割成介于漢字和詞語(yǔ)之間的子詞作為token。例如:
我喜歡吃蘋(píng)果
假設(shè)經(jīng)過(guò)BPE算法訓(xùn)練后,生成的子詞詞典包含以下條目:
我, 喜, 歡, 吃, 蘋(píng), 果, 我喜歡, 吃蘋(píng)果
子詞粒度Tokenized結(jié)果:
['我', '喜歡', '吃', '蘋(píng)果']
在這個(gè)例子中,“我喜歡吃蘋(píng)果”被切分為四個(gè)子詞“我”、“喜歡”、“吃”和“蘋(píng)果”,這些子詞均在詞典中出現(xiàn)。雖然沒(méi)有像英文子詞那樣將漢字進(jìn)一步組合,但子詞Tokenization方法在生成詞典時(shí)已經(jīng)考慮了高頻詞匯組合,如“我喜歡”和“吃蘋(píng)果”。這種切分方式在處理未知詞匯的同時(shí),也保持了詞語(yǔ)級(jí)別的語(yǔ)義信息。
索引化
假設(shè)已有創(chuàng)建好的語(yǔ)料庫(kù)或詞匯表如下。
vocabulary = {
'我': 0,
'喜歡': 1,
'吃': 2,
'蘋(píng)果': 3,
'。': 4
}
則可以查找序列中每個(gè)token在詞匯表中的索引。
indexed_tokens = [vocabulary[token] for token in token_sequence]
print(indexed_tokens)
輸出:[0, 1, 2, 3, 4]。