0Pricing
AI Engineering Academy · Pelajaran

Pencarian Semantik dengan NumPy

Bangun sistem pencarian semantik Python murni menggunakan NumPy untuk menghitung kesamaan kosinus antara penyematan kueri dan kumpulan penyematan dokumen.

Pencarian Semantik dengan NumPy adalah pelajaran AI Engineering Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Engineering Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Engineering Academy mencakup 4 pelajaran total.

Pencarian Semantik Tanpa Basis Data

Pencarian semantik menemukan dokumen yang paling relevan untuk suatu kueri berdasarkan makna, bukan berdasarkan kemiripan kata kunci. Implementasi paling sederhana menggunakan NumPy untuk menghitung kemiripan kosinus antara embedding kueri dan semua embedding dokumen di memori—tanpa memerlukan basis data eksternal.

Pendekatan ini bekerja dengan baik hingga puluhan ribu dokumen dan ideal untuk pembuatan prototipe sebelum Anda berinvestasi pada basis data vektor.

Membangun Korpus Dokumen

Mulailah dengan mengumpulkan dokumen Anda dan menghasilkan satu embedding per dokumen menggunakan API OpenAI. Simpan embedding sebagai larik NumPy 2D, dengan setiap baris mewakili satu vektor dokumen. Simpan daftar teks dokumen secara paralel agar Anda dapat mengambil konten asli setelah menemukan kecocokan terbaik.

import numpy as np
from openai import OpenAI

client = OpenAI()

documents = [
    'Python is a high-level programming language.',
    'NumPy provides fast numerical computing for Python.',
    'Embeddings represent text as dense vectors.',
    'Cosine similarity measures angle between vectors.',
    'RAG combines retrieval with language generation.'
]

response = client.embeddings.create(
    model='text-embedding-3-small',
    input=documents
)

corpus_embeddings = np.array([item.embedding for item in response.data])
print(f'Corpus shape: {corpus_embeddings.shape}')  # (5, 1536)

Membuat Embedding untuk Kueri Pengguna

Saat pengguna mengirimkan kueri pencarian, buat embedding untuk kueri tersebut menggunakan model yang sama dengan yang digunakan untuk membuat embedding dokumen. Mencampur model—misalnya, menggunakan text-embedding-3-small untuk dokumen dan text-embedding-3-large untuk kueri—akan menghasilkan vektor dalam ruang yang berbeda dan memberikan skor kemiripan yang tidak bermakna.

from openai import OpenAI
import numpy as np

client = OpenAI()

query = 'How do I compute similarity between text?'

response = client.embeddings.create(
    model='text-embedding-3-small',   # must match corpus model
    input=query
)

query_embedding = np.array(response.data[0].embedding)
print(f'Query vector shape: {query_embedding.shape}')  # (1536,)

Menghitung Kemiripan Kosinus dengan NumPy

Untuk menemukan kemiripan antara kueri dan setiap dokumen dalam satu operasi, hitung hasil kali titik antara vektor kueri dan matriks vektor dokumen. Karena kedua embedding OpenAI dinormalisasi dengan L2, hasil ini sama dengan kemiripan kosinus untuk semua dokumen sekaligus—O(n * d), dengan n sebagai jumlah dokumen dan d sebagai dimensi.

import numpy as np

# corpus_embeddings: (n_docs, 1536)
# query_embedding: (1536,)

def semantic_search(query_vec, corpus_vecs):
    # Matrix-vector dot product: shape (n_docs,)
    similarities = corpus_vecs @ query_vec
    return similarities

# Example call (assuming pre-computed embeddings)
# sims = semantic_search(query_embedding, corpus_embeddings)
# print(sims)  # array of similarity scores, one per document

Mengurutkan dan Mengambil Hasil Teratas-K

