RAGやセマンティック検索の話題になると必ず登場するのが「エンベディング」という言葉です。エンベディングはテキストや画像を意味を保持したまま数値ベクトルに変換する技術であり、LLMアプリケーションにおける「意味理解」の基盤インフラとして機能しています。本記事では、エンベディングの定義と仕組み、主要モデルの比較、そして実務での活用シーンまでを、実装コードを交えて解説します。
エンベディングとは何か――テキストを「数値」に変換する技術
エンベディングとは、テキスト(あるいは画像・音声・動画)を、意味を保持した数値ベクトルに変換する技術のことです。変換後のベクトルは数百〜数千次元の数値配列となり、意味的に近い文書同士はベクトル空間上でも近い位置に配置されます。
エンベディングの威力を示す有名な例が「King – Man + Woman = Queen」です。単語を数値化した後に足し算や引き算ができ、その結果が意味的に妥当になるという驚くべき性質です。これは、エンベディングが単なる符号化ではなく、意味の構造そのものを捉えていることを示しています。
【エンベディングの概念】
テキスト ベクトル空間(2次元で視覚化)
「犬が好きです」 ----> * --- * 「猫が好きです」
|
「ワンちゃんが可愛い」 ----> *
* 「ペットを飼っています」
「機械学習の論文」 ----> 遠く離れた場所に配置
*
* 「深層学習の研究」
※実際は1536次元や3072次元といった高次元空間だが、
類似文書同士の距離が近くなる性質は同じ。
エンベディングの仕組み――どうやってベクトルを生成するか
現代のエンベディングモデルは、ほぼすべてがTransformerベースです。入力テキストをトークン化し、Transformerで処理した後、文全体を代表する固定長のベクトルを出力する構造になっています。次元数はモデルによって異なり、OpenAIのtext-embedding-3-smallは1536次元、text-embedding-3-largeは3072次元です。次元数が大きいほど表現力は高いものの、ストレージと計算コストも増加します。
from openai import OpenAI
client = OpenAI()
def embed(text: str) -> list[float]:
response = client.embeddings.create(
model="text-embedding-3-small",
input=text,
)
return response.data[0].embedding
vec = embed("データ基盤の構築について教えてください")
print(f"次元数: {len(vec)}")
print(f"先頭5要素: {vec[:5]}")
2つのベクトル間の類似度はコサイン類似度(角度による近さ)で計算するのが一般的です。1.0に近いほど意味的に類似、0に近いほど無関係、-1に近いほど反対の意味になります。
import numpy as np
def cosine_similarity(v1: list[float], v2: list[float]) -> float:
a, b = np.array(v1), np.array(v2)
return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b)))
text_a = "犬はかわいい動物です"
text_b = "犬は愛らしいペットです"
text_c = "量子コンピュータの研究"
print(cosine_similarity(embed(text_a), embed(text_b))) # 約0.9 (類似)
print(cosine_similarity(embed(text_a), embed(text_c))) # 約0.3 (無関係)
主要エンベディングモデルの比較
エンベディングモデル選定では、日本語対応、次元数、最大入力トークン、コスト、ベンチマークスコア(MTEB等)の5軸で評価するのが実務的です。OSSで自社運用する選択肢とAPI利用の選択肢があり、データ規模と運用体制で使い分けます。
| モデル名 | 提供元 | 次元数 | 最大入力トークン | 日本語対応 | コスト | ベンチマーク |
|---|---|---|---|---|---|---|
| text-embedding-3-small | OpenAI | 1536 | 8,191 | 対応 | 約 0.02 USD / 1Mトークン | 高 |
| text-embedding-3-large | OpenAI | 3072 | 8,191 | 対応 | 約 0.13 USD / 1Mトークン | 非常に高い |
| embed-multilingual-v3 | Cohere | 1024 | 512 | 対応 | 約 0.10 USD / 1Mトークン | 高 |
| multilingual-e5-large | OSS | 1024 | 512 | 対応 | 自社運用のみ | 高 |
| BGE-M3 | BAAI (OSS) | 1024 | 8,192 | 対応 | 自社運用のみ | 非常に高い |
| Sentence-Transformers | OSS | 384〜768 | 256〜512 | 限定的 | 自社運用のみ | 中 |
エンベディングの5つの活用シーン
エンベディングの活用範囲は想像以上に広く、以下の5つが実務で頻出するパターンです。
- セマンティック検索――キーワードの完全一致ではなく、意味で検索する仕組みです。「返品したい」という検索クエリに対して「キャンセル方法」の文書をヒットさせることができます。
- RAG(検索拡張生成)――社内ドキュメントをエンベディング化してベクトルDBに保存し、質問時に意味的に近い文書を取得してLLMに渡す仕組みです。社内知識を活かしたLLM回答の基盤となります。
- テキスト分類――あらかじめ各カテゴリの代表ベクトルを作成し、新しいテキストをコサイン類似度で分類する手法です。学習不要で高精度です。
- クラスタリング――大量の文書を意味的に似たグループに自動分割します。問い合わせログの分析や顧客の声のトピック抽出に有効です。
- レコメンデーション――ユーザーが閲覧した商品や記事のベクトルと類似する商品を推薦します。コールドスタート問題にも強い特性があります。
| 活用シーン | 入力 | 出力 | 精度の鍵 | 実装難易度 |
|---|---|---|---|---|
| セマンティック検索 | クエリ+文書群 | 類似文書リスト | チャンクサイズ | 中 |
| RAG | 質問+知識ベース | 根拠付き回答 | 検索精度と再順位付け | 中〜高 |
| テキスト分類 | 文書 | カテゴリ | カテゴリ代表の質 | 低 |
| クラスタリング | 文書群 | グループ | クラスタ数の設定 | 中 |
| レコメンド | ユーザー履歴 | 推薦候補 | コールド対応 | 中 |
エンベディングの注意点とベストプラクティス
エンベディングを実運用で使う際の落とし穴をいくつか挙げます。第一がモデル変更時の再インデックスです。エンベディングモデルはそれぞれ独自のベクトル空間を持つため、モデルを変更したら過去の全文書を再度ベクトル化する必要があります。数千万件規模のデータベースでは、この移行作業が数日〜数週間かかります。
第二が長文テキストの扱いです。多くのモデルには最大入力トークンの制約があり、長文はチャンクに分割する必要があります。チャンクサイズの設計(長すぎると内容が希釈、短すぎると文脈が切れる)は検索精度に直結する重要な設計判断です。第三が多言語対応で、日本語と英語が混在する文書ではモデルによって精度が大きく変動します。
まとめ――エンベディングはAI活用の「基盤インフラ」
- エンベディングはテキストを意味を保持した数値ベクトルに変換する技術
- Transformerベースのモデルが主流で、次元数と対応言語で選定する
- セマンティック検索・RAG・分類・クラスタリング・レコメンドに応用できる
- 運用ではモデル変更時の再インデックスとチャンキング設計が鍵となる
DE-STKでは、エンベディング戦略の設計、モデル選定、RAG構築、そして既存検索システムのセマンティック化まで幅広く支援しています。社内検索精度の向上やLLMアプリの精度改善をご検討の方は、お気軽にご相談ください。
よくある質問
Q. エンベディングとは何ですか?
テキストや画像などのデータを、意味を保持した数値ベクトル(数百〜数千次元の数値配列)に変換する技術です。意味的に近いテキスト同士はベクトル空間上でも近くに配置されるため、類似度検索や分類に活用できます。
Q. エンベディングはどのような場面で使われますか?
RAG(検索拡張生成)での文書検索、セマンティック検索、テキスト分類、文書クラスタリング、レコメンデーションなど幅広い場面で使われています。LLMアプリケーションにおける「意味の理解」の基盤技術です。
Q. エンベディングモデルの選び方は?
日本語対応の有無、次元数(検索精度とストレージのトレードオフ)、最大入力トークン数、コスト、ベンチマークスコアの5軸で評価します。OSS(Sentence-Transformers等)とAPI(OpenAI、Cohere)の選択も重要な判断ポイントです。