MSMarco Ranking數(shù)據(jù)集三種分詞工具比較

寫在前面

最近在處理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的詞。

nltk詞頻大于5

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

再過濾一下詞頻大于20的。


nltk詞頻大于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的詞。


spacy詞頻大于5

這里詞表一共有:1579122,稍微小了點(diǎn)兒,不過總感覺是和nltk差不多,亂七八糟的兩個(gè)詞拼在一起的也有。

spacy詞頻大于20

過濾了詞頻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以下的詞之后。


正則詞頻大于5

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

正則詞頻大于20

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容