Bag of Words(BoW)は、自然言語処理(NLP)においてテキストデータを数値ベクトルとして表現するための最も基本的かつ重要な手法の一つです。BoWは、文書中に含まれる単語の出現頻度に基づいて文書を特徴ベクトルに変換します。このシンプルさから、BoWはテキスト分類、情報検索、スパムフィルタリングなど、さまざまな応用分野で広く利用されています。
BoWの主な利点は、実装が容易で、計算コストが低いことです。しかし、単語の順序や文脈が無視されるため、意味的な情報を捉えにくいという欠点もあります。
BoWのプロセス
BoWモデルを作成するプロセスは、以下のステップで構成されます。
1. テキストの前処理
下記のような前処理を実施します。
- トークン化: 文書を単語(トークン)に分割します。
- 不要な文字の除去: 句読点や特殊文字などを取り除きます。
- ステミング/見出し語化: 単語を基本形に変換します(例: "running" -> "run")。
- ストップワードの除去: 一般的に使用される単語("the", "a", "is"など)を除外します。 (必要に応じて)
2. 辞書の作成
すべての文書から抽出されたユニークな単語の集合(語彙)を作成します。
3. ベクトル化
各文書に対して、辞書内の各単語の出現回数をカウントし、数値ベクトルを生成します。
具体例
以下の3つの文書を例にBoWの作成手順を説明します。
- 文書1: "機械学習 は 興味深い 分野 であり 、 機械学習 アルゴリズム は データ に 基づいて 学習 し ます。"
- 文書2: "機械学習 を 使って テキスト 分類 や 予測 を 行い ます。"
- 文書3: "機械学習 の 応用 は 多岐 に わたり ます。"
ステップ1: テキストの前処理 (トークン化後)
- 文書1: [機械学習, は, 興味深い, 分野, であり, 機械学習, アルゴリズム, は, データ, に, 基づいて, 学習, し, ます]
- 文書2: [機械学習, を, 使って, テキスト, 分類, や, 予測, を, 行い, ます]
- 文書3: [機械学習, の, 応用, は, 多岐, に, わたり, ます]
ステップ2: 辞書の作成
上記の文書から作成された辞書(語彙)は以下のようになります。
[機械学習, は, 興味深い, 分野, であり, アルゴリズム, データ, に, 基づいて, 学習, し, ます, を, 使って, テキスト, 分類, や, 予測, 行い, の, 応用, 多岐, わたり]
ステップ3: ベクトル化
各文書を、辞書内の単語の出現頻度に基づくベクトルに変換します。 同じ出現頻度の単語は辞書の順に並べられます。
| 文書 | 機械学習 | は | 興味深い | 分野 | であり | アルゴリズム | データ | に | 基づいて | 学習 | し | ます | を | 使って | テキスト | 分類 | や | 予測 | 行い | の | 応用 | 多岐 | わたり |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 文書1 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 文書2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
| 文書3 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 |
BoWの応用例と他の手法との比較
応用例
- スパムメールフィルタリング: BoWでメールをベクトル化し、「無料」、「当選」などの特定の単語の出現頻度が高いメールをスパムとして分類します。
- 文書分類: ニュース記事をBoWでベクトル化し、スポーツ、政治、経済などのカテゴリに分類します。
- 感情分析: 映画のレビューをBoWでベクトル化し、肯定的なレビューと否定的なレビューに分類します。
他の手法との比較
| 手法 | 特徴 | BoWとの比較 |
|---|---|---|
| TF-IDF | 単語の出現頻度と逆文書頻度(IDF)を組み合わせる | BoWよりも単語の重要度を考慮できる |
| Word2Vec | 単語を分散表現(密なベクトル)に変換する | BoWよりも単語の意味や文脈を捉えられる |
| BERT | Transformerベースの事前学習モデル | 文脈を考慮した高度なテキスト表現が可能。BoWよりもはるかに高い精度が期待できる |
PythonによるBoWの実装
Pythonのscikit-learnライブラリを使用してBoWを実装する例を示します。
from sklearn.feature_extraction.text import CountVectorizer # サンプル文書 documents = [ "機械学習は興味深い分野であり、機械学習アルゴリズムはデータに基づいて学習します。", "機械学習を使ってテキスト分類や予測を行います。", "機械学習の応用は多岐にわたります。" ] # CountVectorizerの初期化 # stop_words: ストップワードのリストを指定 (ここでは日本語のストップワードを使用) # max_features: 使用する特徴量(単語)の最大数を指定 vectorizer = CountVectorizer(stop_words=['は', 'を', 'に', 'や', 'の', 'で', 'し', 'ます', '、', '。', 'て'], max_features=10) # 文書をBoW表現に変換 bow_matrix = vectorizer.fit_transform(documents) # 特徴名(単語)を取得 feature_names = vectorizer.get_feature_names_out() # BoW行列と特徴名(単語)の表示 print("Bag of Words (BoW) 行列:") print(bow_matrix.toarray()) print("\n特徴名:") print(feature_names) # 各行が各文書に対応し、各列が特徴名(単語)に対応します。 # 例えば、bow_matrix[0, 0] は1番目の文書における1番目の単語(ここでは「アルゴリズム」)の出現回数を表します。
N-gramの利用
上記のCountVectorizerは、デフォルトでは1つの単語(1-gram)をトークンとして扱います。ngram_rangeパラメータを指定することで、N-gram(連続するN個の単語の組み合わせ)をトークンとして扱うことができます。
# 2-gram (bigram) を使用する場合 bigram_vectorizer = CountVectorizer(ngram_range=(2, 2)) # 2-gramのみ bow_matrix_bigram = bigram_vectorizer.fit_transform(documents) print("\nBigram Bag of Words (BoW) 行列:") print(bow_matrix_bigram.toarray()) print("\n特徴名(Bigram):") print(bigram_vectorizer.get_feature_names_out())
完成したコード例
from sklearn.feature_extraction.text import CountVectorizer # サンプル文書 documents = [ "機械学習は興味深い分野であり、機械学習アルゴリズムはデータに基づいて学習します。", "機械学習を使ってテキスト分類や予測を行います。", "機械学習の応用は多岐にわたります。" ] # CountVectorizerの初期化 (1-gram, ストップワード除去、最大特徴量数10) vectorizer = CountVectorizer(stop_words=['は', 'を', 'に', 'や', 'の', 'で', 'し', 'ます', '、', '。', 'て'], max_features=10) bow_matrix = vectorizer.fit_transform(documents) feature_names = vectorizer.get_feature_names_out() print("Bag of Words (BoW) 行列 (1-gram):") print(bow_matrix.toarray()) print("\n特徴名 (1-gram):") print(feature_names) # CountVectorizerの初期化 (2-gram) bigram_vectorizer = CountVectorizer(ngram_range=(2, 2)) bow_matrix_bigram = bigram_vectorizer.fit_transform(documents) print("\nBigram Bag of Words (BoW) 行列:") print(bow_matrix_bigram.toarray()) print("\n特徴名 (Bigram):") print(bigram_vectorizer.get_feature_names_out())
まとめ
Bag of Words(BoW)は、テキストデータを数値ベクトルに変換するためのシンプルかつ強力な手法です。BoWは、自然言語処理のさまざまなタスクで広く利用されており、その基礎を理解することは、テキストデータ分析の第一歩として非常に重要です。 BoWは、単語の出現頻度のみを考慮し、文脈や単語の順序は無視するという特徴から限界もあります。より高度なテキスト処理には、TF-IDF、Word2Vec、BERTなどの手法と組み合わせることが有効です。