LoginSignup
4
5

More than 5 years have passed since last update.

natto-py を通して Python で MeCab 制約付き解析(部分解析)を使う

Posted at

制約付き解析(部分解析)

MeCab の制約付き解析(部分解析)機能は、文の一部の形態素情報が既知である、あるいは境界が分かっている場合に使う機能です。Python と MeCab のバインディングの natto-py は、3つの制約付き解析方法を提供します。

  1. --partial / -p オプション
  2. boundary 制約の指定
  3. feature 制約の指定

--partial オプションで部分解析

MeCab インスタンスを取得するときに --partial または -p オプションを指定します。
parse に渡す入力文は次のようなフォーマットで制約を記述します。

  • 文断片:

    • 文の断片。制約がないときと同じように通常の形態素解析が行われる。ただし文断片をまたぐような 形態素は出力されない。
    • 必ず \n (改行)を末尾に付け加える。
  • 形態素断片

    • フォーマットは 表層\t素性パターン\n
  • 最後に、入力文の末尾に \n を付け加える。

from natto import MeCab

text = """にわ\tほげ
に
はにわ\tほげ
にわとり\tほげ
がいる。
"""

with MeCab("--partial") as nm:
    print(nm.parse(text))

にわ  ほげ
に 助詞,格助詞,一般,*,*,*,に,ニ,ニ
はにわ   ほげ
にわとり    ほげ
が 助詞,格助詞,一般,*,*,*,が,ガ,ガ
いる  動詞,自立,*,*,一段,基本形,いる,イル,イル
。 記号,句点,*,*,*,*,。,。,。
EOS

上記の例は解析結果を標準出力に送りますが、より細かい制約ならば、形態素境界制約指定 (boundary) または品詞制約指定 (feature) の機能を使ってください。

形態素境界制約の指定 (boundary constraints)

単語境界があらかじめ分かっているのであれば boundary_constraints キーワード引数でその境界をコンパイル済みの正規表現または文字列を指定することができます。指定された形態素境界にマッチするものは、一つの形態素として扱って解析するようになります。

text = "にわにはにわにわとりがいる。"

patt = "にわとり|はにわ|にわ"

with MeCab() as nm:
    # 形態素境界制約を指定して、各 MeCabNode 情報を取得する
    for n in nm.parse(text, boundary_constraints=patt, as_nodes=True):
        if not (n.is_bos() or n.is_eos()):
            print("{}:\t{}". format(n.surface, n.feature))

# BOS/EOS ノードは省略する
にわ: 名詞,一般,*,*,*,*,*
に:    助詞,格助詞,一般,*,*,*,に,ニ,ニ
はにわ:  名詞,一般,*,*,*,*,はにわ,ハニワ,ハニワ
にわとり:   名詞,一般,*,*,*,*,にわとり,ニワトリ,ニワトリ
が:    助詞,格助詞,一般,*,*,*,が,ガ,ガ
いる: 動詞,自立,*,*,一段,基本形,いる,イル,イル
。:    記号,句点,*,*,*,*,。,。,。  

詳しくは 6.2. re — 正規表現操作re.finditer を参照してください。

品詞制約の指定 (feature constraints)

feature_constraints キーワード引数により、特定の形態素ごとに品詞分類を指定することができます。形態素に対する品詞をペアとしてもつタプル (tuple) を、それらの形態素・品詞マッピングを更にタプルに格納しておいて、次のように parse メソッドに渡します。

feat = (("にわとり","ほげ"), ("はにわ","ほげほげ"), ("にわ","更にほげ"))

with MeCab() as nm:
    # 一部の形態素に対して品詞制約を指定して、各 MeCabNode 情報を取得する
    for n in nm.parse(text, feature_constraints=feat, as_nodes=True):
        if not (n.is_bos() or n.is_eos()):
            print("{}:\t{}". format(n.surface, n.feature))

# BOS/EOS ノードは省略する
にわ: 更にほげ
に:    助詞,格助詞,一般,*,*,*,に,ニ,ニ
はにわ:  ほげほげ
にわとり:   ほげ
が:    助詞,格助詞,一般,*,*,*,が,ガ,ガ
いる: 動詞,自立,*,*,一段,基本形,いる,イル,イル
。:    記号,句点,*,*,*,*,。,。,。

以上

参照

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5