b belajar.myudak

Pencarian dengan cosine similarity

Diberikan matriks embedding E (satu baris per item) dan vektor query q. Kembalikan indeks k baris yang paling mirip arahnya dengan q menurut cosine similarity, terurut dari yang paling mirip. Jika seri, indeks yang lebih kecil didahulukan.

cos⁡(a,b)=a⋅b∥a∥ ∥b∥\cos(a, b) = \frac{a\cdot b}{\lVert a\rVert\,\lVert b\rVert}
E = [[1,0], [0,1], [1,1]], q = [1, 0.1], k = 2  →  [0, 2]
E = [[1,0], [2,0], [-1,0]], q = [3, 0], k = 3   →  [0, 1, 2]   // [1,0] dan [2,0] sama arahnya
Ruang embedding
rajaratupriawanitakucinganjingsingamobilmotorsepedaapeljerukmanggasemarangjakartabandung

Klik kata di grafik. cos(a, b) = a·b / (‖a‖‖b‖): 1 = searah, 0 = tegak lurus, −1 = berlawanan.

  1. 1anjing0.986
  2. 2singa0.914
  3. 3sepeda0.566
  4. 4motor0.387
  5. 5pria0.212
  6. 6mobil0.162
  7. 7wanita-0.134
  8. 8raja-0.151

Arah, bukan panjang

Cosine similarity hanya melihat sudut antar-vektor. [1, 0] dan [2, 0] punya kemiripan 1, walau jarak Euclid-nya 1. Untuk embedding, panjang vektor sering dipengaruhi hal seperti frekuensi kata, sedangkan arahnya membawa makna. Karena itu cosine adalah ukuran default.

Kalau semua vektor sudah dinormalkan ke panjang 1, cosine similarity sama dengan dot product biasa. Database vektor memanfaatkan sifat ini supaya pencarian menjadi satu perkalian matriks E @ q.

Hubungan dengan attention

Skor attention q⋅kq\cdot k juga mengukur kemiripan arah (ditambah panjang). Attention pada dasarnya adalah pencarian lunak (soft retrieval): bukan mengambil top-k, tapi mengambil rata-rata berbobot dari semua item, dengan bobot softmax dari kemiripannya.

Penjelasan

Yang diminta. Indeks k baris E yang arahnya paling mirip dengan q.

Langkah di kode:

  1. E @ q memberi dot product q dengan setiap baris, (n,).
  2. np.linalg.norm(E, axis=1) memberi panjang setiap baris, dan np.linalg.norm(q) panjang query.
  3. Bagi untuk mendapat cosine similarity, (n,), nilainya di antara −1 dan 1.
  4. np.argsort(-sims, kind="stable"): argsort mengurutkan dari kecil ke besar, jadi kita urutkan negatifnya agar yang terbesar di depan. kind="stable" menjaga urutan asli untuk nilai yang sama, sehingga indeks yang lebih kecil didahulukan saat seri.
  5. Ambil [:k] dan ubah ke list Python.

Kenapa cosine, bukan jarak? Di case 2, [1, 0] dan [2, 0] sama-sama searah dengan q = [3, 0], sehingga cosine keduanya 1 dan seri. Dengan jarak Euclid, [2, 0] akan lebih dekat. Embedding membawa makna di arah-nya.

Yang dikembalikan: list k bilangan bulat.

Topik
embeddingcosine similarityretrieval
Petunjuk 1

cos(a, b) = a·b / (‖a‖ ‖b‖). Untuk semua baris sekaligus: (E @ q) / (np.linalg.norm(E, axis=1) * np.linalg.norm(q)).

Petunjuk 2

np.argsort(-sims, kind='stable') mengurutkan dari terbesar, dan pada nilai seri indeks kecil tetap di depan.

Python 3.14 · NumPy

Pengaturan editor

Ukuran font
Ukuran huruf di editor.
Ukuran tab
Lebar indentasi. Otomatis: 2 spasi untuk TypeScript, 4 untuk Python.
Key bindings
Ganti ke mode Vim.
Nomor baris relatif
Nomor baris dihitung dari posisi kursor (berguna untuk gerakan Vim).
Word wrap
Baris panjang dilipat agar muat di lebar editor.
IntelliSense
Saran kode otomatis saat mengetik (Ctrl+Spasi tetap bisa dipakai saat mati).

Nilai ditulis sebagai JSON. Output yang diharapkan dihitung dari solusi referensi.