こんにちは、エクスペリエンスデザインセンターのsgi-changです。
今日は、MeCabをPythonで使って形態素解析をしてみます。
さらに音声認識の結果とかを渡せるよう、API化してみます。
以下の流れで進めていきたいと思います。
- 形態素解析とは
- MeCabとは
- Flaskとは
- 実装編
それでは、いざ、形態素解析の世界へ
自然言語のテキストデータ(文)から、形態素に分割してそれぞれの品詞等を判別することです。
形態素とは、言語で意味を持つ最小単位です。
例えば、最近話題の「鬼滅の刃」をこれ以上小さくできないところまで分析すると、
鬼 名詞,一般,*,*,*,*,鬼,オニ,オニ 滅 名詞,一般,*,*,*,*,滅,メツ,メツ の 助詞,連体化,*,*,*,*,の,ノ,ノ 刃 名詞,一般,*,*,*,*,刃,ハ,ハ |
と「鬼」「滅」「の」「刃」の四つの単位に分けることができます。
(上記は辞書オプションなしのMeCabの解析結果)
オープンソースの形態素解析エンジンです。
C言語,C++,Java,python等の言語で使用することが可能です。
公式ページに詳しい説明があるので、以下に抜粋します。
MeCabは 京都大学情報学研究科−日本電信電話株式会社コミュニケーション科学基礎研究所 共同研究ユニットプロジェクトを通じて開発されたオープンソース 形態素解析エンジンです。 言語, 辞書,コーパスに依存しない汎用的な設計を 基本方針としています。 パラメータの推定に Conditional Random Fields (CRF) を用 いており, ChaSenが採用している 隠れマルコフモデルに比べ性能が向上しています。また、平均的に ChaSen, Juman, KAKASIより高速に動作します。 ちなみに和布蕪(めかぶ)は, 作者の好物です。
ちなみに和布蕪(めかぶ)は, 作者の好物です。
(素敵…ほっこり)
またいくつかの辞書を使って解析することができます。
(主にIPA品詞体系で構築されたIPADICが一般的らしい…)
例えば、先ほどの「鬼滅の刃」を mecab-ipadic-neologd という辞書を使って解析すると
鬼滅の刃 鬼滅の刃 名詞,固有名詞,一般,*,*,*,鬼滅の刃,キメツノヤイバ,キメ ツノヤイバ EOS |
という結果に。「鬼滅の刃」そのものが名詞として解析されています!
オープンソースの形態素解析エンジンは、他にも
- Chasen
- JUMAN
- KAKASI
- KyTea
- Janome
などがあって解析モデルだったりとか学習モデルだったり利用できる辞書だったり違いがあるようです。
Python用の軽量なウェブアプリケーションフレームワーク。標準で提供する機能を最小限に保っているため「マイクロフレームワーク」と名乗っているのだとか。
使ってみた感想は、本当にシンプル。REST APIの開発がかなり楽です。
実装の前に、MeCabとFlaskをインストールしてください。
本記事では割愛させて頂きます。
インストールには以下のサイトを参考にさせて頂きました。
ちなみに自身の実行時の環境は、Ubuntu 20.04.1 LTS です。
ここからはFlaskと、MeCabを使った形態素解析の実装をご紹介します。
例えば、
http://localhost:8000/utterance/朝の散歩
のようなリクエストに対して
{ |
"utterance": "朝の散歩", |
"result": [ |
{ |
"surface": "朝", |
"features": ["名詞","副詞可能","*","*","*","*","朝","アサ","アサ"] |
}, |
{ |
"surface": "の", |
"features": ["助詞","連体化","*","*","*","*","の","ノ","ノ"] |
}, |
{ |
"surface": "散歩", |
"features": ["名詞","サ変接続","*","*","*","*","散歩","サンポ","サンポ"] |
} |
] |
} |
のようなJSONでのレスポンスを目指します。
from flask import * |
import MeCab |
import json |
app = Flask(__name__) |
@app.route("/") |
def main(): |
return "Hello, World!" # Hello, World... |
@app.route("/utterance/<utterance>") |
def morphological_analysis(utterance): |
# 追加した辞書を指定します。 |
# もしmecab-ipadic-neologdを追加したら |
# 「echo `mecab-config --dicdir`"/mecab-ipadic-neologd"」の結果を貼り付けてください。 |
word = MeCab.Tagger( |
'-d /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd') |
result = [] |
for line in word.parse(utterance).split('\n'): |
line = line.strip() |
parts = line.split('\t', 1) |
if line == 'EOS' or len(parts) <= 1: |
continue |
# 表層形\t,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音 に分ける |
surface, features = parts |
ret = {'surface': surface, 'features': features.split(',')} |
result.append(ret) |
# Jsonにする |
results = {'utterance': utterance, 'result': result} |
# そのまま出力されると非 ASCII 文字はエスケープされるのでfalseで |
results = json.dumps(results, indent=2, ensure_ascii=False) |
return results |
# http://localhost:8000/utterance/今日はいい天気 みたいに呼び出します |
if __name__ == "__main__": |
app.run(debug=True, host='0.0.0.0', port=8000, threaded=True) |
l.19行目で指定している辞書について
もし追加辞書があったらここで指定してください。辞書のパス検索は
echo `mecab-config --dicdir`"/mecab-ipadic-neologd" |
でできます。
(mecab-ipadic-neologd部分を追加した辞書名に置き換えてください)
l.23行目のlineにはMeCabで解析した結果の
「表層形\t,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用型,活用形,原形,読み,発音」
が入ってきます。(表層形とそれ以外はタブ区切り)
l.28行目では「表層形」か「それ以外」でしか分けていないですが、名詞だけ抽出とか色々とお好みで。
以前、MeCabとCaboCha(オープンソースの係り受け解析エンジン)を使って言語解析をする機会がありました。
普段、主にフロントエンド開発に従事しているのでとても貴重な経験でした。
もしかしたら最初で最後かもしれない…
せっかくなので、いつか記事にしたいとずっと思っていたので念願かなって嬉しいです。
しかし時は過ぎ、当時はDocker + Ubuntu で動かしていたのですが、
同じチームの方に教えてもらったWSL2(Windows Subsystem for Linux)で
簡単にWindows + Ubuntuで開発が出来ると知り…驚愕でした。
それと久しぶりのMeCab、CaboChaのインストールがなかなかに手ごわかった…
色々と時と情報の流れの早さを痛感しました。
しかしながら、自然言語処理を経験したことがない私でも、言語解析に触れることができたのは、
先人達、オープンソースや、情報・ハウツーを提供されている方達のお陰だなと、改めて感謝です。
せっかく自パソコンにMeCabとCaboChaを入れたので、Web Speech APIと何かワクワクできることがないか、模索中です。
最後までお読みいただき誠にありがとうございます。