1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SudachiPyとN-gram解析で実現する「文章パターン・特定構文」の自動抽出テクニック

1
Posted at

単語単体の頻度カウント(Uni-gram)だけでは、「誤解 + を + 招く」のような特定の言葉の連続(パターン)や構文の特徴を捉えることはできません。

本記事では、SudachiPyで形態素解析を行った後、N-gram(バイグラム/トライグラム)を用いて連続する単語の組み合わせを抽出・集計し、特定の文体や構文パターンを自動抽出するPython実装を解説します。


1. N-gram(エヌグラム)解析とは?

N-gramとは、テキストをN個の単語(または文字)の連なりとして区切る手法です。

  • Uni-gram(1-gram): ["誤解", "を", "招く"]
  • Bi-gram(2-gram): [("誤解", "を"), ("を", "招く")]
  • Tri-gram(3-gram): [("誤解", "を", "招く")]

単語単体ではなく Bi-gram(2連語)Tri-gram(3連語) を解析することで、文章の「言い回し」「決まり文句」「定型フレーズ」を数値データとして捉えられるようになります。


2. 環境構築

必要なパッケージをインストールします。

pip install sudachipy sudachidict_core


3. 実装:SudachiPy × 形態素N-gram抽出パイプライン

テキストから形態素の原形(normalized_form)を取り出し、指定したN(2や3)の単語ペアを抽出する汎用関数を実装します。助詞や記号も含めた「構文パターン」を正確に抽出できます。

from collections import Counter
from sudachipy import dictionary, tokenizer

# 辞書とTokenizerのセットアップ
tokenizer_obj = dictionary.Dictionary().create()


def generate_morpheme_ngrams(
    text: str, n: int = 2, mode=tokenizer.Tokenizer.SplitMode.A
) -> list[tuple[str, ...]]:
    """テキストを形態素解析し、指定されたサイズのN-gram(単語原形のタプル)リストを返します。

    :param text: 解析対象テキスト
    :param n: N-gramのサイズ (2: Bi-gram, 3: Tri-gram)
    :param mode: 分割モード (デフォルト: Mode A)
    :return: N-gramのタプルリスト
    """
    tokens = tokenizer_obj.tokenize(text, mode)

    # 補助記号や改行などのノイズを除去した形態素リストを作成
    cleaned_tokens = [
        t.normalized_form()
        for t in tokens
        if t.part_of_speech()[0] not in ["補助記号", "空白"]
    ]

    # N-gramの生成
    ngrams = [
        tuple(cleaned_tokens[i : i + n])
        for i in range(len(cleaned_tokens) - n + 1)
    ]
    return ngrams


4. 実行例:文章パターンの比較解析

2つの異なる文体のテキスト(謝罪文パターンA・B)から Tri-gram(3連語) を抽出し、出現するフレーズ構造の違いを分析します。

# パターンA:言い訳・定型文が多いテキスト
text_a = """
今回の件につきましては、誤解を招く表現があり、大変不快な思いをさせてしまい誠に申し訳ございませんでした。
今後は誤解を招かないよう、真摯に対応を検討してまいります。
"""

# パターンB:具体的行動を示すテキスト
text_b = """
今回の不祥事につきまして、本日付けでサービスを一時停止いたします。
原因を調査し、再発防止策を策定した上で、来週月曜日に詳細を発表いたします。
"""

# Tri-gram (3-gram) の抽出とカウント
ngrams_a = generate_morpheme_ngrams(text_a, n=3)
ngrams_b = generate_morpheme_ngrams(text_b, n=3)

print("=== パターンA(定型・受動フレーズ)のTOP 3 ===")
for ngram, count in Counter(ngrams_a).most_common(3):
    print(f"{' -> '.join(ngram)} : {count}")

print("\n=== パターンB(具体行動フレーズ)のTOP 3 ===")
for ngram, count in Counter(ngrams_b).most_common(3):
    print(f"{' -> '.join(ngram)} : {count}")

実行結果

=== パターンA(定型・受動フレーズ)のTOP 3 ===
誤解 -> を -> 招く : 2回
を -> 招く -> 表現 : 1回
招く -> 表現 -> が : 1回

=== パターンB(具体行動フレーズ)のTOP 3 ===
サービス -> を -> 一時停止 : 1回
原因 -> を -> 調査 : 1回
再発防止策 -> を -> 策定 : 1回

「誤解 -> を -> 招く」 のような連続した動詞構文パターンが、明確なデータ(出現回数)として捕捉できていることが分かります。


5. 応用:特定品詞ペアのフィルタリング(名詞+動詞など)

N-gramに加えて「品詞フィルタリング」を組み合わせることで、「どんな名詞に対してどんな動詞が使われているか」という「目的語 + 動作」の構文ペアだけを取り出すことも可能です。

def extract_noun_verb_pairs(
    text: str, mode=tokenizer.Tokenizer.SplitMode.A
) -> list[str]:
    """「名詞 + 助詞(を/に/へ) + 動詞」のパターンを抽出します。"""
    tokens = tokenizer_obj.tokenize(text, mode)
    pairs = []

    for i in range(len(tokens) - 2):
        t1, t2, t3 = tokens[i], tokens[i + 1], tokens[i + 2]

        pos1 = t1.part_of_speech()[0]
        pos2 = t2.part_of_speech()[0]
        pos3 = t3.part_of_speech()[0]

        # 「名詞 + 助詞('を') + 動詞」の構造を判定
        if pos1 == "名詞" and pos2 == "助詞" and pos3 == "動詞":
            if t2.surface() in ["", "", ""]:
                pair_str = f"{t1.normalized_form()}{t2.surface()}{t3.normalized_form()}"
                pairs.append(pair_str)

    return pairs


# 実行
pairs = extract_noun_verb_pairs(text_b)
print("=== 抽出された「名詞+助詞+動詞」構造 ===")
print(pairs)
# 出力例: ['サービスを一時停止する', '原因を調査する', '再発防止策を策定する', '詳細を発表する']


6. まとめ

  • 単語単体のカウントでは捉えきれない「言い回し」や「構文」の特徴は、SudachiPy × N-gram解析で効果的に捉えられる。
  • Bi-gram / Tri-gram を使うことで、文章内の定型表現やコロケーション(連語)の抽出が可能。
  • 品詞情報(Part-of-Speech)を掛け合わせることで、「名詞+動詞」のような特定文脈の構文だけをピンポイントでデータ化できる。
1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?