寫在前面
最近在處理msmarco數(shù)據(jù)集,因?yàn)槲业哪P筒恍枰玫絙ert,elmo這種language model的預(yù)訓(xùn)練表達(dá)。本來是想用用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
這里簡單過濾了停用詞,并且過濾了詞頻小于等于5的詞。

這里一共有1927856個(gè)詞,還有可以看到這里分的并不好。各種點(diǎn)把本來應(yīng)該是兩個(gè)詞的連在了一起。
再過濾一下詞頻大于20的。

還有84萬多的詞,太多了。而且分的like shit。
Spacy
后來聽了小伙伴說的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)兒,不過總感覺是和nltk差不多,亂七八糟的兩個(gè)詞拼在一起的也有。

過濾了詞頻20以下的之后,還是有69萬詞表,不過看效果真的不太行。
正則表達(dá)式
后來又問了問同學(xué),本來想試試有沒有基于詞表的分詞的,有個(gè)說jieba分詞可以。不過我沒嘗試。
在msmarco的Leaderboard上面看到了Duet v2的Official Baseline里面有完整的處理和模型的代碼,用的正則分詞,并過濾了詞,詞表只用了7萬多。鏈接:[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
過濾了詞頻為5以下的詞之后。

詞表大小只有:733205,比前面的小了一半多。而且起碼看著像個(gè)樣子。

目前應(yīng)該是先拿正則的用了。