BrambleXu / knowledge-graph-learning

A curated list of awesome knowledge graph tutorials, projects and communities.
MIT License
735 stars 120 forks source link

EMNLP-2018-SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing #289

Open BrambleXu opened 4 years ago

BrambleXu commented 4 years ago

Summary:

直接从句子中学习分词方式的手法。提出的背景在于像英语这样的语言有空格可以作为分词的依据,但中文,日语,韩语等语言则没有空格。针对这些语言,为了做到语言独立性,提出了SentencePiece的方法。主要实现了 byte-pairencoding (BPE) (Sennrich et al., 2016) 和 unigram language model (Kudo, 2018)两种subword segmentation算法。

Resource:

Paper information:

Notes:

日语里的拉丁字母有全角和半角之分,这里使用Unicode NFKC normalization来进行处理。

3.5 Self-contained models

预处理操作上的不同,会影响最终的模型效果。比如NFKC normalization may yield different results depending on the Unicode version. 为了减少影响,sentencepiece的model里不仅包含了vocabulary和segementation parameters,还包含了用于charecter normalization的状态转换器。也就是说,sentencepiece的结果只取决于model file。

3 subword algorithms help to improve your NLP model performance: 这篇文章做了一个很好的总结。

而SentencePiece则是包含了BPE和 Unigram Language Model两种分词方法的工具包。其中默认的分词方法是 Unigram Language Model。

用法:

pip install sentencepiece

下面的训练的部分,使用的训练数据data.txt应该是不包含test数据才对的。data.txt的格式应该是一行一句话。

import sentencepiece as spm

sp = spm.SentencePieceProcessor()
# train sentence piece
spm.SentencePieceTrainer.Train("--input=data.txt --model_prefix=trained_model --vocab_size=8000")

执行完晚上的部分,应该能得到trained_model.model和trained_model.vocab两个文件夹。后者保存了subword和对应的emission log probabilities,其id就是所在的行号。

使用方法

# load model
sp.Load("trained_model.model")

splitted_list = sp.EncodeAsPieces(" ところがNTTが二・八%で決着、円高が急進したのを受け、磯村巌副社長が「八千円は出せない」と発言。一気にムードを冷やし、磯村氏自身も「あれで随分冷えた」と苦笑した。")

splitted_list
['▁ところが', 'NTT', 'が二', '・', '八', '%', 'で', '決着', '、', '円高が', '急', '進', 'した', 'の', 'を受け', '、', '磯村', '巌', '副社長', 'が', '「', '八', '千円', 'は', '出せない', '」', 'と発言', '。', '一気に', 'ムード', 'を', '冷や', 'し', '、', '磯村', '氏', '自身', 'も', '「', 'あれ', 'で', '随分', '冷', 'えた', '」', 'と苦笑', 'した', '。']

其他一些和sentencepiece相关的文章:

使用上面训练得到的sentencepiece模型来进行分解的结果。可以看到应该是文字设定的太大了,结果分割非常细。

>>> sp.EncodeAsPieces(" ところがNTTが二・八%で決着、円高が急進したのを受け、磯村巌副社長が「八千円は出せない」と発言。一気にムードを冷やし、磯村氏自身も「あれで随分冷えた」と苦笑した。")
['▁ところが', 'NTT', 'が', '二', '・', '八', '%', 'で', '決', '着', '、', '円', '高', 'が', '急', '進', 'した', 'の', 'を', '受け', '、', '磯', '村', '巌', '副', '社長', 'が', '「', '八', '千', '円', 'は', '出せ', 'ない', '」', 'と', '発言', '。', '一', '気', 'に', 'ムード', 'を', '冷', 'や', 'し', '、', '磯', '村', '氏', '自身', 'も', '「', 'あ', 'れ', 'で', '随', '分', '冷', 'え', 'た', '」', 'と', '苦笑', 'した', '。']

其他一些和sentencepiece相关的文章:

比较不同分词手法结果:

Model Graph:

Result:

Thoughts:

Next Reading: