寫(xiě)在前面
最近在處理msmarco數(shù)據(jù)集锚赤,因?yàn)槲业哪P筒恍枰玫絙ert馒胆,elmo這種language model的預(yù)訓(xùn)練表達(dá)狭郑。本來(lái)是想用用fasttext亚茬,但是機(jī)器只有128G內(nèi)存偏陪,連數(shù)據(jù)都放不下去抢呆,所以放棄了,于是決定好好處理分詞了笛谦。
這里比較了三種分詞工具:
- 1 . nltk
- 2 . spacy
- 3 . 正則表達(dá)式
詞表統(tǒng)計(jì)的Passage Retrieval數(shù)據(jù)集的small數(shù)據(jù)集抱虐。一共接近4000w個(gè)pair。
NLTK
from nltk.corpus import stopwords
import string
from nltk.tokenize import word_tokenize
def my_tokenize(title):
""" tokenize word """
title = title.lower()
words = []
for _token in word_tokenize(title):
if _token in StopWords:
continue
words.append(_token)
return words
這里簡(jiǎn)單過(guò)濾了停用詞饥脑,并且過(guò)濾了詞頻小于等于5的詞恳邀。
這里一共有1927856個(gè)詞,還有可以看到這里分的并不好灶轰。各種點(diǎn)把本來(lái)應(yīng)該是兩個(gè)詞的連在了一起谣沸。
再過(guò)濾一下詞頻大于20的。
還有84萬(wàn)多的詞笋颤,太多了乳附。而且分的like shit。
Spacy
后來(lái)聽(tīng)了小伙伴說(shuō)的spacy的分詞不錯(cuò)伴澄,還有有篇論文里面也用了spacy分詞赋除。
于是乎嘗試了一波,直接用的allennlp集成的WordTokenizer非凌,底層是spacy举农。
from allennlp.data.tokenizers import WordTokenizer
from nltk.corpus import stopwords
import string
StopWords = set(stopwords.words('english') + list(string.punctuation))
tokenizer = WordTokenizer()
def my_tokenize(tokenizer, title):
""" tokenize word """
title = title.lower()
words = []
for _token in tokenizer.tokenize(title):
_token = str(_token).strip()
if _token == "":
continue
if _token in StopWords:
continue
words.append(_token)
return words
再看下詞頻大于5的詞。
這里詞表一共有:1579122敞嗡,稍微小了點(diǎn)兒并蝗,不過(guò)總感覺(jué)是和nltk差不多祭犯,亂七八糟的兩個(gè)詞拼在一起的也有。
過(guò)濾了詞頻20以下的之后滚停,還是有69萬(wàn)詞表,不過(guò)看效果真的不太行粥惧。
正則表達(dá)式
后來(lái)又問(wèn)了問(wèn)同學(xué)键畴,本來(lái)想試試有沒(méi)有基于詞表的分詞的,有個(gè)說(shuō)jieba分詞可以突雪。不過(guò)我沒(méi)嘗試起惕。
在msmarco的Leaderboard上面看到了Duet v2的Official Baseline里面有完整的處理和模型的代碼,用的正則分詞咏删,并過(guò)濾了詞惹想,詞表只用了7萬(wàn)多。鏈接:[Official Baseline] Duet V2 (Ensembled)
from nltk.corpus import stopwords
import string
import re
StopWords = set(stopwords.words('english') + list(string.punctuation))
def my_tokenize(title):
regex_multi_space = re.compile('\s+')
regex_drop_char = re.compile('[^a-z0-9\s]+')
words = regex_multi_space.sub(' ', regex_drop_char.sub(' ', title.lower())).strip().split()
tokens = []
for _token in words:
if _token in StopWords:
continue
tokens.append(_token)
return tokens
過(guò)濾了詞頻為5以下的詞之后督函。
詞表大小只有:733205嘀粱,比前面的小了一半多。而且起碼看著像個(gè)樣子辰狡。
目前應(yīng)該是先拿正則的用了锋叨。