NISHIO Hirokazu[日本語][English]

テキスト埋め込みベクトルの分布

そもそもテキスト埋め込みベクトルの分布の形状はどのようなものか

データはXから取得した18129件からTalk to the Cityのextructionで抽出されたargument 7574件

  • これをtext-embedding-3-largeで3072次元のベクトル空間に埋め込んでいる

OpenAIが返す埋め込みベクトルは正規化されているので全てのベクトルの長さは1である

  • なので3072次元の球面上に分布している py
def p(x):
   print(f"{x.mean()} ± {x.std() * 3}")

norm = np.linalg.norm(embeddings_array, axis=1)
p(norm)  # -> 0.999999999999999 ± 1.2314317043463034e-15

各軸の値はSD 0.01程度の狭い範囲に集まっている py

axis_std = embeddings_array.std(axis=0)
pd.DataFrame(axis_std).describe()

image

3072次元のうち80次元が6割の情報を持っている

  • 9割の情報が500次元に散っている
  • imageimage
  • とても高次元だな、2次元だと情報が1割もない

各データの他のデータに対する内積は0.4あたりを平均として0.1~0.7程度

  • image
    • 順番をシャッフルして隣のベクトルとの内積をとったヒストグラム
  • 各軸の値がSD 0.01程度の狭い範囲で動くのに全体としては結構範囲が広いな〜
    • これは高次元球面上のベルトが実はとても広いことに起因する感覚のずれか
    • 次元の呪い
  • ユークリッド距離にしておくとこんな感じ
    • image
    • ほとんどのデータが他のほとんどのデータと0.8~1.4くらい離れている
    • これはかなり重要な特徴で、DBSCANのepsはデフォルト値だと0.5だから「ほとんどすべての点が隣接してない」になっちゃうわけ

HDBSCANのcondensed_tree_.plot

  • デフォルトのHDBSCAN(min_cluster_size=5)
    • image
  • HDBSCAN(min_cluster_size=30)にして推定される密度をなめらかにしたもの
    • image
    • つまり大雑把にいうと「おおきなひとつのクラスタにちょっと小さなこぶがあるだけ」
    • lambda 1.0より小さい「密度薄くてもOK」な領域では7000個全てが一つにつながっている
    • ~1.2の領域でクラスタとみなされない小集合が離脱していき1000個程度しか残らない
    • その小集合が3つに分かれる
    • min_cluster_size=5ではクラスタとみなす小集合が増えてもっと細かく描かれている

(C)NISHIO Hirokazu / Converted from Markdown (ja)
Source: [GitHub] / [Scrapbox]