シナプス技術者ブログ

シナプスの技術者公式ブログ。インターネットで、鹿児島の毎日を笑顔にします。

テキストエンベディング再入門

シナプスの技術部システム開発課の小園です。

これまで感覚的に用いることの多かったテキストエンベディングについて、その仕組みと活用法を深く掘り下げてみました。
当初は「似た文章をベクトルで探す仕組み」という程度の認識でしたが、学習を進めるうちにその奥深さに触れる良い機会となりました。

テキストエンベディングとは?

テキストエンベディングとは、ひと言で言えば「言葉をコンピュータが計算できる数値(ベクトル)に変換する技術」です。人間が使う言葉(非構造化データ)を、意味の関連性を保ったまま多次元空間上の座標(ベクトル)に変換することで、コンピュータによる意味の比較や計算を可能にします。
変換されたベクトルは、単なる数値の羅列ではありません。最大の特徴は、元の言葉が持つ意味的な関連性を、ベクトル空間上での向きや距離として保持する点にあります。

ベクトルデータの特徴

  • 意味が近いデータ(例:「猫」と「犬」)は、互いに近い場所に配置されます。
  • 意味が遠いデータ(例:「猫」と「AI」)は、離れた場所に配置されます。
  • 「東京」 - 「日本」 + 「フランス」 = 「パリ」のような、意味の足し算・引き算が可能になります。
    • 実際には「パリ」に近いベクトルの近似値が得られます。
    • この現象は古典的な静的埋め込みで顕著に観察され、近年の文脈化埋め込みでは必ずしも再現されません。

テキストエンベディングのモデル

テキストエンベディングのモデルは、大きく「静的埋め込み」と「文脈化埋め込み」に分類されます。

  • 静的埋め込み (Static Embeddings)
    • 特徴: 個々の単語に固定された一つのベクトルを割り当てます。(例: Word2Vec, GloVe, fastText)
    • 長所/短所: 軽量で高速に動作しますが、文脈による意味の違い(多義性)を捉えることはできません。
  • 文脈化埋め込み (Contextualized Embeddings)
    • 特徴: 文章全体の文脈を理解し、その文脈に応じたベクトルを生成します。
    • 長所/短所: 高精度で文脈を捉えられますが、計算コストが高くなります。現在のLLM関連技術の主流はこちらです。

なお、エンベディングの次元数は一般に数百〜数千です。

テキストの「近さ」はどう測る?

ベクトル化されたテキスト同士が「どのくらい意味が似ているか」を判断するには、コサイン類似度(Cosine Similarity)という指標がよく用いられます。
これは、2つのベクトルがなす角度に着目し、その向きがどれだけ似ているかを測るものです。

なぜ「距離(ユークリッド距離)」ではなく「角度(コサイン類似度)」なのか?

「なぜ単純な2点間の距離(ユークリッド距離)を使わないのか?」という疑問が浮かぶかもしれません。その答えは、文章の長さに影響されにくいためです。

以下の2つの文章を考えてみてください。

  • A: 「猫が好き」
  • B: 「私は、本当に本当に猫が大好きです」

これら2つの文章は、伝えたい本質(意味の方向性)は同じです。しかし、単語数が異なるため、各単語のベクトルを単純に合算した場合、文章Bのベクトルの方が長くなります。その結果、終点間のユークリッド距離を計測すると、2つの文章の距離は遠くなり、「意味は似ているのに、似ていない」と誤って判断される可能性があります。

一方、コサイン類似度はベクトルの「向き」だけに着目するため、ベクトルの「長さ(大きさ)」が異なっていても、向きが似ていれば類似度が高いと判断できます。これにより、表現の冗長性に左右されず、本質的な意味の近さを捉えることが可能になるのです。

補足: 実務では用途やモデルの正規化の有無に応じて、内積(dot product)やユークリッド距離(L2)を用います。モデルやライブラリによっては、すでに単位ベクトルへ正規化されている場合もあります。

テキストエンベディングは何に使える?

テキストエンベディングは、現代のAIアプリケーションの様々な場面で活用されています。

