『Pytorch自然言語処理プログラミング』の1章が終わって、間を飛ばして5章をやってます。
東北大BERT cl-tohoku/bert-base-japanese · Hugging Face と BertJapaneseTokenizer を使って文を単語列に分割していきましょう。
... ModuleNotFoundError: You need to install fugashi to use MecabTokenizer. See https://pypi.org/project/fugashi/ for installation.
お。
$ pip install fugashi
インストーりました。
fugashi GitHub - polm/fugashi: A Cython MeCab wrapper for fast, pythonic Japanese tokenization and morphological analysis. は MeCabを使うためのwrapperなんですね、 mecab-python3 みたいなやつかな。
... ModuleNotFoundError: The ipadic dictionary is not installed. See https://github.com/polm/ipadic-py for installation.
お。
$ pip install ipadic
はい、こっちもインストーりました。
IPA辞書の説明 GitHub - polm/ipadic-py: IPAdic packaged for easy use from Python. を見るとデカデカと You Shouldn’t Use This って書いてて、もう更新されていないから UniDic を使ってねらしいけど… bert-base-japanese の説明では
Tokenization The texts are first tokenized by MeCab morphological parser with the IPA dictionary and then split into subwords by the WordPiece algorithm. The vocabulary size is 32000.
ということなので、IPA辞書でいくのがいいってことで。
# bert2.py from transformers import BertJapaneseTokenizer tknz = BertJapaneseTokenizer.from_pretrained("cl-tohoku/bert-base-japanese") print(tknz.tokenize("関西国際空港駅に行きます")) #['関西', '##国際空港', '駅', 'に', '行き', 'ます']
文を単語列に分割してはる。
ところで以前、係り受け解析がうまくいかないと思ったら形態素解析に使用する辞書の違いだったことがあり 開発記録 191013 Sun (CaboChaが文節を区切ってくれない件、一応解決) - アイソモカ 、開発記録191124 Sun (100本ノック#041, UniDic) - アイソモカ 、懲りたので、辞書を指定して動かしてみる。
まずはターミナルから MeCab を直接。
# unidic $ mecab -d /usr/local/lib/mecab/dic/unidic-cwj-2.3.0/ -Owakati 関西国際空港駅に行きます 関西 国際 空港 駅 に 行き ます # ipadic $ mecab -d /usr/local/lib/mecab/dic/ipadic/ -Owakati 関西国際空港駅に行きます 関西国際空港 駅 に 行き ます
次に、Python からIPA辞書を指定して fugashi を使ってみる。
辞書の指定方法は、.../.pyenv/versions/3.7.4/lib/python3.7/site-packages/transformers/models/bert_japanese/tokenization_bert_japanese.py
を参考にしました。
import os from fugashi import GenericTagger import ipadic dic_dir = ipadic.DICDIR mecab_option = "-Owakati" mecabrc = os.path.join(dic_dir, "mecabrc") print(mecabrc) # .../.pyenv/versions/3.7.4/lib/python3.7/site-packages/ipadic/dicdir/mecabrc mecab_option = f'-d "{dic_dir}" -r "{mecabrc}" ' + mecab_option tagger = GenericTagger(mecab_option) text = "関西国際空港駅に行く" print(tagger.parse(text)) # 関西国際空港 駅 に 行く
大丈夫そ。
MeCab + ipadic で '関西国際空港', '駅', 'に', '行き', 'ます’
と分かち書きされ、
そこで未知語になった「関西国際空港」が WordPiece により分割されて '関西', '##国際空港', '駅', 'に', '行き', 'ます’
になるという理解です。
##
は、 WordPiece で分割する前にはこの前の単語にくっついてたよ〜の印っぽい。
# bert2.py from transformers import BertJapaneseTokenizer tknz = BertJapaneseTokenizer.from_pretrained("cl-tohoku/bert-base-japanese") print(tknz.tokenize("関西国際空港駅に行きます")) print(tknz.encode("関西国際空港駅に行きます")) print(tknz.decode(tknz.encode("関西国際空港駅に行きます"))) #$ python bert2.py #['関西', '##国際空港', '駅', 'に', '行き', 'ます'] #[2, 3013, 23783, 235, 7, 2609, 2610, 3] #[CLS] 関西国際空港 駅 に 行き ます [SEP]
ははん、未知語は WordPiece によって分割されても、decode すると ##
が消えて元に戻るんやね…