N-gramの意味とnltkを利用した実装例について

はるか
はるか
N-gramについて…単語や文字列を区切って解析する手法。
ふゅか
ふゅか
N-gramはテキスト解析の基本的な考え方だよね!

1. N-gramとは?

N-gram(エヌグラム)は、テキストやデータの分析で使われる基本的な手法の一つで、連続する単語や文字列を一定の長さに区切ってグループ化する手法を指します。「N」はそのグループ内の要素数を示し、単語や文字の並びを考慮した自然言語処理(NLP)の分野で特によく使われます。

2. N-gramの基本的な考え方

N-gramは、テキストデータを「N個」の連続した要素に分割します。

はるか
はるか
N-gramは、単語や文字を区切って分析する手法。

2.1. 例: 文字単位のN-gram

テキスト:「AIは未来」

  • 1-gram(Uni-gram) 各文字を1つの単位として分割します。 結果: 「A」「I」「は」「未」「来」
  • 2-gram(Bi-gram) 連続する2つの文字を1つの単位とします。 結果: 「AI」「Iは」「は未」「未来」
  • 3-gram(Tri-gram) 連続する3つの文字を1つの単位とします。 結果: 「AIは」「Iは未」「は未来」

2.2. 例: 単語単位のN-gram

テキスト:「AIは未来を変える」

  • 1-gram 各単語を1つの単位とします。 結果: 「AI」「は」「未来」「を」「変える」
  • 2-gram 連続する2つの単語を1つの単位とします。 結果: 「AIは」「は未来」「未来を」「を変える」
  • 3-gram 連続する3つの単語を1つの単位とします。 結果: 「AIは未来」「は未来を」「未来を変える」

3. N-gramの数式

ふゅか
ふゅか
N-gramの数式について教えて!数式とか、ちょっと難しそうに見えるけど…。
はるか
はるか
実は簡単。テキストをトークン化して、連続するN個の要素を取り出すだけ。

3.1. テキストデータのトークン化

テキストデータを次のように定義します。テキストやデータをトークン(単語や文字)に分割したものを

\[ S = \{w_1, w_2, w_3, \dots, w_T\} \]

とします。ここで \(w_i\) は \(i\) 番目のトークン(単語や文字)を表し、\(T\) はトークンの総数です。したがって、$T=|S|$とも書けます。

3.2. N-gramの定義

N-gramは連続する \(N\) 個のトークンを取り出したものです。これを数式で表すと

\[ \text{N-gram} = \{(w_i, w_{i+1}, \dots, w_{i+N-1}) \mid 1 \leq i \leq T - N + 1\} \]

ここで

  • \(N\) はグループ化するトークンの数(例: 2ならBi-gram, 3ならTri-gram)。
  • \(T - N + 1\) はテキスト内のN-gramの総数です。

3.3. 具体例:2-gram(Bi-gram)

テキスト:「AIは未来を変える」をトークン化して次のように表します

\[ S = \{\text{“AI”}, \text{“は”}, \text{“未来”}, \text{“を”}, \text{“変える”}\} \]

2-gram(Bi-gram)は次のように計算されます:

\[ \text{Bi-gram} = \{(w_1, w_2), (w_2, w_3), (w_3, w_4), (w_4, w_5)\} \]

結果は: \[ \{(\text{“AI”}, \text{“は”}), (\text{“は”}, \text{“未来”}), (\text{“未来”}, \text{“を”}), (\text{“を”}, \text{“変える”})\} \]

4. Pythonを利用した実装例

ふゅか
ふゅか
Pythonで実際にN-gramを使ってみたいな!何か便利な方法ってある?
はるか
はるか
nltkライブラリ。簡単に使える。

4.1. nltkライブラリを使用

nltk(Natural Language Toolkit)にはn-gramを簡単に生成するユーティリティが含まれています。

4.2. インストール

まず、nltkをインストールします。

pip install nltk

4.3. 使用例

nltk.utilのngramsを利用することで、n-gramを実装することができます。

from nltk.util import ngrams

# テキストからn-gramを生成
text = "I love Python programming".split()
n = 2  # バイグラム
bigrams = list(ngrams(text, n))
print("Bigrams:", bigrams)  # 出力: [('I', 'love'), ('love', 'Python'), ('Python', 'programming')]

# 文字列のn-gramも同様に生成可能
char_bigrams = list(ngrams("Python", 2))
print("Character Bigrams:", char_bigrams)  # 出力: [('P', 'y'), ('y', 't'), ('t', 'h'), ('h', 'o'), ('o', 'n')]

実際に、動かすと次のようになります。

PR