代表例: RAG (Retrieval Augmented Generation)
現在最も注目されている応用例がRAGです。これは、LLMに外部の知識データベースを参照させることで、より正確で最新の情報に基づいた回答を生成させる技術であり、その裏側でテキストエンベディングが中心的な役割を果たしています。

  • 事前準備: 社内ドキュメントなどの知識源を、段落や数文ごとのまとまり(チャンク)に分割し、それぞれをエンベディング化してベクトルデータベースに保存します。
  • 実行時: ユーザーからの質問(クエリ)も同様にエンベディング化します。
  • 検索(Retrieval): 質問ベクトルとデータベースに保存されている文書ベクトルとの間でコサイン類似度を計算し、最も関連性の高い文書チャンクを複数検索します。
  • 生成(Generation): 検索した文書チャンクをコンテキスト情報としてプロンプトに含め、「この情報に基づいて回答してください」とLLMに指示し、最終的な回答を生成させます。

この仕組みにより、LLMが元々学習していない社内情報や最新情報についても、正確な回答を生成できるようになります。

補足: RAGではモデルごとにスコア分布が異なるため、類似度の閾値や上位k件の件数はモデル別にキャリブレーション(調整)するのが実務的です。

その他の応用例

  • セマンティック検索: 単なるキーワードの一致ではなく、ユーザーの検索意図やクエリの「意味」を理解して検索結果を返します。「コスパの良いノートPC」と検索した際に、「安くて高性能なラップトップのおすすめ」という記事がヒットするのはこの技術によるものです。
  • クラスタリング: 大量のテキストデータを、意味の類似性に基づいて自動的にグループ分けします。顧客からの問い合わせ内容の分類や、ニュース記事のトピック分類などに活用されます。
  • レコメンデーション: ユーザーが過去に閲覧・購入した商品のエンベディングと、他の商品のエンベディングを比較し、類似度の高い(関連性の高い)商品を推薦します。

AIが言葉を理解するまでの2つのマイルストーン

テキストエンベディング技術の進化は、AIが人間の言葉を理解する上で非常に重要な役割を果たしてきました。特に以下の2つの出来事は、大きな転換点となりました。

  • Word2Vecの登場(2013年)
    Googleの研究者が発表したこの技術により、単語の「意味」をベクトルとして効率的に扱えるようになりました(静的埋め込み)。「king - man + woman = queen」のような意味の演算を可能にし、自然言語処理の分野に大きな進歩をもたらしました。
  • Transformer/BERTの登場(2018年)
    同じくGoogleが発表したTransformerアーキテクチャと、それを用いたBERTモデルにより、AIは文脈に応じた意味理解が可能になりました(文脈化埋め込み)。これが、現在のChatGPTをはじめとする大規模言語モデルの直接的な基礎となっています。

代表的な文脈化埋め込みのテキストエンベディングモデル

代表的な文脈化埋め込みモデルには、以下のようなものがあります。

上記のモデルはいずれも以下のような特徴を持ちます。

  • Transformerベース
  • 文章(テキスト)の文脈を理解する
  • 高い性能
  • 優れた多言語対応能力
  • 低次元出力の選択肢

テキストエンベディング補足

