BoWと形態素解析|実践的自然言語処理入門 #1
時折自然言語処理のセミナーを行うのですが、毎回同じことを話すのもなかなか退屈なので、基礎知識を公開情報の形式で簡単にまとめていければと思います。
#1では教師あり学習について簡単に復習した上で、言語処理の基本となるBoWと形態素解析について解説していきます。
以下目次になります。
1. 機械学習(教師あり学習)の復習
2. 自然言語の取り扱いとBoW(Bag of Words)
3. 形態素解析とJanome
4. まとめ
1. 自然言語処理に機械学習をどのように適用するか(概論)
自然言語処理について学ぶ前にまず機械学習について軽く復習します。
上記の記事でご説明したように機械学習において実務で用いやすい教師あり学習のアルゴリズムはXとyの組みから規則を作って新しいXに対して予測を行うアルゴリズムです。
上記の記事では距離の概念を利用して規則を作っていますが、規則の作り方は色々とありこれについては下記の『はじめてのパターン認識』のシリーズで諸々取り扱っていますので詳細について気になる方は下記記事のご確認をお願いいたします。
教師あり学習について簡単な復習を行ないましたが、上記のような表形式で表せるデータのことを構造化データ(Structured data)と呼んでいます。こちらに関してはベーシックな統計や機械学習の手法を用いて計算していくことができます。しかし、言語は表型の構造では表すことができない非構造化データ(Unstructured data)と呼ばれる形式です。
非構造化データ - Wikipedia
この非構造化データ形式である言語をどう扱うのが良いのでしょうか。2節では言語を表型の形式でベーシックに取り扱ったBoWについて紹介します。
2. 自然言語の取り扱いとBoW(Bag of Words)
1節では機械学習(教師あり学習)について復習しましたが、2節では機械学習を今回のテーマである自然言語処理にどのように当てはめるかについて考えていきましょう。これを考えるにあたって初めに抑えておきたいのがBoW(Bag of Words)です。BoWとは文書群を文書(Document)と単語(Word)の行列で表現する形式で、それぞれの要素を出現数のカウントによって値を与えます。
これによって文書群を行列で表記できるようにできるため、教師あり学習の手法を用いて計算していくことができます。
ここで疑問が生じるのですが、英語のようなスペース区切りの文書は行列にしやすいと思いますが、日本語にこの方法を適用するにはどのようにするのが良いでしょうか。
これを実現する手法として形態素解析というのがあるのですがこちらについては3節で取り扱います。
形態素解析とは日本語の文章を分かち書きする手法のことです。例えば、『私は今日Pythonの勉強をする』という入力に対して形態素解析を行うことで、『私|は|今日|Python|の|勉強|を|する』という形で出力を行ってくれます。これにより、1節で述べたBoW形式に落とすことができ、教師あり学習の手法を用いることができます。
また、この際の分割のアルゴリズムとしてはデファクト的によく用いられているMeCabの最小コスト法が有名です。最小コスト法では単語の生起コストと連接コストの二つの辞書を元に最もコストの低いパスとして分割結果を出力します。これにより文章を単語単位に分かち書きすることができます。
MeCabはよく用いられるのですが、インストールでこけるケースが多いのでPython前提であればJanomeを勧めるようにしています。Janomeの処理パフォーマンスが問題になる際はPythonで実装することそのものから見直す方が良いので、Pythonを用いて行っている段階でのR&Dの仕事としてはJanomeで十分だと思います。
Welcome to janome's documentation! (Japanese) — Janome v0.3 documentation (ja)
以下、Janomeの簡単な用法についてまとめます。
・モジュールのインストール
$ pip install janome
でインストールすることが可能です。
・デフォルト辞書の読み込みとシンプルな形態素解析の実行
from janome.tokenizer import Tokenizer
t = Tokenizer()
for token in t.tokenize(u'すもももももももものうち'):
print(token)
上記を実行することで、簡単な形態素解析を行うことができます。
・分かち書きモードでの実行
from janome.tokenizer import Tokenizer #別途行なっているなら不要
t = Tokenizer()
tokens = t.tokenize(u'分かち書きモードがつきました!', wakati=True)
print(tokens)
上記を実行することで単語をリスト形式で得ることができます。
・ちょっと高度な処理
from janome.tokenizer import Tokenizer
t = Tokenizer()
for token in t.tokenize(u'すもももももももものうち'):
if token.part_of_speech.split(',')[0] == '名詞'
print(token.surface)
これにより名詞の単語のみ出力することができます。タグ付けなどの簡単なテキストマイニングでは、名詞に着目するだけでうまくいくケースが多いなど、品詞を元にフィルタリングしていく処理などは便利です。(Filter機能を使う方法もあるようなのですが、こちらの方がわかりやすいのでこのような記述としました。)
4. まとめ
#1では自然言語に教師あり学習のアルゴリズムを使用するにあたって、BoWと形態素解析について取り扱いました。
#2ではPoCの開発に用いる際に便利だったりBoWにおける頻度の代用にもなるということで特徴語抽出のアルゴリズムのtf-idfの簡単な仕組みとそのPythonでの実装について取り扱います。
↓以降の記事リストは下記です。
分散表現とWord2vec|実践的自然言語処理入門 #3 - lib-arts’s diary
言語処理におけるグラフ理論とネットワーク分析|実践的自然言語処理入門 #6 - lib-arts’s diary
↓また、当記事の内容を元に再構成と少しだけ加筆を行い電子書籍化を行いました!pdf版が欲しいなどありましたら下記をご購入いただけたら大変嬉しいです!!