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がとってきた全情報をフィールドに記憶させ、各メソッドにてそのフィールドから必要な情報だけ正規表現でとってきて出力する。

コードは次の通り。

```py: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' '」']`