今回は、「MeCab(メカブ)」という形態素解析器を使用して自然言語処理を実装していきたいと思います。
自然言語処理とは、「natural language processing:NLP」とも言って、人間が日常的に使っている自然言語をコンピュータに処理させる技術であり、人工知能と言語学の分野と言われています。
詳しくわ、「Wikipedia:自然言語処理」をご参照ください。
その自然言語処理に使われる解析器の1つが「形態素解析」になります。
他にも「構文解析」「文脈解析」「意味解析」とありますが、今回は導入が簡単ですぐにプログラムに組み込む事ができそうな「形態素解析」を中心に実装します。
形態素解析とは、「形態素を解析する」というように対象言語の文法に従ってそれぞれ単語区切りの形態素に分割して、単語や品詞が登録されている辞書から解析を行ってコンピュータでの処理を簡易的にします。
例えば「形態素解析をする」という文を形態素にしてみると、「形態素解析/を/する」という風に分けられ、「名詞/助詞/動詞」のようにそれぞれの特徴を得ることができます。
取得したい品詞を指定できれば、余分な単語を除いた処理が可能となるので、チャットボットの受け答えなどに活用することができます。
実際に検索エンジンなどのプログラムにも使われているそうです。
形態素解析器のソフトウェアは数種類あると言われておりますが、その中でもサンプル数が豊富でPythonが実行可能な「MeCab」を使って行きます。
MeCabについての詳しい情報は、こちら「MeCab (和布蕪)とは」をご参照ください。
他の記事でもMeCabを利用したプログラムを紹介しているので興味がある方はぜひご参照ください。
実行環境 |
---|
Windows Subsystem for Linux |
Python 3.6.8 |
pip 9.0.1 |
使用ライブラリ | ライセンス |
---|---|
mecab | ? |
形態素解析器のMeCabをPythonで実行させるには、先にお使いのシステムにMeCab本体を導入する必要があります。
mecab-python3の公式ドキュメントより
$ sudo apt install swig libmecab-dev
# 本体と辞書
$ sudo apt install mecab mecab-ipadic-utf8
さっそく起動してみます。
# 実行
$ mecab
形態素解析をする
形態素 名詞,一般,*,*,*,*,形態素,ケイタイソ,ケイタイソ
解析 名詞,サ変接続,*,*,*,*,解析,カイセキ,カイセキ
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
する 動詞,自立,*,*,サ変・スル,基本形,する,スル,スル
EOS
上記のように起動し処理されれば成功です。
解析には辞書の「mecab-ipadic」が使用されていますが、実は最近流行っているような新語には対応していません。
例えば以下のような文では
# 実行
$ mecab
人工知能がバズる
人工 名詞,一般,*,*,*,*,人工,ジンコウ,ジンコー
知能 名詞,一般,*,*,*,*,知能,チノウ,チノー
が 助詞,格助詞,一般,*,*,*,が,ガ,ガ
バズ 名詞,一般,*,*,*,*,*
る 助動詞,*,*,*,文語・ル,基本形,る,ル,ル
EOS
と解析されますが、意図としている解析は
人工知能がバズる
人工知能 名詞,固有名詞,一般,*,*,*,人工知能,ジンコウチノウ,ジンコーチノー
が 助詞,格助詞,一般,*,*,*,が,ガ,ガ
バズる 名詞,固有名詞,一般,*,*,*,バズる,バズル,バズル
EOS
のような結果だと思います。
このように細かい部分にも対応された辞書を使えるようにするため「mecab-ipadic-NEologd」もインストールします。
ここでは簡単な説明にとどめているので、詳しい内容については「mecab-ipadic-NEologdの公式ドキュメント」をご覧ください。
インストールするには、GitHubに置かれているmecab-ipadic-NEologdのリポジトリをダウンロードします。
ダウンロードしたいディレクトリにて以下のコマンドを打ちます。
$ git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
すると「mecab-ipadic-neologd」というリポジトリがダウンロードされるので、cdコマンドでリポジトリの階層に移動します。
$ cd mecab-ipadic-neologd
移動したら以下のコマンドを打ってインストールを行います。
/mecab-ipadic-neologd$ ./bin/install-mecab-ipadic-neologd -n
install......
# 結果の確認
# 「yes」と入力
# sudo権限で実行されるのでパスワードを入力
mecab-ipadic-neologdのインストール先は、mecab-configの設定により決められるということなので実際どの階層に辞書が置かれているか確認する必要があります。
確認するには以下のコマンドを打ちます。
$ mecab-config --dicdir
/usr/lib/x86_64-linux-gnu/mecab/dic
私のシステム上では「/usr/lib/x86_64-linux-gnu/mecab/dic」の配下に「mecab-ipadic-neologd」の辞書が納められているということになります。
※mecab-ipadic-neologdが置かれている場所は環境によって異なる場合があるので公式ドキュメントでも確認方法を見ておきましょう。
新語が適用した辞書を利用するためには、オプションとして「/usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd」のようなフルパスを与える必要があるので、フルパスをコピーします。
ペーストして実際に使ってみましょう。
# 実行
$ mecab -d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd
人工知能がバズる
人工知能 名詞,固有名詞,一般,*,*,*,人工知能,ジンコウチノウ,ジンコーチノー
が 助詞,格助詞,一般,*,*,*,が,ガ,ガ
バズる 名詞,固有名詞,一般,*,*,*,バズる,バズル,バズル
EOS
MeCabの設定ができたので、Pythonモジュールの「mecab-python3」をpipインストールします。
$ pip3 install mecab-python3
これで準備は完了です。
まずは適当なスクリプトファイルにコードを書いて形態素解析を出力してみます。
# test.py
import MeCab
text = '形態素解析をする'
mecab = MeCab.Tagger()
par = mecab.parse(text)
print(text)
print('----------')
print(par)
デフォルトの設定では以下のように出力されます。
# 実行
$ python3 test.py
形態素解析をする
----------
形態素 名詞,一般,*,*,*,*,形態素,ケイタイソ,ケイタイソ
解析 名詞,サ変接続,*,*,*,*,解析,カイセキ,カイセキ
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
する 動詞,自立,*,*,サ変・スル,基本形,する,スル,スル
EOS
他にも、オプション機能として4種類程の出力フォーマットを呼び出すことができます。
「4種類程」と言った理由は、標準で用意されているオプションの4種類以外にユーザーがフォーマットを自由に定義できるようになっているからです。
詳しくはMeCab公式の出力フォーマットをご参照ください。
では4種類のオプションをそれぞれ見ていきましょう。
分かち書きとは、文章の単語を空白で区切ることと言われています。
では実際に「MeCab.Tagger()」の引数にオプションを追加して実行してみます。
# test.py
import MeCab
text = '形態素解析をする'
""" 分かち書きオプションを追加 """
mecab = MeCab.Tagger('-Owakati')
par = mecab.parse(text)
print(text)
print('----------')
print(par)
# 実行
$ python3 test.py
形態素解析をする
----------
形態素 解析 を する
振り仮名オプションを使うと、文字に対しての読み仮名を出力します。
# test.py
import MeCab
text = '形態素解析をする'
""" 読み仮名オプションを追加 """
mecab = MeCab.Tagger('-Oyomi')
par = mecab.parse(text)
print(text)
print('----------')
print(par)
# 実行
$ python3 test.py
形態素解析をする
----------
ケイタイソカイセキヲスル
ChaSenとは、茶筌システムとも呼び、奈良先端科学技術大学院大学情報科学研究科自然言語処理学講座(松本研究室)が保持する、形態素解析ソフトウェアの事です。
その茶筌の解析器を使用して出力することができます。
詳しくこちらMeCab の開発経緯をご覧ください。
# test.py
import MeCab
text = '形態素解析をする'
""" ChaSenオプションを追加 """
mecab = MeCab.Tagger('-Ochasen')
par = mecab.parse(text)
print(text)
print('----------')
print(par)
# 実行
$ python3 test.py
形態素解析をする
----------
形態素 ケイタイソ 形態素 名詞-一般
解析 カイセキ 解析 名詞-サ変接続
を ヲ を 助詞-格助詞-一般
する スル する 動詞-自立 サ変・スル 基本形
EOS
このオプションは単語に含まれる全情報を出力することができます。
# test.py
import MeCab
text = '形態素解析をする'
""" 全情報出力オプションを追加 """
mecab = MeCab.Tagger('-Odump')
par = mecab.parse(text)
print(text)
print('----------')
print(par)
# 実行
$ python3 test.py
形態素解析をする
----------
0 BOS BOS/EOS,*,*,*,*,*,*,*,* 0 0 0 0 0 0 2 1 0.000000 0.000000 0.000000 0
7 形態素 名詞,一般,*,*,*,*,形態素,ケイタイソ,ケイタイソ 0 9 1285 1285 38 2 0 1 0.000000 0.000000 0.000000 5338
13 解析 名詞,サ変接続,*,*,*,*,解析,カイセキ,カイセキ 9 15 1283 1283 36 2 0 1 0.000000 0.000000 0.000000 9241
20 を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ 15 18 156 156 13 6 0 1 0.000000 0.000000 0.000000 8792
29 する 動詞,自立,*,*,サ変・スル,基本形,する,スル,スル 18 24 599 599 31 6 0 1 0.000000 0.000000 0.000000 10526
33 EOS BOS/EOS,*,*,*,*,*,*,*,* 24 24 0 0 0 0 3 1 0.000000 0.000000 0.000000 9188
右側の数字に関しては、スクリプト言語のバインディングの「全メソッド」に内容が記載されているのでそちらをご参考ください。
このオプションは、MeCab導入時に触れた「新語」が適用されている辞書を使用する方法です。
ターミナルで行ったMeCabのコマンドオプション「-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd」と同じように「MeCab.Tagger()」の引数にそのまま渡します。
# test.py
import MeCab
text = '形態素解析をする'
""" mecab-ipadic-NEologdオプションを追加 """
mecab = MeCab.Tagger('-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd')
par = mecab.parse(text)
print(text)
print('----------')
print(par)
# 実行
$ python3 test.py
形態素解析をする
----------
形態素解析 名詞,固有名詞,一般,*,*,*,形態素解析,ケイタイソカイセキ,ケイタイソカイセキ
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
する 動詞,自立,*,*,サ変・スル,基本形,する,スル,スル
EOS
今まで「形態素」と「解析」で分割されていましたが、1つの名詞として「形態素解析」が出力されるようになりました。
これまで「MeCab.Tagger()」オブジェクトを作成して、「parse()」メソッドにテキストを渡して形態素を出力してきましたが、「parse()」ではなく「parseToNode()」メソッドを使って柔軟に処理が行えるように実装していきたいと思います。
例えば「parseToNode()」を使用してこれまでと同じような出力をするとなると、以下のように処理をします。
# test.py
import MeCab
text = '形態素解析をする'
mecab = MeCab.Tagger()
par = mecab.parseToNode(text)
print(text)
print('----------')
print(type(par))
while par:
""" 形態素の出力 """
print(par.surface)
""" 品詞などの出力 """
print(par.feature)
""" 次の単語へ """
par = par.next
# 実行
$ python3 test.py
形態素解析をする
----------
<class 'MeCab.Node'>
BOS/EOS,*,*,*,*,*,*,*,*
形態素
名詞,一般,*,*,*,*,形態素,ケイタイソ,ケイタイソ
解析
名詞,サ変接続,*,*,*,*,解析,カイセキ,カイセキ
を
助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
する
動詞,自立,*,*,サ変・スル,基本形,する,スル,スル
BOS/EOS,*,*,*,*,*,*,*,*
形態素の出力では「surface」とし、品詞などの出力には「feature」とすることで必要な情報を細かく取得することができます。
whileループの末尾に「next」というメソッドを変数に格納していますが、これは次の処理を実行させるために必要なメソッドです。
その他の情報の取得に関しては、スクリプト言語のバインディングの「全メソッド」に内容が記載されているのでそちらをご参照ください。
細かい制御ができるようになったところなので、欲しい情報だけ取得する処理を行ってみたいと思います。
# test.py
import MeCab
text = '形態素解析をする'
mecab = MeCab.Tagger()
par = mecab.parseToNode(text)
print(text)
print('----------')
while par:
if par.feature.split(',')[0] == '名詞':
print(par.surface, par.feature.split(',')[0])
par = par.next
「split()」関数で0番目の「名詞」を指定し比較演算子をすることで、名詞の形態素だけを取得することができます。
出力すると
# 実行
$ python3 test.py
形態素解析をする
----------
形態素 名詞
解析 名詞
このように入力されたテキストを形態素解析にかけ、何らかの処理を実行できるようになれば無駄の無いまとまったプログラムを実装できるようになります。
冒頭でも言ったようにチャットボットや検索エンジンのプログラムも簡易的に開発ができるようになると思います。
このようなソフトウェアを開発してくださった 京都大学情報学研究科−日本電信電話株式会社コミュニケーション科学基礎研究所 共同研究ユニットプロジェクトさんには非常に感謝致します。
活かすも殺すも開発者次第なので、無駄にならないようどんどん開発していきましょう。
それでは以上となります。
最後までご覧いただきありがとうございました。