📝

MeCabで半角スペースを解析に含める (CLI, mecabrc, fugashi)

2022/03/08に公開

概要

MeCabは、日本語の自然言語処理で広く用いられている形態素解析器です。

さて、MeCabでは下記のように半角スペースが含まれている文字列を解析する場合、半角スペースで分かち書きされます。英語は基本的に半角スペース区切りですので、日本語を含む文においても区切り位置として自然です。ただし、デフォルトの状態では、区切り文字として利用されたスペースは解析結果には含まれません。そのため、分かち書きした後の情報のみを使って元の文を復元したり、形態素の情報を使って元の文を書き換えようとすると、意図せず元の文字列中の半角スペースが消えてしまうことがあります。すなわちPart of Speechを形態素解析した後に元に復元しようとすると、PartofSpeechとなってしまうということです。

$ mecab
Part of Speech
Part    名詞,固有名詞,組織,*,*,*,*
of      名詞,一般,*,*,*,*,*
Speech  名詞,固有名詞,組織,*,*,*,*
EOS

そこで、MeCabによる形態素解析結果から元の文を再構成できるように、半角スペースを解析に含める方法を紹介します。

MeCabの出力フォーマットを変更する

各単語の文字列(表層文字列)にスペースを含めるように出力フォーマットを変更します。%Mを利用することで、空白文字も含めることが可能です(参考)。この際、スペースは次の単語の前に付与されます。

CLI

コマンドラインからは、--node-format--unk-formatのオプションに出力フォーマットを記述します。

$ mecab --node-format="%M\t%H\n" --unk-format="%M\t%H\n"
Part of Speech
Part    名詞,固有名詞,組織,*,*,*,*
 of     名詞,一般,*,*,*,*,*
 Speech 名詞,固有名詞,組織,*,*,*,*

mecabrc

mecabrcに記述することも可能です。記法はCLIの場合と同様ですが、mecabrcに記述する場合は-KEYというsuffixを付与し、コマンドラインから-Oオプションで指定する形で実現します。ここではspaceという名前のsuffixを用いています。

mecabrc
node-format-space = %M\t%H\n
unk-format-space = %M\t%H\n
$ mecab -r mecabrc -Ospace
Part of Speech
Part    名詞,固有名詞,組織,*,*,*,*
 of     名詞,一般,*,*,*,*,*
 Speech 名詞,固有名詞,組織,*,*,*,*

fugashiを利用する

fugashiはPythonのMeCabラッパーで、PythonのコードからMeCabを容易に利用できるようにするパッケージです。

fugashiの形態素解析結果のNodeクラスにはwhite_spaceというプロパティがあり、ここに半角スペースが含まれていたかの情報が含まれています。

In []: import fugashi

In []: tagger = fugashi.GenericTagger("-r /etc/mecabrc")

In []: for word in tagger("Part of Speech"):
   ...:     print(word.surface, word.white_space == " ")
Part False
of True
Speech True

この情報を使うことで、簡単に元の文が復元できます。

In []: "".join([w.surface for w in tagger("Part of speech")])
Out[]: 'partofspeech'

In []: "".join([w.white_space + w.surface for w in tagger("Part of speech")])
Out[]: 'part of speech'

# 複数の半角スペースが含まれる場合も可能
In [26]: "".join([w.white_space + w.surface for w in tagger("Part   of   speech")])
Out[26]: 'Part   of   speech'

追記

fugashi作者の方から補足情報を頂きました。\n\tも半角スペース扱いになるようです。

https://twitter.com/polm23/status/1501058672591441920

参考

Discussion