🐙
代表的な「文章のベクトル化」方法と使い所
代表的な「文章のベクトル化」方法を、超コンパクトにコード付きで解説します。下に行くほど“意味”をうまく捉えます。
⸻
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