Re Reference AI

技術

N-gramとは

Nグラム

テキストを連続するN個の単語・文字の並びに区切って扱う、統計的言語モデルの基礎となる表現手法

言語処理トークナイゼーション

ひとことで言うと

文章を連続するいくつかの単語や文字のまとまりで区切る、古くからある言語処理の方法。

概要

N-gramとは、テキストを連続するN個の単語(または文字)の並びの単位に区切って扱う手法。 Nが1の場合はUnigram(単語単体)、2の場合はBigram(2語の並び)、3の場合はTrigramと呼ばれる。 直前のN-1個の単語から次の単語の出現確率を推定する統計的言語モデル(N-gramモデル)の基礎単位として使われ、深層学習以前の自然言語処理において、機械翻訳・音声認識・文章生成等で広く用いられていた。 現在のLLMは主にニューラルネットワークベースの言語モデルを用いる一方、テキストの重複検出や簡易な言語モデルの構築等では今もN-gramの利用場面がある。

背景

コンピュータが自然言語のテキストを確率的に扱うには、単語の出現しやすさや並び方の傾向を数値化する必要があった。 N-gramは、直前の少数の単語列から次の単語の出現確率を推定するという単純化によって、統計的に言語をモデル化する手法として発展した。

アーキテクチャ

N-gramモデルは、直前のN-1個の単語が与えられたときの次の単語の出現確率を、学習コーパス中での出現頻度から推定する(マルコフ性の仮定)。 学習データに出現しない単語列には確率0が割り当たってしまう問題(データスパース性)に対応するため、頻度に一定の値を加えるLaplaceスムージングや、より高度なKneser-Neyスムージング等の手法が用いられる。

ワークフロー

テキストをトークン化する → 連続するN個のトークンの出現頻度を数える → 直前のN-1個のトークンを条件とした条件付き確率を計算する(未知の単語列にはLaplaceスムージング等を適用する) → 文全体の確率を各N-gramの条件付き確率の積として求める、または次の単語の予測に使う。

コード例

Pythonで単純なN-gramの頻度を数える

from collections import Counter

def ngrams(tokens, n):
    return [tuple(tokens[i:i + n]) for i in range(len(tokens) - n + 1)]

tokens = ["私", "は", "猫", "が", "好き", "です"]
bigram_counts = Counter(ngrams(tokens, 2))
print(bigram_counts)

利点

  • モデルの構造が単純で、計算コストが低く実装しやすい
  • 深層学習モデルと比べて、学習に必要なデータ量・計算資源が少なくて済む
  • 頻度に基づく確率の意味が直感的に理解しやすく、モデルの挙動を説明しやすい

欠点

  • 直前のN-1個の単語しか参照しないため、より長い文脈の依存関係を捉えられない
  • 学習データに出現しない単語列に対しては確率をうまく推定できない(データスパース性の問題)
  • Nを大きくするほど考慮できる文脈は増えるが、組み合わせが爆発的に増えデータスパース性が悪化する

比較

  • トークナイゼーションN-gramは、トークン化されたテキストを連続するN個の単位に区切って扱う手法
  • LLMN-gramモデルが直前の少数の単語のみを参照するのに対し、LLMはTransformerの自己注意機構により長い文脈全体を考慮できる

関連用語

トークナイゼーションNLPLLM

よくある質問

N-gramは今も使われている?

ニューラルネットワークベースの言語モデルが主流になった現在も、テキストの重複検出や簡易な言語モデル、検索エンジンのインデックス等、軽量さが求められる場面では使われている。

Nの値はどう決める?

Nを大きくすると文脈を考慮しやすくなる一方、データスパース性の悪化というトレードオフを伴う。 扱うデータ量に応じて、Bigram(N=2)やTrigram(N=3)程度がよく使われる。

関連Zenn記事