Gunakan np.argsort untuk mengurutkan dokumen berdasarkan skor kemiripan dalam urutan menurun, lalu ambil indeks teratas-k. Dengan begitu, Anda mendapatkan indeks dokumen yang paling relevan, yang dapat digunakan untuk mengambil teks asli dari daftar paralel Anda.

import numpy as np

def get_top_k(query_vec, corpus_vecs, documents, k=3):
    similarities = corpus_vecs @ query_vec
    # argsort gives ascending order; [::-1] reverses to descending
    ranked_indices = np.argsort(similarities)[::-1]
    top_k_indices = ranked_indices[:k]
    return [
        {'text': documents[i], 'score': float(similarities[i])}
        for i in top_k_indices
    ]

# results = get_top_k(query_embedding, corpus_embeddings, documents, k=3)
# for r in results:
#     print(f'{r["score"]:.4f}: {r["text"]}')

Contoh Lengkap Pencarian Semantik

Menggabungkan semuanya: buat embedding korpus, buat embedding kueri, hitung kemiripan, lalu kembalikan hasil yang telah diurutkan. Pola lengkap ini merupakan inti dari setiap langkah pengambilan RAG, bahkan saat basis data vektor menggantikan NumPy di balik layar.

import numpy as np
from openai import OpenAI

client = OpenAI()

docs = [
    'Embeddings map text to numerical vectors.',
    'Python lists store ordered collections.',
    'Cosine similarity compares vector directions.',
    'RAG retrieves documents to ground LLM answers.',
    'Dictionaries store key-value pairs in Python.'
]

corpus_resp = client.embeddings.create(model='text-embedding-3-small', input=docs)
corpus = np.array([d.embedding for d in corpus_resp.data])

query = 'finding similar text using angles'
q_resp = client.embeddings.create(model='text-embedding-3-small', input=query)
q_vec = np.array(q_resp.data[0].embedding)

scores = corpus @ q_vec
for i in np.argsort(scores)[::-1][:3]:
    print(f'{scores[i]:.3f}: {docs[i]}')

Menetapkan Ambang Skor

Tidak semua hasil teratas-k benar-benar relevan—terkadang kecocokan terbaik pun masih kurang sesuai secara semantik. Tambahkan ambang skor untuk menyaring hasil dengan kemiripan rendah. Ambang yang umum untuk kemiripan kosinus adalah 0,70–0,80, tetapi Anda sebaiknya mengalibrasinya berdasarkan ranah spesifik Anda menggunakan kueri nyata.

import numpy as np

def search_with_threshold(query_vec, corpus_vecs, documents, k=5, threshold=0.75):
    similarities = corpus_vecs @ query_vec
    ranked = np.argsort(similarities)[::-1][:k]
    results = []
    for i in ranked:
        if similarities[i] >= threshold:
            results.append({'text': documents[i], 'score': float(similarities[i])})
    return results

# Only returns documents above the minimum similarity threshold

Karakteristik Kinerja Pencarian NumPy

Pencarian kemiripan NumPy memiliki kompleksitas waktu O(n * d) per kueri, dengan n sebagai jumlah dokumen dan d sebagai dimensi embedding. Untuk embedding berdimensi 1536:

  • 10.000 dokumen: sekitar 5 md per kueri pada CPU modern
  • 100.000 dokumen: sekitar 50 md per kueri
  • 1.000.000 dokumen: sekitar 500 md—terlalu lambat, beralihlah ke basis data vektor

NumPy sangat baik untuk pembuatan prototipe, tetapi tidak menyediakan pencarian aproksimasi, pemfilteran, atau persistensi secara bawaan.

Menyimpan Embedding ke Disk

Menghitung ulang embedding pada setiap proses membuang pemanggilan API dan biaya. Simpan embedding korpus dan teks dokumen Anda ke disk agar Anda hanya perlu membuat ulang embedding saat korpus berubah.

np.save menyimpan matriks embedding secara efisien, dan Anda dapat menyimpan daftar dokumen sebagai JSON. Saat memulai, muat kedua berkas tersebut, bukan memanggil API.

