MeCabをPythonから使って遊びたい
例
コード
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import MeCab import re import pandas as pd ATTR = ['表層形', '品詞', '品詞細分類1', '品詞細分類2', '品詞細分類3', '活用形', '活用型', '原形', '読み', '発音'] TEXT = "今日はいい天気だった。\n明日も晴れるといいな。くぁせdrftgyふじこlp\n" def create_word_segmentation_func(cmd=''): """形態素解析を行う関数を生成する。 MeCabを呼び出し、この時に呼び出したMeCabで形態素解析する関数を作成する。 Args: cmd (str, optional): MeCab呼び出し時にMeCabに渡すコマンド 出力形式(--???-format)は設定しないでください。処理がうまくいかなくなる可能性があります。 Returns: (str) -> (pd.DataFrame): 形態素解析を行う関数 Args: (str): 形態素解析したい文字列 Returns: pd.DataFrame: 形態素解析を行う関数 [['表層形','品詞','品詞細分類1','品詞細分類2','品詞細分類3','活用形','活用型','原形','読み','発音'],\n ...\n ] """ # MeCab起動 # 同時に出力方法を設定しておく m = MeCab.Tagger(r'--node-format=%m\t%f[0]\t%f[1]\t%f[2]\t%f[3]\t%f[4]\t%f[5]\t%f[6]\t%f[7]\t%f[8]\n' + r' --unk-format=%m\t%f[0]\t%f[1]\t%f[2]\t%f[3]\t\t\t%f[6]\t\t\n' + r' --eos-format= ' + ' ' + cmd) def word_segmentation(s): """形態素解析を行う関数 具体的な説明は外の関数の戻り値参照 """ # MeCabで解析 # 表層形,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音 # の形で戻ってくる d = m.parse(s) # words_infos に結果を詰めていく words_infos = [] l = 0 winfo = [''] * 10 i = 0 for k, r in zip(d, range(0, len(d))): if(k == '\t'): winfo[i] = d[l:r] i += 1 l = r + 1 elif(k == '\n'): winfo[i] = d[l:r] words_infos += [winfo] winfo = [''] * 10 i = 0 l = r + 1 # テーブル words_infos を pd.DataFrame に変換して返す return pd.DataFrame(words_infos, columns=ATTR) return word_segmentation if __name__ == '__main__': # 形態素解析 word_segmentation = create_word_segmentation_func() words_infos = word_segmentation(TEXT) # 解析結果を '表層形 原形\n' で len(tword_info)行 で標準出力 for k in words_infos[['表層形', '原形']].values: print(k[0] + ' ' + k[1]) # 速度を計る import unittest class WS_TEST(unittest.TestCase): def test_ws(self): for i in range(100): word_segmentation(TEXT) unittest.main()
出力
今日 今日 は は いい いい 天気 天気 だっ だ た た 。 。 明日 明日 も も 晴れる 晴れる と と いい いい な な 。 。 く くい ぁせ drftgy ふじこ ふじこ l l p p . ---------------------------------------------------------------------- Ran 1 test in 0.100s OK
解説
基本的なこと
基本的なライブラリの入れ方や使い方は末尾にある参考ページへ。
MeCabの出力を使いやすくする
m = MeCab.Tagger(r'--node-format=%m\t%f[0]\t%f[1]\t%f[2]\t%f[3]\t%f[4]\t%f[5]\t%f[6]\t%f[7]\t%f[8]\n' + r' --unk-format=%m\t%f[0]\t%f[1]\t%f[2]\t%f[3]\t\t\t%f[6]\t\t\n' + r' --eos-format= ' + ' ' + cmd)
MeCabの初期化時にフォーマットを指定することで出てきた結果を後で使いやすくする。
今回は、tvs形式で出力させている。こうすることで、非常にデータの扱いやすさが増す。
具体的な指定方法は、MeCab公式ページ->目次->高度な使い方->出力フォーマットの詳細定義 から参照できる。
できるだけ早くテーブルを作りたい!!
# MeCabで解析 # 表層形,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音 # の形で戻ってくる d = m.parse(s) # words_infos に結果を詰めていく words_infos = [] l = 0 winfo = [''] * 10 i = 0 for k, r in zip(d, range(0, len(d))): if(k == '\t'): winfo[i] = d[l:r] i += 1 l = r + 1 elif(k == '\n'): winfo[i] = d[l:r] words_infos += [winfo] winfo = [''] * 10 i = 0 l = r + 1
pythonのstr型はことあるごとにコピーが発生するため文字列操作が結構遅い。
append(other) はotherのコピーを作ってそれを末尾に追加し、
list += other はotherの参照を末尾に追加する。
したがって、捨ててしまうwinfoを+=でwords_infos に結合させて最適化している。
また、リストの初期化は ['']*10 が早い気がする。
参考
MeCab (URL: http://taku910.github.io/mecab/)
mecab-python3 (URL: https://pypi.org/project/mecab-python3/)
Pandas (URL: https://pandas.pydata.org/)