Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
10
Help us understand the problem. What is going on with this article?
@NLPingu

低頻度語をぶっ壊す~How to subword-nmt~

More than 1 year has passed since last update.

LSTMとかの深層学習モデルで自然言語を扱うとき、
語彙数が増えると計算量やGPUメモリサイズが爆発的に増えてしまうことが多い。

予め低頻度語をBPEサブワード化することで語彙サイズを減らそうというエントリー。

サブワード化ってなんだ。

あまり出現しない単語を、文字や部分文字(サブワード)に分割しようということ。
これにより、語彙サイズが圧縮できる。
極端な話、英単語を文字に分割すれば語彙数は英語アルファベットの52種(大文字+小文字)に圧縮可能。

BPEって何だ。

BPE(Byte Pair Encoding)は元々圧縮に使われていた技術。
共通な2バイトを新しい1バイトに置き換えることで圧縮していく。
例えば、aabbaacaaAに置き換えると、AbbAcと圧縮できる。

この処理を語彙圧縮に適用したのが、
Neural Machine Translation of Rare Words with Subword Units

事前にコーパスの語彙に対してBPEを適用することで、サブワードを学習する。

subword-nmtのインストール

subword-nmtを使えば、簡単にBPEを使用したサブワードの学習とサブワード化ができる。
Pythonで書かれているのでpipでインストールする。

pip install subword-nmt

データ準備と前処理

サブワードの学習にはコーパスが必要。
今回は、吾輩は猫であるを用意した。

wagahai.txtの一部
 吾輩わがはいは猫である。名前はまだ無い。
 どこで生れたかとんと見当けんとうがつかぬ。何でも薄暗いじめじめした所でニャーニャー泣いていた事だけは記憶している。吾輩はここで始めて人間というものを見た。

日本語からサブワードを学習する場合は、文章はあらかじめ単語単位に分割されている必要がある。
今回はMeCabを使って、分かち書きしたwakati_wagahai.txtを用意した。

mecab -b 100000 -Owakati wagahai.txt -o wakati_wagahai.txt
wakati_wagahai.txtの一部
  吾輩 わがはい は 猫 で ある 。 名前 は まだ 無い 。 
  どこ で 生れ た か とんと 見当 けん とう が つか ぬ 。 何 でも 薄暗い じめじめ し た 所 で ニャーニャー 泣い て いた事 だけ は 記憶 し て いる 。 吾輩 は ここ で 始め て 人間 という もの を 見 た 。 

いざサブワードの学習

以下のコマンドでwakati_wagahai.txtからサブワードを学習する。

subword-nmt learn-bpe -s 3000 < wakati_wagahai.txt > codes.txt

-sは共通文字置き換え回数を指定している。
小さいほどサブワードは文字単位になる。(0だと完全に文字になるはず。)

codes.txtの中身はこんな感じ。

codes.txtの一部
吾 輩</w>
ま す</w>
さ ん</w>
じ ゃ</w>
な っ</w>
こ れ</w>
と こ
で も</w>

吾 輩</w>は、単語内に輩</w>が出現したら我輩</w>に結合するよ。という意味。
さっきのBPEの例で行くとaaAにするよ。と同意。
(</w>は元の単語の末尾であることを表してます。 )

サブワード化する。

学習したcodes.txtを用いて以下のコマンドでwakati_wagahai.txtをサブワード化してみる。

subword-nmt apply-bpe -c codes.txt < wakati_wagahai.txt > subword_wagahai.txt

subword_wagahai.txtはこんな感じ。

subword_wagahai.txtの一部
  吾輩 わが@@ はい は 猫 で ある 。 名前 は まだ 無い 。 
  どこ で 生れ た か とんと 見当 けん とう が つか ぬ 。 何 でも 薄@@ 暗い じ@@ め@@ じめ し た 所 で ニャ@@ ー@@ ニャ@@ ー 泣い て いた@@ 事 だけ は 記憶 し て いる 。 吾輩 は ここ で 始め て 人間 という もの を 見 た 。

わが@@はいと元々1単語であったことを示している。

低頻度語は解体できたのか

以下の簡単なPythonスクリプトで語彙数を確認してみる。

import sys
for arg in sys.argv[1:]:
    print("Input : {}".format(arg))
    with open(arg, "r") as f:
        text = f.read()
    tokens = text.split()
    print("Vocab : {}".format(len(set(tokens))))
$ python3 counter.py wakati_wagahai.txt subword_wagahai.txt 
Input : wakati_wagahai.txt
Vocab : 15717
Input : subword_wagahai.txt
Vocab : 7515

無事語彙数が15717から7515に減ったことがわかる。

10
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
NLPingu
筑波大学CSのD1です。研究分野は自然言語処理です。理研AIPでアンサンブルラーニングや知識構築、属性値抽出の研究をしています。森羅プロジェクト(http://urx.blue/XHQi )というWikipediaの構造化タスクの運営に携わっています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
10
Help us understand the problem. What is going on with this article?