静かなる名辞

pythonとプログラミングのこと


【python】MeCabバインディングのparseToNodeでBOS/EOSを除外

はじめに

 mecab-pythonで以下のようなコードを書くことがよくあると思います。

import MeCab
s = "吾輩は猫である。"

tagger = MeCab.Tagger("")
tagger.parse("")

node = tagger.parseToNode(s)
while node:
    print(node.surface, node.feature)
    node = node.next
    
""" =>
 BOS/EOS,*,*,*,*,*,*,*,*
吾輩 名詞,代名詞,一般,*,*,*,吾輩,ワガハイ,ワガハイ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
猫 名詞,一般,*,*,*,*,猫,ネコ,ネコ
で 助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ
ある 助動詞,*,*,*,五段・ラ行アル,基本形,ある,アル,アル
。 記号,句点,*,*,*,*,。,。,。
 BOS/EOS,*,*,*,*,*,*,*,*
"""

 BOS/EOSがしっかり出ています。出力フォーマットが空文字列なので表面的には現れませんが、品詞タグとしてはBOS/EOSという特別なものが出てくるということです。後処理で取り除いても良いですが、遅いpythonのリスト処理であれこれするよりは、先になんとかしておいた方がスマートですし速いと思います。

 ということで工夫してみます。

対処法

 まずBOSについては、ループの前に1つ進めておくことで解決します。

 また、EOSはループで1つ先を見れば解決します。

 以上を踏まえたコードと結果が以下のものです。

import MeCab
s = "吾輩は猫である。"

tagger = MeCab.Tagger("")
tagger.parse("")

node = tagger.parseToNode(s).next
while node.next:
    print(node.surface, node.feature)
    node = node.next
    
""" =>
吾輩 名詞,代名詞,一般,*,*,*,吾輩,ワガハイ,ワガハイ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
猫 名詞,一般,*,*,*,*,猫,ネコ,ネコ
で 助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ
ある 助動詞,*,*,*,五段・ラ行アル,基本形,ある,アル,アル
。 記号,句点,*,*,*,*,。,。,。
"""

 両方とも消せました。ちょっと変態っぽいけど、これはこれで使えるテクニックのはずです。