コンピュータが人間の言葉(自然言語)を理解する「自然言語処理(NLP)」という技術が、私たちの身の回りでたくさん使われています。その中でも、最も基本的で重要な技術の一つが「Bag-of-Words(バッグ・オブ・ワーズ)」、略してBoWです。
この記事では、自然言語処理の初心者の方でも理解できるように、BoWの仕組みからメリット・デメリット、そして実際の活用例までを丁寧に解説していきます。
Bag-of-Words(BoW)とは?
Bag-of-Words(BoW)とは、文章を分析するために、その文章に含まれる単語の出現回数を数えて数値のベクトル(数字の列)に変換する手法です。 「単語の袋」という名前の通り、文章中に出てくる単語を順番を気にせず、すべて一つの袋(Bag)にごちゃまぜに入れ、どの単語が何回出てきたかを数える、というイメージです。
コンピュータは「猫は可愛い」といった文章をそのままでは理解できません。しかし、BoWを使って文章を数値の集まりに変換することで、機械学習モデルがデータを処理できるようになります。 これは、テキストデータを分析する上での非常に重要な前処理ステップです。
BoWの仕組み
BoWは、以下の3つのステップで文章をベクトルに変換します。
- トークン化(Tokenization): 文章を単語ごとに区切ります。日本語の場合は、英語のようにスペースで単語が区切られていないため、「形態素解析」という技術を使って単語に分割します。
- 語彙(Vocabulary)の作成: 分析したい全ての文章から、登場する単語をすべて集めて重複を除いた「単語の辞書(語彙)」を作成します。
- ベクトル化(Vectorization): 各文章について、作成した語彙の中の単語がそれぞれ何回出現するかを数え、その回数を並べたベクトルを作成します。
具体例で見てみよう
以下の2つの短い文章をBoWでベクトル化してみましょう。
- 文章A: 「私は猫が好きです」
- 文章B: 「私は犬が好きです 猫も好きです」
Step 1 & 2: トークン化と語彙の作成
まず、文章を単語に分け、すべての文章から語彙を作成します。
語彙: {私, は, 猫, が, 好き, です, 犬, も}
Step 3: ベクトル化
次に、各文章が語彙の単語をそれぞれ何回含んでいるかを数えます。
単語 | 私 | は | 猫 | が | 好き | です | 犬 | も |
---|---|---|---|---|---|---|---|---|
文章Aのベクトル | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 0 |
文章Bのベクトル | 1 | 0 | 1 | 0 | 2 | 2 | 1 | 1 |
このようにして、文章を数値の列(ベクトル)に変換することができました。
Pythonでの実装例 (scikit-learn)
Pythonの機械学習ライブラリ`scikit-learn`にある`CountVectorizer`を使うと、BoWを簡単に実装できます。
from sklearn.feature_extraction.text import CountVectorizer
# 日本語の文章は、事前に形態素解析して単語をスペースで区切っておく必要があります。
# ここでは、簡単化のため、すでに分かち書きされているとします。
documents = [
"私 は 猫 が 好き です",
"私 は 犬 も 好き です が 、 猫 は もっと 好き です"
]
# CountVectorizerのオブジェクトを作成
vectorizer = CountVectorizer()
# 文章をBoW表現に変換
bow_matrix = vectorizer.fit_transform(documents)
# 作成された語彙(単語とインデックス)
print("語彙(Vocabulary):")
print(vectorizer.vocabulary_)
# BoW表現(スパース行列)を配列に変換して表示
print("\nBoW行列:")
print(bow_matrix.toarray())
BoWのメリットとデメリット
メリット
- シンプルで直感的: 仕組みが非常に分かりやすく、実装も簡単です。
- 計算が速い: 単純なカウント処理なので、大量の文書データも高速に処理できます。
- 汎用性が高い: 文書分類、感情分析など、多くの自然言語処理タスクの基礎として利用できます。
デメリット
- 単語の順序を無視する: 「犬が猫を追いかけた」と「猫が犬を追いかけた」は、BoWでは同じように扱われてしまい、文脈が失われます。
- 単語の重要度が考慮されない: 「です」「ます」のような頻出するが重要度の低い単語も、専門用語のような重要な単語も同じ1回としてカウントされます。
- 未知語に弱い: 語彙の作成時に存在しなかった新しい単語(未知語)が現れると、うまく処理できません。
BoWの応用例と発展
主な応用例
BoWはそのシンプルさから、様々なタスクに応用されています。
- 文書分類: ニュース記事を「スポーツ」「経済」「国際」などのカテゴリに自動で分類したり、メールが「スパム」か「非スパム」かを判定したりします。
- 感情分析(センチメント分析): 商品レビューやSNSの投稿が「ポジティブ」か「ネガティブ」かを分析します。
- 情報検索: 検索エンジンが、検索クエリと関連性の高い文書を見つけるために利用します。
BoWの発展形
BoWのデメリットを補うために、いくつかの発展的な手法が考案されています。
- TF-IDF: BoWの「単語の重要度を考慮できない」という欠点を改善した手法です。 TF-IDFは、文書内で頻繁に出現するが、他の多くの文書にはあまり出現しない単語の重要度を高く評価します。 これにより、単なる出現回数よりも的確に単語の重要性を捉えることができます。
- n-gram (Bag-of-n-Grams): BoWが単語の順序を無視する点を部分的に補う手法です。 例えば「2-gram (bigram)」では、「私 は」「は 猫」のように隣接する2つの単語を1セットとして扱います。 これにより、「New York」のような複合語を一つの単位として認識したり、単語の並びに関する情報を少し保持したりできます。
まとめ
Bag-of-Words(BoW)は、文章を単語の出現頻度という観点から数値ベクトルに変換する、シンプルかつ強力な手法です。単語の順序を無視するといった欠点はあるものの、その分かりやすさと実装の容易さから、今でも多くの自然言語処理タスクの基礎として利用されています。
BoWを理解することは、TF-IDFやWord2Vecといったより高度な技術を学ぶ上での重要な第一歩となります。この機会に、ぜひ自然言語処理の世界に触れてみてください。