Posted at

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


概要

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


きっかけ

janomeのAnalyzerがイケてますよね.てか基本的にjanomeがインストールもしやすいし使いやすいんですよね.でもNEologdの辞書を使うのはvery experimentalって謳ってるのでなんだかなぁと思っていました.じゃあ形態要素解析の部分はmecabとNEologdに任せて,それを使いやすくするためのラッパーを作ろうと思ったのがきっかけです.


その名もwakame!

githubはこちら

PyPIはこちら

janomeの「me」の部分とめかぶの派生からのwakameです.作者がわかめ好きだからではありません.

最初はmecab-no-meという名前で作ってたけど先輩から「wakameでよくね?」って言われて採用させてもらいました.よくわからない名前になる危機を救ってくれた先輩に感謝.


インストール

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

pip install wakame

ただ,mecabを使うのでmecabのインストールが別途必要になります.READMEにもいちおう記載していますので,そちらを参照してください.


使い方

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


基本的な使い方

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

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で返せるメソッドを用意しました.

# 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を作ったかというと,「くんさんにしたいけどちゃんはそのまま使いたい」みたいなときがあったからです.

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があったらぼちぼち追加していこうと思います.

暖かく見守ってくれたらうれしいです.