🐙

代表的な「文章のベクトル化」方法と使い所

に公開

代表的な「文章のベクトル化」方法を、超コンパクトにコード付きで解説します。下に行くほど“意味”をうまく捉えます。

0) データ準備(共通)

docs = [
    "私はラーメンが好きです。",
    "彼はつけ麺が大好物だ。",
    "今日は寿司を食べに行く予定です。"
]

1) Bag of Words(単語出現数)

単語ごとの出現回数を次元にする基本形。簡単・高速。ただし語順や文脈は無視。

from sklearn.feature_extraction.text import CountVectorizer

vec = CountVectorizer()  # 日本語は形態素分かち書き前提だが、まずは雰囲気用
X = vec.fit_transform(docs)  # Xは(文書数×語彙数)の疎行列

print(vec.get_feature_names_out()[:10])  # 語彙の例
print(X.toarray()) # カウントベクトル

使いどころ:特徴量の基礎・ルールベースの分類器・軽量なベースライン。

2) TF-IDF(重要度で重み付け)

頻出しすぎる語の重みを下げ、各文書で特徴的な語を持ち上げます。

from sklearn.feature_extraction.text import TfidfVectorizer

tfidf = TfidfVectorizer()
X = tfidf.fit_transform(docs)

print(tfidf.get_feature_names_out()[:10])
print(X.toarray())  # 値は0〜1付近の実数(重み)

使いどころ:類似検索・クラスタリングのベースラインに強い。

3) 文章ベクトル(Sentence Embedding:推奨)

意味を捉える高次元ベクトル。日本語含む多言語対応モデルでOK。
※ 初回はモデルを自動ダウンロードします。

#pip install sentence-transformers  が必要
from sentence_transformers import SentenceTransformer
from sklearn.metrics.pairwise import cosine_similarity

model = SentenceTransformer("sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
emb = model.encode(docs, convert_to_numpy=True)  # shape: (3, 384) など

# 類似度(コサイン類似度)
sim = cosine_similarity(emb)
print(sim)  # [0,1]に近いほど似ている

使いどころ:意味ベースの検索(RAG)、重複検出、要約・FAQマッチングなど。

4) 日本語の分かち書き+TF-IDF(精度↑)

日本語は形態素解析で単語に切ると精度が上がります。例:Janome/MeCab/Sudachiなど。

#pip install janome
from janome.tokenizer import Tokenizer
from sklearn.feature_extraction.text import TfidfVectorizer

t = Tokenizer()

def tokenize_ja(text):
    return [token.surface for token in t.tokenize(text) if token.part_of_speech.split(',')[0] in ("名詞","動詞","形容詞")]

tfidf = TfidfVectorizer(tokenizer=tokenize_ja)
X = tfidf.fit_transform(docs)
print(tfidf.get_feature_names_out()[:20])
print(X.toarray())

5) 実用の型:類似検索(TF-IDF or 埋め込み)

import numpy as np
from sklearn.metrics.pairwise import cosine_similarity

query = "ラーメンを食べたい"
# ① TF-IDFでやるなら:tfidf.fit(docs) 済みとして
q_vec = tfidf.transform([query])
scores = cosine_similarity(q_vec, X).ravel()
print(np.argsort(-scores), scores[np.argsort(-scores)])

# ② 埋め込みでやるなら:model.encode 済みとして
q_emb = model.encode([query], convert_to_numpy=True)
scores = cosine_similarity(q_emb, emb).ravel()
print(np.argsort(-scores), scores[np.argsort(-scores)])

どれを使う?

  • 速く・軽く:CountVectorizer / TF-IDF
  • “意味”で探したい・RAG:SentenceTransformer(多言語MiniLMなど)
  • 日本語の精度を上げたい:分かち書き+TF-IDF or 日本語対応埋め込み

Discussion