テキストエンベディングについての補足です。

  • ベクトルデータは膨大になるため、実際には、以下のような手段を用いてデータ量を削減できます。
    • 量子化: float32をint8に変換するなどの方法があります。
      • float32からint8への変換では、単純計算でデータ量は1/4になります。
      • float32 で表現できる膨大な数の実数を、たった256段階のint8に無理やり丸めるため、元々あった微妙な情報の差異が失われます。
    • 次元削減: PCA(主成分分析) などの手法を用いて、ベクトルの次元数そのものを削減します。例えば、1536次元のベクトルを256次元に圧縮するなどです。
      • 次元数が減るため、ストレージ削減に加え、類似度計算(例: コサイン類似度)の計算量も大幅に削減できます。
      • 次元削減は本質的に非可逆圧縮です。元の高次元空間で表現されていた、単語や文脈の細かなニュアンスが失われるリスクがあります。
  • ベクトルデータを扱えるデータベースやライブラリなどが存在します。
    • データベース: Pinecone, Milvus, Weaviate, Qdrant, pgvector(PostgreSQLの拡張機能)
    • ライブラリ例: C#はMicrosoft.Extensions.VectorData、PythonはLangChainなど。
  • ベクトルデータを検索する際には、「完全ではないが、実用上十分な精度で、非常に高速に」最も近いベクトルを見つける近似最近傍探索(ANN)という技術が一般的に用いられます。
    • 近似最近傍探索: 大量のデータの中から、指定したものに『だいたい似ている』ものを、高速に見つけ出す技術
    • あらかじめ索引(インデックス)を作成し、候補を絞り込みます。
  • テキストエンベディングをした結果のベクトルは、モデルが異なれば違う値になります。
    • データのインデックス作成時とクエリ(検索)実行時には、必ず同一のモデル(バージョンを含む)を使用する必要があります。
      同じ文章でもモデルやバージョンが異なればベクトルは一致せず、類似度スケールも変わるため、モデル間やバージョン間でスコアを直接比較しないでください。
  • 文章エンベディングモデルで生成したベクトルからテキストへ戻すことはできません。
    • 文章エンベディングモデルは、文脈、語順、単語同士の関係性など、文章全体の意味を「凝縮(非可逆圧縮)」してベクトルを作ります。
    • このため、通常は元のテキストと生成されたベクトルをセットで管理します。
    • 単語エンベディングモデルは、単語とベクトルが1対1に近い関係で管理されているため、ベクトルが指し示す最も近い単語を探すことで、元の単語を推測することは可能です。
  • 多言語間の同じ意味を表す単語は、近い(近似的な)ベクトルになります。
    • 例えば、日本語の「りんご」と英語の「Apple」は、多言語モデルにおいて意味的に近いベクトルとして扱われます。しかし、英語の「Apple」には「Apple社」という意味も含まれるため、文脈によっては単純な同義語として扱えないケースもあります。このように、特定の慣用句や多義語など、言語によって単語の持つ意味合いが微妙に異なる点には注意が必要です。

テキストエンベディングとLLMの違い

テキストエンベディングとLLMは、テキストデータを扱うAI技術ですが、その役割と目的は異なります。

  • 役割
    • エンベディング: テキストの「意味の座標」を定める技術。テキスト間の関連性を数値化し、検索や分類の土台を築きます。言わば「意味の測量士」です。
    • LLM: 文脈を理解し、論理的に思考して新たなテキストを生成するモデル。与えられた情報から、筋の通った回答や文章を作り出す「賢い対話相手」です。
  • 判断基準
    • エンベディング: 主に「意味の近さ」(トピック類似度)を基準に判断します。似ているかどうか、関連が強いかどうかを素早く測るのが得意です。
    • LLM: 「論理的一貫性」(話の筋や整合性)を重視します。文法・事実関係・推論の流れが破綻していないか、全体の整合性で良し悪しが決まります。
  • 思考プロセス
    • エンベディング: 幾何学的です。ベクトルの向きや距離という“座標”で意味をとらえます。
    • LLM: 分析的・論理的です。文法や事実、因果関係を踏まえて結論を組み立てます。
  • 得意分野
    • エンベディング: 高速検索、類似文書探索、クラスタリング、レコメンドなど「関連度に基づく分類・順位付け」を得意とします。
    • LLM: 対話、要約、質問応答、解説・推論タスクなど「文脈を読み解き、新たな文章を生成する」タスクを得意とします。
  • 計算コスト
    • エンベディング: 低コスト・高速です。大量データでもスケールしやすいです。
    • LLM: 高コスト・相対的に低速です(プロンプト長やモデル規模で変動)。

テキストエンベディングによる文章比較

本記事で解説した内容を踏まえ、代表的なエンベディングモデルを用いて短文ペアの類似度を比較する実験を行いました。
評価軸は次の7種類です。各カテゴリ3ペアのデータを用意し、OpenAIとGeminiのモデルで検証しました。

  • 比較軸

    • 似ている (similar)
    • 無関係 (unrelated)
    • 多言語 (multilingual)
    • 同義語 (synonym)
    • 否定 (negation)
    • 上位/下位 (hypernymy)
    • 事実の矛盾 (contradiction)
  • 使用モデルと実装

比較結果概要

注意: サンプル数が少ないため、スコアの絶対値ではなくカテゴリ内の相対比較や分布傾向の把握に留めるのが適切です。また、モデルごとにスコア分布のオフセットやレンジが異なるため、複数のモデルで共通の閾値を設けて判定することは推奨されません。

モデル similar
(類似ペア)
unrelated
(無関係ペア)
multilingual
(多言語ペア)
synonym
(同義語ペア)
negation
(否定ペア)
hypernymy
(上下関係ペア)
contradiction
(矛盾ペア)
OpenAI-small 0.642 0.1355 0.6419 0.696 0.857 0.7195 0.8442
OpenAI-large 0.7279 0.167 0.7021 0.8062 0.7857 0.7494 0.8068
Gemini 0.8557 0.5367 0.8604 0.8727 0.8872 0.9027 0.9296

結果詳細

結果から見える特徴と注意点

  • 多言語ペアは、言語が異なっても意味が近いため、高い類似度を示す傾向があります。
  • 無関係ペアは、低い類似度となることが期待されます。今回の実験ではOpenAI系は低い値を示しましたが、Geminiはやや高めの値となりました。
    • ただし、詳細結果の分布グラフを見ると、Geminiのスコアも他のカテゴリと比較すれば明確な差異が表れており、数値の絶対値だけで判断すべきではないことが分かります。
  • 一方で、否定や矛盾を含むペアでは、類似度が高く算出されやすい傾向が見られました。
    • これは、エンベディングが文全体のトピックや構成語彙の近さを捉えるため、多くの単語を共有しているとベクトル空間上での向きが近づきやすくなるためです。
    • 例(事実の矛盾)
      • 「日本の首都は東京です。」
      • 「日本の首都は大阪です。」
    • 上記2文は、「日本の首都は〜です」という構文と語彙の大部分を共有しています。さらに、「東京」と「大阪」も「日本の主要都市」という共通のセマンティック空間に位置するため、ベクトル表現が近接し、結果として高い類似度スコアが算出されるのです。

エンベディングの類似度をどう解釈すべきか

今回の実験で、事実が矛盾する「日本の首都は東京です」と「日本の首都は大阪です」のペアでも高い類似度が出たように、エンベディングはあくまで「トピックや構成語彙の近さ」を測るものです。

実務でエンベディングを用いる際は、類似度スコアを文章の「正しさ」や「真偽」の判定に直接利用するのは避けるべきです。まず類似度検索で関連候補を絞り込み、その後の処理でLLMに論理的な整合性を検証させるといった、複数の技術を組み合わせた複合的な設計が不可欠です。

再現手順(簡易)

  • 前提: Python環境、OpenAI/GoogleのAPIキーを環境変数に設定します。(OPENAI_API_KEY, GOOGLE_API_KEY)
  • 依存: openai, google-generativeai, numpy, pandas, python-dotenvなどをインストールします。
  • 実行: example1.py を実行すると、各カテゴリの平均コサイン類似度とピボットテーブルが出力されます。

参考: ソースコード
https://github.com/synapse-jp/embedding_example/blob/main/src/example1.py

まとめ

  • エンベディングは「意味を計算可能にする」鍵であり、検索・分類・レコメンドからRAGまで幅広く支える基盤技術です。
  • 今回の比較実験で示したように、モデルごとに振る舞いは異なり、否定や矛盾を含む文章でも高い類似度スコアを示す場合があります。
  • だからこそ実務では、ベクトル検索の結果を鵜呑みにせず、後段でLLMによる整合性チェックを組み合わせるなど、コストと精度のバランスを考えた設計が重要になります。