import numpy as np
import json

# Save
np.save('/tmp/corpus_embeddings.npy', corpus_embeddings)
with open('/tmp/corpus_docs.json', 'w') as f:
    json.dump(documents, f)

# Load
corpus_embeddings = np.load('/tmp/corpus_embeddings.npy')
with open('/tmp/corpus_docs.json') as f:
    documents = json.load(f)

print(f'Loaded {len(documents)} docs, shape {corpus_embeddings.shape}')

Menangani Dokumen Baru Secara Bertahap

Saat dokumen baru tiba, Anda tidak perlu membuat ulang embedding seluruh korpus. Buat embedding hanya untuk dokumen baru dan gunakan np.vstack untuk menambahkan vektornya ke matriks yang ada. Ingatlah untuk menambahkan teks baru ke daftar dokumen dalam urutan yang sama.

import numpy as np
from openai import OpenAI

client = OpenAI()

# Assume these exist from a previous session:
# corpus_embeddings: (n, 1536)
# documents: list of strings

new_docs = ['New document about vector search.']
resp = client.embeddings.create(model='text-embedding-3-small', input=new_docs)
new_vecs = np.array([item.embedding for item in resp.data])

corpus_embeddings = np.vstack([corpus_embeddings, new_vecs])
documents.extend(new_docs)
print(f'Corpus now has {len(documents)} documents')

Keterbatasan Pencarian dalam Memori

Pencarian semantik NumPy memiliki keterbatasan yang signifikan dibandingkan basis data vektor yang dibuat khusus:

  • Tidak ada persistensi—semuanya berada di RAM dan hilang saat dimulai ulang
  • Tidak ada pemfilteran metadata—Anda tidak dapat memfilter hasil berdasarkan tanggal, kategori, atau penulis
  • Hanya pemindaian linear—tidak ada pengindeksan tetangga terdekat aproksimasi
  • Tidak ada akses bersamaan—tidak cocok untuk penerapan produksi dengan banyak pengguna

Keterbatasan ini menjadi alasan untuk menggunakan basis data vektor khusus bagi sistem RAG produksi.

Pemeriksaan Singkat

Uji pemahaman Anda tentang konsep Rekayasa AI dari pelajaran ini.

Ringkasan Pelajaran

Dalam pelajaran ini, Anda mempelajari bahwa: hasil kali titik matriks terhadap embedding yang dinormalisasi dengan L2 menghitung kemiripan kosinus untuk seluruh korpus dalam satu operasi, np.argsort dengan pembalikan mengambil k dokumen yang paling mirip, dan pencarian NumPy ideal untuk prototipe, tetapi tidak memiliki persistensi dan pemfilteran metadata. Berikutnya, kita akan menggunakan pengelompokan dan UMAP untuk menemukan struktur topik dalam kumpulan embedding.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Pencarian Semantik dengan NumPy” gratis?

Ya — teks lengkap “Pencarian Semantik dengan NumPy” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Engineering Academy, upgrade ke CoddyKit PRO. Kursus AI Engineering Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Pencarian Semantik dengan NumPy”?

Bangun sistem pencarian semantik Python murni menggunakan NumPy untuk menghitung kesamaan kosinus antara penyematan kueri dan kumpulan penyematan dokumen. Kamu berlatih AI Engineering Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai AI Engineering Academy?

Tidak diperlukan pengalaman sebelumnya. AI Engineering Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.

Berapa lama pelajaran “Pencarian Semantik dengan NumPy” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Engineering Academy ini?

Ya. Setiap pelajaran AI Engineering Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Apa Itu Penyematan Vektor?
  2. Membuat Penyematan dengan OpenAI
  3. Pencarian Semantik dengan NumPy
  4. Mengelompokkan dan Memvisualisasikan Penyematan
← Kembali ke AI Engineering Academy