本稿は Embedding(埋め込み) に関する記事です。
| この記事の要点 |
- Embedding は単語・文・画像・コードなどを「意味を保ったベクトル」に変換したもの
- 距離が近いベクトル = 意味が近い、というルールが学習される
- 用途: 類似検索 / レコメンド / クラスタリング / RAG / クラス分類
- 典型次元: 256〜3072 次元(モデル依存)
- 主要モデル: OpenAI text-embedding-3 / Cohere Embed / BGE / E5(OSS)
- 類似度: コサイン類似度が定番。距離は内積 / L2 も用途次第
- 保存先: ベクトルDB(Chroma / pgvector / Pinecone / Qdrant / Faiss)
|
Embedding とは?
Embedding(埋め込み / ベクトル化) は、テキスト・画像・音声・コードといった離散的・記号的なデータを、固定長の高次元ベクトルに変換する技術です。重要なのは「意味が近いものは近くに、遠いものは遠くに」並ぶよう学習されている点で、これにより意味検索や類似度に基づくレコメンドが可能になります。
近年は RAG(検索拡張生成) の必須部品として注目され、社内ナレッジ検索・FAQ ボット・コード検索などの実装で広く使われています。
身近な直感
| 補足: 「王様 - 男 + 女 ≒ 女王」 |
Word2Vec で有名になった例ですが、単語をベクトル化すると意味の演算がベクトル演算で近似できます: vec("king") - vec("man") + vec("woman") ≒ vec("queen")
これは「ジェンダー」という意味成分がベクトルの 1 方向に表現されている、ということです。現代の Embedding ではより複雑な意味関係が高次元空間で表現されています。 |
Embedding の歴史
| 時代 | 手法 |
| 2013 | Word2Vec(Mikolov)— 単語埋め込みの普及 |
| 2014 | GloVe — 共起統計ベース |
| 2017〜 | Transformer ベース(BERT 等)で文脈付き埋め込みへ |
| 2019〜 | Sentence-BERT — 文単位の Embedding |
| 2022〜 | OpenAI text-embedding、Cohere、BGE 等の高品質 API / OSS |
| 現在 | マルチモーダル Embedding(CLIP、Jina、SigLIP)、長文対応、コード特化 |
主要な Embedding モデル
| モデル | 提供 | 特徴 |
| OpenAI text-embedding-3-small / large | API | 性能・コストバランス◎。3072 次元(large) |
| Cohere Embed v3 | API | 多言語・RAG 特化 |
| Voyage AI | API | コード・ドメイン特化版が豊富 |
| Google Gecko | Vertex AI | Google エコシステム統合 |
| BGE (BAAI) | OSS | ローカル実行可・高性能。中国発 |
| E5 (Microsoft) | OSS | 多言語・軽量 |
| Jina Embeddings v3 | OSS / API | マルチモーダル・長コンテキスト |
| nomic-embed-text | OSS | 軽量・公開重み |
| Sentence-Transformers | OSS | 多数の事前学習済みモデル |
| CLIP / SigLIP | OSS | 画像 + テキストのマルチモーダル |
類似度の計算
| 距離 / 類似度 | 特徴 | いつ使う |
| コサイン類似度 | ベクトル方向の類似(-1〜1) | RAG・意味検索の定番 |
| 内積 | 方向 + ノルム | 正規化済みベクトルではコサインと等価 |
| L2 距離(ユークリッド) | 絶対距離 | 近傍探索の数学的基本 |
最小サンプル: 類似検索
|
from openai import OpenAI
import numpy as np
client = OpenAI()
def embed(texts):
res = client.embeddings.create(model="text-embedding-3-small", input=texts)
return np.array([d.embedding for d in res.data])
docs = [
"PyTorch はディープラーニングのフレームワーク",
"バナナは黄色い果物",
"TensorFlow も DL ライブラリ",
]
doc_vecs = embed(docs)
query_vec = embed(["機械学習のライブラリは?"])[0]
# コサイン類似度
def cos(a, b): return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
for i, dv in enumerate(doc_vecs):
print(f"{cos(query_vec, dv):.3f} | {docs[i]}")
|
RAG での使われ方
| ステップ | 内容 |
| 1. 文書を分割 | 500〜1000 文字程度のチャンクに分ける |
| 2. Embedding 生成 | 各チャンクをベクトル化 |
| 3. ベクトルDB に保存 | Chroma / pgvector / Pinecone 等 |
| 4. 質問の Embedding | ユーザ質問もベクトル化 |
| 5. 類似検索 | 近傍 k 件のチャンクを取得 |
| 6. LLM に渡す | 取得チャンクをプロンプトの参考情報として連結 |
| 7. 回答生成 | LLM が情報源を踏まえて回答 |
保存先(ベクトルDB)の選択
| DB | 特徴 |
| Chroma | ローカル動作。プロト・小規模に最適 |
| Faiss | Meta 製。ライブラリとして高速 |
| pgvector | PostgreSQL 拡張。既存 RDBMS 活用 |
| Pinecone | マネージド SaaS。本番運用容易 |
| Qdrant | OSS + マネージド。フィルタ機能豊富 |
| Weaviate | OSS + マネージド。スキーマ駆動 |
| Milvus / Zilliz | 大規模分散 |
| OpenSearch / Elasticsearch | 既存検索基盤に Embedding 追加 |
運用上のヒント
| Tips |
- 同一モデル・同一バージョンで生成した Embedding 同士でしか比較できない。途中でモデルを変えると全件再生成
- 類似度しきい値はデータセットごとに実測して決める(0.7 が常に良い等はない)
- RAG の検索品質はチャンク分割が支配的。サイズ・重複・分割単位を試行錯誤
- 多言語データを扱うなら多言語対応モデル(multilingual-e5、bge-multilingual)
- OpenAI Embedding は長さに料金が比例。トークン数を見積もる
- 機密データはローカル埋め込み(BGE / nomic)でクラウド送信を避ける
- 精度向上には再ランク(Reranker)を後段で入れる
|
注意点
| よくある落とし穴 |
- 類似 ≠ 答え: 似ていてもユーザの意図と違うチャンクが返ることがある
- 意味検索だけだと弱い: 固有名詞・型番は BM25 などのキーワード検索とハイブリッドが強い
- Embedding の偏り: 学習データの偏りで特定話題で性能が落ちる
- 次元呪い: 高次元ほど距離が均一化しやすい。再ランクで補強
- 長文を 1 ベクトルに: 重要情報が薄まる。チャンク分割が基本
- 料金・遅延: 大量埋め込みは時間とコストがかかる。バッチで実行
|
関連