【NLP】機(jī)器如何認(rèn)識文本 ?NLP中的Tokenization方法總結(jié)
Tokenization
關(guān)于Tokenization,網(wǎng)上有翻譯成"分詞"的,但是我覺得不是很準(zhǔn)確,容易引起誤導(dǎo)。一直找不到合適的中文來恰當(dāng)表達(dá),所以下文采用原汁原味的英文表達(dá)。
在正式進(jìn)入主題之前,先來看看NLP任務(wù)中最基礎(chǔ)也最先需要進(jìn)行的一步:tokenization。簡單說,該操作的目地是將輸入文本分割成一個個token,和詞典配合以讓機(jī)器認(rèn)識文本。Tokenization的難點(diǎn)在于如何獲得理想的切分,使文本中所有的token都具有正確的表義,并且不會存在遺漏(OOV問題)。
接下來,我們簡單梳理下目前主流的tokenization方法,及其優(yōu)缺點(diǎn)。
詞粒度
詞粒度的切分就跟人類平時理解文本原理一樣,常常用一些工具來完成,例如英文的NLTK、SpaCy,中文的jieba、LTP等。舉個栗子:
英文:
live in New York ------> live / in / New York /
中文:
在紐約生活 -----> 在 / 紐約 / 生活
詞粒度的切分能夠非常好地保留完整語義信息,但是如果出現(xiàn)拼寫錯誤、英文中的縮寫等情況,魯棒性一般。另一方面,詞切分會產(chǎn)生非常巨大的詞表,而且這都不能確保不會出現(xiàn)out of vocabulary問題。
字粒度
字粒度最早應(yīng)該是2015年Karpathy[1]提出,簡單說英文就是以字母為單位(對于大小寫不敏感的任務(wù),甚至可以先轉(zhuǎn)小寫再切分),中文就是以字為單位,舉個栗子,
英文:
live in New York -----> l / i / v /e / i / n / N / e / w / Y / o / r /k
中文:
在紐約生活 -----> 在 / 紐 / 約 / 生 / 活
可以看出,字粒度的切分很好地解決了詞粒度的缺陷,魯棒性增強(qiáng)、詞表大大減小。但另一方面,也會帶來一些麻煩:
「毫無意義」:一個字母或一個單字本質(zhì)上并沒有任何語義意義; 「增加輸入計(jì)算壓力」:減小詞表的代價就是輸入長度大大增加,從而輸入計(jì)算變得更耗時耗力;
如果詞粒度不理想,而且字粒度似乎也有自己的問題,那么還有什么替代方法呢?
Here comes subword tokenization!
Subword粒度
我們理想中的tokenization需要滿足:
它能夠在不需要無限詞匯表的情況下處理缺失的標(biāo)記,即通過有限的已知單詞列表來處理無限的潛在詞匯; 此外,我們不希望將所有內(nèi)容分解為單個字符的額外復(fù)雜性,因?yàn)樽址墑e可能會丟失單詞級別的一些含義和語義細(xì)節(jié)。
為此,我們需要考慮如何重新利用『小』單詞來創(chuàng)建『大』單詞。subword tokenization不轉(zhuǎn)換最常見的單詞,而是將稀有單詞分解成有意義的子詞單元。如果unfriendly被標(biāo)記為一個稀有詞,它將被分解為un-friendly-ly,這些單位都是有意義的單位,un的意思是相反的,friend是一個名詞,ly則變成副詞。這里的挑戰(zhàn)是如何進(jìn)行細(xì)分,我們?nèi)绾潍@得un-friend-ly而不是unfr-ien-dly。
NLP最火的網(wǎng)紅 Transformer 和 BERT 就是Subword的帶鹽人,來看個它們做tokenization的栗子,
I have a new GPU ?----> [’i’, ’have’, ’a’, ’new’, ’gp’, ’##u’, ’.’]
subword粒度切分算法又有以下幾種:
BPE WordPiece ULM
BPE
BPE全稱Byte Pair Encoding,字節(jié)對編碼,首先在Neural Machine Translation of Rare Words with Subword Units[2] 中提出。BPE 迭代地合并最頻繁出現(xiàn)的字符或字符序列,具體步驟:
準(zhǔn)備足夠大的語料庫 定義好所需要的詞表大小 將單詞拆分為字符序列,在末尾添加后綴 w>,并統(tǒng)計(jì)單詞頻率。本階段的subword的粒度是字符。例如,“ low”的頻率為5,那么我們將其改寫為l o w w>:5統(tǒng)計(jì)每一個連續(xù)字節(jié)對的出現(xiàn)頻率,選擇最高頻者合并成新的subword 重復(fù)第4步直到達(dá)到第2步設(shè)定的subword詞表大小或下一個最高頻的字節(jié)對出現(xiàn)頻率為1
舉個栗子,我們輸入,
{'l?o?w?':?5,?'l?o?w?e?r?':?2,?'n?e?w?e?s?t?':?6,?'w?i?d?e?s?t?':?3}
第一輪迭代,統(tǒng)計(jì)連續(xù)的每兩個字節(jié)出現(xiàn)的次數(shù),發(fā)現(xiàn) e 和s 共現(xiàn)次數(shù)最大,合并成es,有,
{'l?o?w?':?5,?'l?o?w?e?r?':?2,?'n?e?w?es?t?':?6,?'w?i?d?es?t?':?3}
第二輪迭代,統(tǒng)計(jì)連續(xù)的每兩個字節(jié)出現(xiàn)的次數(shù),發(fā)現(xiàn) es 和t 共現(xiàn)次數(shù)最大,合并成est,有,
{'l?o?w?':?5,?'l?o?w?e?r?':?2,?'n?e?w?est?':?6,?'w?i?d?est?':?3}
依次繼續(xù)迭代直到達(dá)到預(yù)設(shè)的subword詞表大小或下一個最高頻的字節(jié)對出現(xiàn)頻率為1。
以上是BPE的整體流程,關(guān)于BPE更多細(xì)節(jié)可以參考:Byte Pair Encoding[3]
Unigram LM
Unigram語言建模首先在Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates[4]中提出,基于所有子詞出現(xiàn)是獨(dú)立的假設(shè),因此子詞序列由子詞出現(xiàn)概率的乘積生成。算法步驟如下:
準(zhǔn)備足夠大的語料庫 定義好所需要的詞表大小 給定詞序列優(yōu)化下一個詞出現(xiàn)的概率 計(jì)算每個subword的損失 基于損失對subword排序并保留前X%。為了避免OOV,保留字符級的單元 重復(fù)第3至第5步直到達(dá)到第2步設(shè)定的subword詞表大小或第5步的結(jié)果不再變化
unigram-LM模型比BPE更靈活,因?yàn)樗诟怕蔐M,并且可以輸出具有概率的多個分段。它不是從一組基本符號開始,更具某些規(guī)則進(jìn)行合并,如BPE或WordPiece,而是從一個龐大的詞匯量開始,例如所有預(yù)處理的單詞和最常見的子字符串,并逐步減少。
WordPiece
WordPiece首先在 JAPANESE AND KOREAN VOICE SEARCH[5] 中提出,最初用于解決日語和韓語語音問題。它在許多方面類似于BPE,只是它基于可能性而不是下一個最高頻率對來形成一個新的子詞。算法步驟如下:
準(zhǔn)備足夠大的語料庫 定義好所需要的詞表大小 將單詞拆分成字符序列 基于第3步數(shù)據(jù)訓(xùn)練語言模型 從所有可能的subword單元中選擇加入語言模型后能最大程度地增加訓(xùn)練數(shù)據(jù)概率的單元作為新的單元 重復(fù)第5步直到達(dá)到第2步設(shè)定的subword詞表大小或概率增量低于某一閾值
WordPiece更像是BPE和Unigram LM的結(jié)合。
小結(jié)
簡單幾句話總結(jié)下Subword的三種算法:
BPE:只需在每次迭代中使用「出現(xiàn)頻率」來確定最佳匹配,直到達(dá)到預(yù)定義的詞匯表大小; Unigram:使用概率模型訓(xùn)練LM,移除提高整體可能性最小的token;然后迭代進(jìn)行,直到達(dá)到預(yù)定義的詞匯表大小; WordPiece:結(jié)合BPE與Unigram,使用「出現(xiàn)頻率」來確定潛在匹配,但根據(jù)合并token的概率做出最終決定.
Sentencepiece
到目前為止,可以發(fā)現(xiàn)subword結(jié)合了詞粒度和字粒度方法的優(yōu)點(diǎn),并避免了其不足。但是,仔細(xì)想會發(fā)現(xiàn)上述三種subword算法都存在一些問題:
「都需要提前切分(pretokenization)」 :這對于某些語言來說,可能是不合理的,因?yàn)椴豢梢杂每崭駚矸指魡卧~;
「無法逆轉(zhuǎn)」:原始輸入和切分后序列是不可逆的。舉個栗子,下面兩者的結(jié)果是相等的,即空格的信息經(jīng)過該操作被丟失
Tokenize(“World.”) == Tokenize(“World .”)
「不是End-to-End」:使用起來并沒有那么方便
ok,here comes SentencePiece!來看看是怎么解決上述問題的
SentencePiece首先將所有輸入轉(zhuǎn)換為unicode字符。這意味著它不必?fù)?dān)心不同的語言、字符或符號,可以以相同的方式處理所有輸入; 空白也被當(dāng)作普通符號來處理。Sentencepiece顯式地將空白作為基本標(biāo)記來處理,用一個元符號 “▁”( U+2581 )轉(zhuǎn)義空白,這樣就可以實(shí)現(xiàn)簡單地decoding Sentencepiece可以直接從raw text進(jìn)行訓(xùn)練,并且官方稱非???!
快結(jié)束了,我想說一下,這真的不是Sentencepiece的軟文(谷歌,打錢?。?/p>
SentencePiece集成了兩種subword算法,BPE和UniLM, WordPiece 則是谷歌內(nèi)部的子詞包,沒對外公開。感興趣的可以去官方開源代碼庫玩玩:google/sentencepiece[6]
放個栗子:
>>>?import?sentencepiece?as?spm
>>>?s?=?spm.SentencePieceProcessor(model_file='spm.model')
>>>?for?n?in?range(5):
...?????s.encode('New?York',?out_type=str,?enable_sampling=True,?alpha=0.1,?nbest=-1)
...
['▁',?'N',?'e',?'w',?'▁York']
['▁',?'New',?'▁York']
['▁',?'New',?'▁Y',?'o',?'r',?'k']
['▁',?'New',?'▁York']
['▁',?'New',?'▁York']
最后,如果想嘗試WordPiece,大家也可以試試HuggingFace的Tokenization庫[7]
from?tokenizers?import?Tokenizer
from?tokenizers.models?import?BPE
from?tokenizers.pre_tokenizers?import?Whitespace
from?tokenizers.trainers?import?BpeTrainer
tokenizer?=?Tokenizer(BPE())
tokenizer.pre_tokenizer?=?Whitespace()
trainer?=?BpeTrainer(special_tokens=["[UNK]",?"[CLS]",?"[SEP]",?"[PAD]",?"[MASK]"])
tokenizer.train(trainer,?["wiki.train.raw",?"wiki.valid.raw",?"wiki.test.raw"])
output?=?tokenizer.encode("Hello,?y'all!?How?are?you????")
print(output.tokens)
#?["Hello",?",",?"y",?"'",?"all",?"!",?"How",?"are",?"you",?"[UNK]",?"?"]
本文參考資料
2015年Karpathy: https://github.com/karpathy/char-rnn
[2]Neural Machine Translation of Rare Words with Subword Units: https://arxiv.org/abs/1508.07909
[3]Byte Pair Encoding: https://leimao.github.io/blog/Byte-Pair-Encoding/
[4]Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates: https://arxiv.org/abs/1804.10959
[5]JAPANESE AND KOREAN VOICE SEARCH: https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37842.pdf
[6]google/sentencepiece: https://github.com/google/sentencepiece
[7]HuggingFace的Tokenization庫: https://github.com/huggingface/tokenizers
-?END?-
往期精彩回顧
獲取本站知識星球優(yōu)惠券,復(fù)制鏈接直接打開:
https://t.zsxq.com/qFiUFMV
本站qq群704220115。
加入微信群請掃碼:
