日本語の埋め込みベクトルを実測したら「猫が犬を追う」と「犬が猫を追う」が0.98だった

ほとんど同じ形の吹き出しを2つ見比べて訝しむトカゲのイラスト。意味の違う2つの文が同じベクトルとして扱われる様子を表している 生成AI・LLM

こんにちは!zhackです。

AIが「意味の近さ」を測るしくみに、埋め込み(Embedding) というものがあります。

言葉を数百〜数千個の数字の並び(ベクトル)に変換して、その向きが近いほど意味が近い、という考え方です。RAGや意味検索の土台になっている技術で、私も解説記事を書いたことがあります。

ただ、書いたときは引用した数字を並べただけでした。

手元にローカルLLMの環境ができたので、日本語で実際に測ってみました。

結論から言うと、教科書どおりだったところと、まったく想定外だったところの両方が出ました。特に想定外のほうは、意味検索やRAGを作る人には無視できない内容だと思います。

ご参考までに、、、

測定に使ったもの

項目 内容
モデル bge-m3(多言語対応の埋め込み専用モデル・1.2GB)
ベクトルの次元 1024
実行環境 Ollama 0.32.1 / RTX 3070 Ti / Windows
測る値 コサイン類似度(−1〜1。1に近いほど同じ向き=意味が近い)

測り方そのものは別記事にまとめています。→ ローカルLLMの速度は自分で測れる|tokens/秒とVRAM使用量の調べ方

先に測定が正しく動いていることの確認をしておきます。

類似度
猫 – 猫(完全に同じ語) 1.0000

上限がきちんと1.0000で出ているので、以下の数字も信用してよさそうです。こういう当たり前の確認をしておかないと、低い数字が出たときに現象なのかバグなのか区別がつきません

まず、教科書どおりだったこと

安心してよかった部分から書きます。

類似度
犬 – 動物 0.7801
犬 – 猫 0.6523
犬 – 自動車 0.5106
うれしい – 楽しい 0.7367
うれしい – 悲しい 0.5471
東京 – 大阪 0.6450
東京 – りんご 0.4811

意味が近いほど数字が高い。これは想定どおりでした。

「コンピュータ – 計算機」が 0.8271、「ホテル – 旅館」が 0.8299 と、外来語と和語の対応もきちんと捉えています。

ここまでは解説記事に書いてあるとおりです。

① 「王 − 男 + 女 = 女王」は、半分しか成立しませんでした

単語ベクトルの説明で必ず出てくる、有名な計算があります。

王 − 男 + 女 = 女王

私も記事に書きました。実際にやってみます。

順位 単語 類似度
1位 王様 0.7066
2位 女王 0.7006
3位 王女 0.6994
4位 0.6289
5位 0.5372

1位は「王様」自身でした。

「女王」は2位で、その差は0.006しかありません。厳密に言えば「女王になった」とは言えない結果です。

(もともとこの手のデモでは、計算に使った単語を候補から除外する慣行があります。それを知らずに「女王になります」とだけ書くと、実際に試した人が戸惑うことになる。私の記事がそうでした)

念のため、別の組み合わせも試しました。

父 − 男 + 女 = ?

順位 単語 類似度
1位 0.7514
2位 0.7429
3位 0.6652

こちらは成功です。「母」が元の「父」を上回って1位に来ました。

つまり成功するかどうかは単語による、というのが実測した結論です。いつでもきれいに決まるわけではありませんでした。

② 「りんご」と「リンゴ」より、「りんご」と「みかん」のほうが近い

ここから想定外です。

日本語には表記ゆれがあります。同じものを、ひらがな・カタカナ・漢字の3通りで書けます。同じものなら、当然いちばん近いはずです。

類似度
りんご – リンゴ(同じもの 0.5985
りんご – 林檎(同じもの 0.4872
リンゴ – 林檎(同じもの 0.6146
りんご – みかん(別の果物) 0.6102
りんご – apple(同じもの・英語) 0.3843

「りんご」と「みかん」(0.6102)が、「りんご」と「リンゴ」(0.5985)を上回りました。

同じものの書き方違いより、別の果物のほうが近いと判定されているわけです。

英語の apple に至っては 0.3843 で、全部の中で最下位でした。多言語対応をうたっているモデルでもこうなります。

日本語で検索システムを作るなら、表記ゆれは埋め込み任せにできないということです。

③ 漢字を共有すると、意味が無関係でも近くなる

最初にこれに気づいたのは、こんな数字を見たときでした。

類似度
動物 – 自動車 0.6422
猫 – 自動車 0.4948

意味的には「猫」のほうが「自動車」に近い……わけではないですが、少なくとも「動物」と「自動車」が特別近い理由はありません。

共通しているのは「動」の字だけです。

そこで、漢字を共有する無関係な語と、共有しない無関係な語を並べて比べました。

基準の語 漢字を共有する語 対照(共有なし)
自動車 動物 0.6422 猫 0.4948 +0.15
人間 時間 0.6375 岩石 0.5400 +0.10
火事 火曜日 0.6162 木曜日 0.5087 +0.11
電車 電話 0.5452 会議 0.5460 −0.001

4組中3組で、意味が無関係でも漢字を共有すると類似度が上がりました。

ただし「電車 – 電話」は例外だったので、法則ではなく傾向です。それでも0.10〜0.15の差は小さくありません。

同音異義語でも似たことが起きています。

類似度
橋 – 箸(音が同じ・意味は無関係) 0.4532
橋 – 川(意味的に関連) 0.4218

「橋」と「箸」が、「橋」と「川」より近いという結果になりました。

④ 語順を入れ替えても 0.98 ─ これが一番驚きました

意味検索の説明では「文の意味をベクトルにする」と言われます。では、意味が正反対の文はどうなるのか。

文の組 類似度
猫が犬を追いかける / 犬が猫を追いかける 0.9805
猫が犬を追いかける / 猫が犬を追う 0.9811
猫が犬を追いかける / 今日は良い天気です 0.4374

上の2行を見比べてください。

  • 意味が正反対(追う側と追われる側が逆)… 0.9805
  • ただの言い換え(同じ意味)… 0.9811

差は 0.0006 です。

区別できていません。方向を持つ文でも同じでした。

文の組 類似度
東京から大阪へ行く / 大阪から東京へ行く 0.9892

さらに、文が長くなるとどうなるかも測りました。

類似度
猫はかわいい動物です / 犬はかわいい動物です 0.8685
猫 / 猫はかわいい動物です 0.7933

1語だけ違う文が 0.8685。 文が長くなるほど、中身の違いは全体の中で薄まっていきます。

⑤ 反義語は「遠く」ならない

ついでに反義語も測りました。直感的には遠くなりそうですが、そうはなりませんでした。

類似度
上 – 下(反義語) 0.7920
上 – 机(無関係・対照) 0.4832
暑い – 寒い(反義語) 0.6917
暑い – 熱い(似た意味) 0.8642
好き – 嫌い(反義語) 0.6306
好き – 楽しい(同じ方向) 0.6803

反義語(0.63〜0.79)は、無関係な語(0.48)よりずっと近いところにいます。

「上」と「下」は、使われ方がそっくりだからです。「上に置く」「下に置く」のように、同じ文脈に現れます。埋め込みは意味そのものではなく使われ方を捉えているので、反対語は近くなります。

これが実務で何に効くか

測って分かったことを、使う側の視点でまとめるとこうなります。

現象 何に注意するか
語順を区別しない 「AがBを〜」と「BがAを〜」を取り違える。契約書や手順書の検索では致命的になりうる
表記ゆれに弱い 「りんご」で検索して「林檎」が出てこない可能性。正規化は別途必要
漢字の共有に引きずられる 無関係な文書が上位に来ることがある
反義語が近い 「値上げ」で検索して「値下げ」が混ざる
長い文ほど差が出ない 長文をまるごと1ベクトルにすると細部が消える。分割して埋め込むほうが効く

埋め込みは「意味で探す」と説明されますが、実際には「使われ方が似ているものを探す」に近い、というのが測ってみた実感です。

注意点(正直なところ)

  • これは bge-m3 という1つのモデルの結果です。モデルが違えば数字も変わります
  • ①の「王 − 男 + 女」はもともと Word2Vec 時代のデモで、bge-m3 のような文埋め込みモデルとは仕組みが違います。同じ土俵ではないことは踏まえてください
  • 各パターンの語数が少ないので、傾向としては読めても厳密な検証ではありません

それでも、自分の手元で数字が出るというのが大きいと思っています。「らしい」と書かれているものを、5分で確かめられる。

さいごに

以上が、日本語の埋め込みを実測してみた記録でした。

いちばん覚えて帰ってほしいのは、「猫が犬を追いかける」と「犬が猫を追いかける」が 0.9805 だったことです。

意味検索やRAGを「意味が分かるすごい技術」として使い始めると、ここで足をすくわれます。実際には使われ方の近さを測っている道具で、得意なことと苦手なことがはっきりあります。

単語ベクトルそのものの仕組みについては、以前に書いた記事があるのでよければどうぞ。→ 単語ベクトルとは?直感でわかる入門

ではでは!

参考文献

ローカルLLMの速度は自分で測れる|tokens/秒とVRAM使用量の調べ方
こんにちは!zhackです。先日、ローカルLLMの入門記事を書いたときに「GPUがあると毎秒30〜60トークンくらい出る」という数字を載せました。調べて出てきた数字を、そのまま書きました。そのあと実際に自分のPCで測ってみたのですが、87ト...
単語ベクトルとは?直感でわかる入門
単語ベクトルとは何かを数式なしで解説。会話と図でWord2Vecの仕組みをやさしく説明。機械学習を学び始めた人が最初に読む自然言語処理の基礎記事。

コメント

タイトルとURLをコピーしました