テキストデータに対する特徴量エンジニアリング(BoW)

目次

はじめに

商品レビューやニュース記事、SNS投稿といったテキストデータを機械学習モデルで使いたい場面はよくあります。しかし、テキストはそのままモデルに渡すことができません。モデルが扱えるのは数値だけなので、文章を数値ベクトルに変換する処理が最初の関門になります。

テキストのベクトル化には、いくつかの代表的な手法があります。

  • ①単語の出現回数(BoW:Bag of Words)
  • ②TF-IDF
  • ③word2vec
  • ④BERT

この記事では、最も基礎的な①BoWに絞って紹介します。

1. BoW:単語の出現回数で文章を数値化する

BoW(Bag of Words)は、文章を「どの単語が何回登場したか」に変換する手法です。単語の順序や文脈は無視して、登場した単語の種類と回数だけを見ます。文章を袋(bag)に放り込んで単語を数えるイメージです。

たとえば、次の3文があったとします。

  • 文書1:「the cat sat on the mat」
  • 文書2:「the dog sat on the mat」
  • 文書3:「the cat and the dog played」

BoWでは、テキスト全体に登場する全単語が列になり、各文書での出現回数が行に並んだ行列を作ります。

scikit-learnの CountVectorizer を使うと、英語テキストはほぼそのままBoWに変換できます。

コード

from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd

texts = [
    "the cat sat on the mat",
    "the dog sat on the mat",
    "the cat and the dog played",
]

vectorizer = CountVectorizer()
X = vectorizer.fit_transform(texts)

df_bow = pd.DataFrame(
    X.toarray(),
    columns=vectorizer.get_feature_names_out(),
    index=["文書1", "文書2", "文書3"],
)

df_bow.head()

出力結果

各行が1文書を表し、値はその単語が登場した回数です。「the」は全文書に2回ずつ登場するため全行が2になっています。「cat」は文書1と文書3に登場しますが文書2には登場しないため、文書2だけが0です。このように、文章の違いが数値の分布として表れているのがわかります。

2. 日本語テキストへの応

英語はスペースで単語が区切られているため、CountVectorizerにそのまま渡せます。一方、日本語はスペースがないので、事前に単語に分解する処理が必要になります。

この処理を「形態素解析」と呼び、分解した単語をスペースでつなげた形式を「分かち書き」と言います。形態素解析ツールとして広く使われているのが MeCab で、-Owakati オプションを指定することでスペース区切りの分かち書きが直接得られます。

以下のコードでは、MeCabで形態素解析・分かち書きを行い、その結果をそのままCountVectorizerに渡してBoWに変換するまでを一括で処理しています。

コード

!pip install mecab-python3 unidic-lite -q

import MeCab
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd

wakati = MeCab.Tagger("-Owakati")

texts_ja = [
    "今日の天気はとても良い",
    "明日は大雨が降るかもしれない",
    "今日は傘を持って外に出かけた",
]

# 形態素解析・分かち書き
tokenized = [wakati.parse(t).strip() for t in texts_ja]

# BoWベクトル化
vectorizer_ja = CountVectorizer()
X_ja = vectorizer_ja.fit_transform(tokenized)

df_ja = pd.DataFrame(
    X_ja.toarray(),
    columns=vectorizer_ja.get_feature_names_out(),
    index=["文書1", "文書2", "文書3"],
)

df_ja.head()

出力結果

(MeCabの辞書や実行環境によって抽出される語や列の順番が変わる場合があります。なお、CountVectorizerのデフォルト設定では1文字のトークンは除外されるため、「の」「は」「が」などの助詞は自動的に取り除かれています。)

「今日」は文書1と文書3に登場するため、この2行が1になっています。「明日」は文書2にしか登場しないため、文書2だけが1です。このように、形態素解析からBoW化まで一連の流れで日本語テキストを数値に変換できます。

まとめ

この記事では、テキストデータの特徴量エンジニアリングの基本として、BoWを紹介しました。

  • テキストはそのままモデルに渡せないため、数値ベクトルへの変換が必要
  • BoWは各単語の出現回数を特徴量とするシンプルな手法で、scikit-learnの CountVectorizer で実装できる
  • 日本語の場合はMeCabで形態素解析・分かち書きを行ってからCountVectorizerに渡す

BoWはシンプルな分、語順を考慮しないなどの限界もあります。他の手法も気になった方はぜひ調べてみてください。

CTA
  • URLをコピーしました!
  • URLをコピーしました!
この記事を書いた人
目次