janomeライクなmecabのラッパー作った話

# 概要
mecabの爆速形態要素解析とNEologdの最新辞書をjanomeのイケてるインターフェイスで使いたい人のためのライブラリをつくりました.

# きっかけ
janomeのAnalyzerがイケてますよね.てか基本的にjanomeがインストールもしやすいし使いやすいんですよね.でもNEologdの辞書を使うのは[very experimental](https://github.com/mocobeta/janome/wiki/(very-experimental)-NEologd-%E8%BE%9E%E6%9B%B8%E3%82%92%E5%86%85%E5%8C%85%E3%81%97%E3%81%9F-janome-%E3%82%92%E3%83%93%E3%83%AB%E3%83%89%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)って謳ってるのでなんだかなぁと思っていました.じゃあ形態要素解析の部分はmecabとNEologdに任せて,それを使いやすくするためのラッパーを作ろうと思ったのがきっかけです.

# その名もwakame!
[githubはこちら](https://github.com/tenajima/wakame)
[PyPIはこちら](https://pypi.org/project/wakame/)
janomeの「me」の部分とめかぶの派生からのwakameです.作者がわかめ好きだからではありません.
最初はmecab-no-meという名前で作ってたけど先輩から「wakameでよくね?」って言われて採用させてもらいました.よくわからない名前になる危機を救ってくれた先輩に感謝.

# インストール
wakame自体はpipで簡単にインストールできます.

```
pip install wakame
```
ただ,mecabを使うのでmecabのインストールが別途必要になります.[README](https://github.com/tenajima/wakame)にもいちおう記載していますので,そちらを参照してください.

# 使い方
基本的にはjanomeのように使えることを目指して使っています.

## 基本的な使い方
READMEに載っているものと同じですが,基本的な使い方は以下のとおりです.

```python
from wakame.tokenizer import Tokenizer
from wakame.analyzer import Analyzer
from wakame.charfilter import *
from wakame.tokenfilter import *

text = '和布ちゃんこんにちは'

# 基本的な使い方
tokenizer = Tokenizer()
tokens = tokenizer.tokenize(text)
for token in tokens:
    print(token)
# >> 和布	名詞,一般,*,*,*,*,和布,ワカメ,ワカメ
# >> ちゃん	名詞,接尾,人名,*,*,*,ちゃん,チャン,チャン
# >> こんにちは	感動詞,*,*,*,*,*,こんにちは,コンニチハ,コンニチワ

# 分かち書き
tokens = tokenizer.tokenize(text, wakati=True)
print(tokens)
# >> ['和布', 'ちゃん', 'こんにちは']

# 辞書をNEologdにする場合
tokenizer = Tokenizer(use_neologd=True)
tokens = tokenizer.tokenize(text)
for token in tokens:
    print(token)
# >> 和布	名詞,一般,*,*,*,*,和布,ワカメ,ワカメ
# >> ちゃん	名詞,接尾,人名,*,*,*,ちゃん,チャン,チャン
# >> こんにちは	感動詞,*,*,*,*,*,こんにちは,コンニチハ,コンニチワ


# filterを利用する場合
# '和布'を'wakame'に変える
char_filters = [RegexReplaceCharFilter('和布', 'wakame')]
# '名詞'のみ取り出すが,'名詞,接尾'のものは取り出さないようにする.
token_filters = [POSKeepFilter('名詞'), POSStopFilter(['名詞,接尾'])]
analyzer = Analyzer(tokenizer, char_filters=char_filters, token_filters=token_filters)
tokens = analyzer.analyze(text)
for token in tokens:
    print(token)
# >> wakame	名詞,固有名詞,組織,*,*,*,*
```

## pandas.DataFrameで扱う
データを見たり,自分でゴニョゴニョするときにDataFrame型式のほうが使いやすい場面があるなぁと思い,surfaceやらpart_of_speechやらをDataFrameで返せるメソッドを用意しました.

```python
# tokenの情報をDataFrameで用いる場合
tokenizer = Tokenizer()
analyzer = Analyzer(tokenizer)
df = analyzer.analyze_with_dataframe(text)
print(df)
# >>   surface part_of_speech infl_type infl_form base_form reading phonetic
# >> 0      和布      名詞,一般,*,*         *         *        和布     ワカメ      ワカメ
# >> 1     ちゃん     名詞,接尾,人名,*         *         *       ちゃん     チャン      チャン
# >> 2   こんにちは      感動詞,*,*,*         *         *     こんにちは   コンニチハ    コンニチワ

```

## 独自のfilter
- urlを特定の文字列に変換する `URLReplaceFilter`
- 特定の品詞を特定の文字列に置き換える `POSReplaceFilter`
- 変換された文字列をもとに戻す `RestoreFilter`

なんでもとに戻すfilterを作ったかというと,「`くん`と`さん`は`様`にしたいけど`ちゃん`はそのまま使いたい」みたいなときがあったからです.

```python
text = '鰹くんと栄螺さんは和布ちゃんの兄妹です'
tokenizer = Tokenizer()
token_filters = [POSReplaceFilter(['名詞,接尾'], '様'), RestoreFilter(['ちゃん'])]
analyzer = Analyzer(tokenizer, token_filters=token_filters)
text = ''.join(analyzer.analyze_with_dataframe(text)['surface'])
print(text)
# >> 鰹様と栄螺様は和布ちゃんの兄妹です
```

このように「あったら便利だなぁ」って機能を追加しております.
大きな文書を品詞分解するのもmecabを使ってるので結構速く処理できます.

# 今後
今後もほしいfilterがあったらぼちぼち追加していこうと思います.
暖かく見守ってくれたらうれしいです.