MeCabとPythonで品詞を選びつつ分かち書きをしたよ

自然言語処理MeCab, Python

どうも、この前Juman++で形態素解析をするのをおすすめしちゃいましたが、自分は現在でもMeCabを使用しています。というのもJuman++では、なんとなく語彙数が少なすぎる感じがするからです(ちゃんとした検証は行っていないので、これはオフレコということでおねがいします)。というわけで、今回はMeCabをPythonから実行することで分かち書きを行うプログラムを作成したので、ここに掲載しておきます。今回は単純な分かち書きだけではなく、特定の品詞の単語を除外したり、自分で定義した書き換えルールに則って特定の品詞の語を別の語に置き換えるという処理を持たせてみました。

今回も例にならいまして、すでにPythonからMeCabを操作できる準備はできているものとして紹介します。それぞれのインストールは別サイトさんを参照するか、本サイトの作業備忘録を参考にしていてください。



OS : Ubuntu 16.04 LTS
Python : 3.5.2


1. 書いたプログラム

今回書いたプログラムは以下のとおりです。

今回のプログラムでは、MeCabを使った単純な分かち書きだけでなく、特定の品詞を除外したり、自分で定義した書き換えルールに該当する単語を別の単語に置き換えるという機能をもたせています。その分動作は遅くなり、使い方も複雑になってしまいましたが、後悔はしていません。

2. 使い方

では、次に一応使い方を紹介しておきます(主に将来の自分用になると思いますが…)。紹介の便宜上上記のプログラムは”mian.py”というファイルに記述されていて、分かち書きをしたいテキストファイルは”input.txt”という名前ということにします。まずは基本的な使い方ですが、以下のコマンドで実行することができます。

この実行により、品詞が”記号”と”EOS/BOS”は無視しつつ、他の品詞の語は原形で出力されるという結果が得られます。さらに、入力テキスト内で品詞が”名詞”でかつ品詞細分類1が”数”のものを”[数値]”という単語に置き換え、”名詞”でかつ品詞細分類1が”固有名詞”でかつ品詞細分類2が”組織”のものを”[固有名詞_組織]”という単語に置き換えるという処理を行っています。

また、出力先を変更したい場合は、以下のコマンドのように”-o”というオプションを持たせれば大丈夫です。 ちなみに、デフォルトでは、out.txtというファイルに出力されます。

おまけ機能として、出力される形態素の形式を選択できるようにしておきました。選択できる形式は、表層形と原形そして読みの三種類です。設定方法は以下の例のように実行時に”-m”というオプションをもたせるだけです。

これらは、ご自身のタスクに合わせて選択してください。しかし、この機能なのですが、MeCabで使用している辞書の書き方によっては正しく動作しない可能性があるので注意です。心配なのは「読み」を出力するときなのですが、ちゃんと読みが定義されていない辞書では、エラーが出ます。これに関してはちゃんとした対策はしていないので、みなさんが注意してくれると助かります。

i. 対象にする品詞を選ぶ

上記のコマンドに実行引数を持たせることによって対象にする品詞を選ぶことができます。選ぶための引数は”-t”と”-e”で指定することができます。”-t”では、対象とする品詞を選べます(何も指定しなければすべての品詞が対象)。また、”-e”では対象にする品詞を選べます(デフォルトでは”記号”と”EOS/BOS”を対象外にしている)。つまり、このどちらも引数に持たせない場合だと、(なかなか気持ち悪い仕様ではありますが、)記号とEOS/BOSの品詞をもつ形態素は出力から除外されるということです。以下にいくつか実行例を載せておきます。

対象外にする品詞は、「品詞細分類1,2」を限定することでより細かく設定することができます。設定方法は、それぞれ”-e1″, “-e2″というオプションでもって品詞を宣言すれば大丈夫です。

ii. 書き換え規則の定義

上記で示しました、単語の書き換え規則なのですが、文字で説明するとかなりややこしいので、解析結果例を下記に示します。

このような置き換え処理は、プログラム内(24行目辺りのreplace_ruleの宣言箇所)で定義します。定義の仕方が多少ややこしくなってしまいましたが、大きな区切りとしての「品詞」だけでなく「品詞細分類1,2」を考慮するためこのような形になりました。基本的には、入れ子状に定義してくだされば大丈夫です。もし、「品詞細分類2」についてのルールを定義したい場合は、「{品詞名:{品詞細分類1名:{品詞細分類2名:”[書き換え後の語]”}}}」という書き方になります。何かもっとわかりやすい書き方があったら教えてください。
ちなみに、なぜ”固有名詞_組織”の書き換えを行っているかを簡単に説明すると、至極単純でこれは未知語である可能性が高いからです。以上。

おわりに

というわけで、分かち書きのプログラムでした。今回は、自分が使うように書いたので、かなり自己満足的なプログラムになってしまいました。正直、ただ分かち書きを行いたいなら、MeCabだけでできるのでコマンド1行で終わってしまいます。つまり今回挙げた例は機能を持たせればもたせるほど使い方がややこしくなるという、ある意味でいいプログラムだと思います。………何いってんだか分からなくなったところで今回はここまで。