pythonでMeCabによる解析結果をndarrayに得るクラスを作った


0.pythonでMeCabを使う方法

  1. 頑張ってMeCabをインストールする。64bit版のpython(3.7以上)をwindowsから使っている人は、古い情報に惑わされないようにしてください。mecab-python-windowsを使ったMeCabのインストールはうまくいきません。その代わり、pip install mecabで一発でうまくいくようになっていました。
  2. import MeCabする。import Mecabではないので注意
  3. print(MeCab.Tagger('-Owakati').parse('すもものははははははははもものははははははとわらう'))みたいにする。

これで得られるのは「一つの長い文字列」であり、リストやらタプルやらになっているわけではない。ちと不便。

1.やったこと

pythonでクラスを作った。コンストラクタでMeCab.Tagger('-Odump')をやることでMeCabがとってきた全情報をフィールドに記憶させ、各メソッドにてそのフィールドから必要な情報だけ正規表現でとってきて出力する。

コードは次の通り。

MeCab_handler.py
import re, MeCab
import numpy as np
import jaconv
from pykakasi import kakasi

class MeCab_handler:
    """
    MeCab.Tagger('-Odump').parse((コンストラクタの引数))を実行し、
    その結果を各メソッドで一次元ndarrayとして取得

    """
    def __init__(self, sentence):
        self.parse_result = MeCab.Tagger('-Odump').parse(sentence)

    def get_separated(self):
        """
        分かち書き
        """
        tmp = np.array(re.findall('\n[0-9]+ ([^ ]*)', self.parse_result))
        return tmp[0:np.size(tmp)-1] #EOSをカット

    def get_words_basic(self):
        """
        基本形
        """
        tmp = np.array(re.findall('\n[0-9]+ [^ ]* (?:[^,]*,){6,6}([^,]*)', self.parse_result))
        return tmp[0:np.size(tmp)-1]

    def get_POS(self, need_detail=False):
        """
        品詞
        オプション引数need_detailをTrueとすると、
        下位分類(最大3段階)がある場合にそれも取得する
        """
        if need_detail:
            tmp = np.array(re.findall('\n[0-9]+ [^ ]* ([^,]*(?:,[^*,]+(?:,[^*,]+(?:,[^*,])?)?)?)', self.parse_result))
        else:
            tmp = np.array(re.findall('\n[0-9]+ [^ ]* ([^,]*)', self.parse_result))

        return tmp[0:np.size(tmp)-1] #EOSをカット

    def get_conjugation_type(self):
        """
        活用型
        """
        tmp = np.array(re.findall('\n[0-9]+ [^ ]* (?:[^,]*,){4,4}([^,]*)', self.parse_result), dtype='object')
        tmp = np.where(tmp=='*', None, tmp)
        return tmp[0:np.size(tmp)-1]

    def get_conjugation_form(self):
        """
        活用形
        """
        tmp = np.array(re.findall('\n[0-9]+ [^ ]* (?:[^,]*,){5,5}([^,]*)', self.parse_result))
        return tmp[0:np.size(tmp)-1]

    def get_katakana(self):
        """
        カタカナ
        """
        tmp = np.array(re.findall('\n[0-9]+ [^ ]* (?:[^,]*,){7,7}([^,]*)', self.parse_result))
        return tmp[0:np.size(tmp)-1]

    def get_hiragana(self):
        """
        ひらがな
        """
        katakanas = self.get_katakana()
        hiraganas = np.zeros(0, dtype=katakanas.dtype)
        for katakana in katakanas:
            hiraganas = np.append(hiraganas, jaconv.kata2hira(katakana))
        return hiraganas


    def get_how_to_speak(self):
        """
        発音の仕方。get_hiraganaやget_katakanaなどとは異なる場合がある。
        ローマ字
        """
        tmp = np.array(re.findall('\n[0-9]+ [^ ]* (?:[^,]*,){8,8}([^ ]*)', self.parse_result))
        katakanas = tmp[0:np.size(tmp)-1]

        kakac = kakasi()
        kakac.setMode("K", "a") #カタカナをasciiへ
        kakac.setMode("r", "Hepburn") #ローマ字にヘボンを採用
        conv = kakac.getConverter()

        romans = np.zeros(0, dtype='object')        
        for katakana in katakanas:
            romans = np.append(romans, conv.do(katakana))
        return romans

機能はソースコードにも書きましたが、以下の表のようになっております。

メソッド 例(print(MeCab_handler('全米が泣いた。映画ドラえもん「のび太の理論と実践」').メソッド))
get_separated() ['全米' 'が' '泣い' 'た' '。' '映画' 'ドラえもん' '「' 'のび太' 'の' '理論' 'と' '実践' '」']
get_words_basic() ['全米' 'が' '泣く' 'た' '。' '映画' 'ドラえもん' '「' 'のび太' 'の' '理論' 'と' '実践' '」']
get_POS() ['名詞' '助詞' '動詞' '助動詞' '記号' '名詞' '名詞' '記号' '名詞' '助詞' '名詞' '助詞' '名詞' '記号']
get_POS(True) ['名詞,固有名詞,地域,一' '助詞,格助詞,一般' '動詞,自立' '助動詞' '記号,句点' '名詞,一般' '名詞,固有名詞,一般' '記号,括弧開' '名詞,固有名詞,人名,名' '助詞,連体化' '名詞,一般' '助詞,格助詞,一般' '名詞,サ変接続' '記号,括弧閉']
get_conjugation_type() [None None '五段・カ行イ音便' '特殊・タ' None None None None None None None None None None]
get_conjugation_form() ['*' '*' '連用タ接続' '基本形' '*' '*' '*' '*' '*' '*' '*' '*' '*' '*']
get_katakana() ['ゼンベイ' 'ガ' 'ナイ' 'タ' '。' 'エイガ' 'ドラエモン' '「' 'ノビタ' 'ノ' 'リロン' 'ト' 'ジッセン' '」']
get_hiragana() ['ぜんべい' 'が' 'ない' 'た' '。' 'えいが' 'どらえもん' '「' 'のびた' 'の' 'りろん' 'と' 'じっせん' '」']
get_how_to_speak() ['zenbei' 'ga' 'nai' 'ta' '。' 'eiga' 'doraemon' '「' 'nobita' 'no' 'riron' 'to' 'jissen' '」']