last
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
invalid type: string "vention\n \nis\n \nnot\n \nused\n \nin\n \nevery\n \ncase\n \nbecause\n \nsometimes\n \nthe\n \nargument\n \nname\n \nand\n \nthe\n \nvariable\n \nname\n \nare\n \ndifferent.\n \nFor\n \nexample:\n \ntext\n \ncontext:\n \nshortUrlBase\n \nHere,\n \n`context`\n \nis\n \nthe\n \nargument\n \nname\n \nand\n \n`shortUrlBase`\n \nis\n \nthe\n \nvariable\n \nbeing\n \npassed\n \nto
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+30
-145
@@ -1,86 +1,53 @@
|
||||
|
||||
from pathlib import Path
|
||||
from pypdf import PdfReader
|
||||
import chromadb
|
||||
from chromadb.utils import embedding_functions
|
||||
|
||||
# ==========================================
|
||||
# 1. MEMBACA DOKUMEN PDF
|
||||
# FUNGSI BANTU
|
||||
# ==========================================
|
||||
|
||||
def baca_pdf(path):
|
||||
reader = PdfReader(path)
|
||||
return "\n".join((p.extract_text() or "") for p in reader.pages)
|
||||
|
||||
|
||||
# ==========================================
|
||||
# 2. MEMBAGI DOKUMEN MENJADI CHUNK
|
||||
# ==========================================
|
||||
|
||||
def potong(teks, ukuran=800, tumpang=100):
|
||||
hasil = []
|
||||
mulai = 0
|
||||
|
||||
hasil, mulai = [], 0
|
||||
while mulai < len(teks):
|
||||
hasil.append(teks[mulai:mulai + ukuran])
|
||||
mulai += ukuran - tumpang
|
||||
|
||||
return [h for h in hasil if h.strip()]
|
||||
|
||||
|
||||
# ==========================================
|
||||
# 3. PENGATURAN EMBEDDING DAN DATABASE
|
||||
# SETUP EMBEDDING & CLIENT
|
||||
# ==========================================
|
||||
|
||||
emb = embedding_functions.SentenceTransformerEmbeddingFunction(
|
||||
model_name="paraphrase-multilingual-MiniLM-L12-v2"
|
||||
)
|
||||
model_name="paraphrase-multilingual-MiniLM-L12-v2")
|
||||
|
||||
client = chromadb.PersistentClient(path="./chroma_db")
|
||||
|
||||
|
||||
# ==========================================
|
||||
# 4. MEMBUAT KOLEKSI
|
||||
# ==========================================
|
||||
|
||||
def buat_koleksi(nama, ukuran, tumpang):
|
||||
|
||||
try:
|
||||
client.delete_collection(nama)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
kol = client.get_or_create_collection(
|
||||
name=nama,
|
||||
embedding_function=emb,
|
||||
metadata={"hnsw:space": "cosine"}
|
||||
)
|
||||
|
||||
name=nama, embedding_function=emb,
|
||||
metadata={"hnsw:space": "cosine"})
|
||||
for pdf in Path("dokumen").glob("*.pdf"):
|
||||
|
||||
teks = baca_pdf(pdf)
|
||||
chunks = potong(teks, ukuran, tumpang)
|
||||
|
||||
if not chunks:
|
||||
continue
|
||||
|
||||
chunks = potong(baca_pdf(pdf), ukuran, tumpang)
|
||||
kol.upsert(
|
||||
ids=[
|
||||
f"{nama}-{pdf.stem}-{i}"
|
||||
for i in range(len(chunks))
|
||||
],
|
||||
ids=[f"{nama}-{pdf.stem}-{i}" for i in range(len(chunks))],
|
||||
documents=chunks,
|
||||
metadatas=[
|
||||
{"sumber": pdf.name, "chunk": i}
|
||||
for i in range(len(chunks))
|
||||
]
|
||||
metadatas=[{"sumber": pdf.name, "chunk": i} for i in range(len(chunks))],
|
||||
)
|
||||
|
||||
print(f" {nama}: {pdf.name} -> {len(chunks)} chunk")
|
||||
return kol
|
||||
|
||||
|
||||
# ==========================================
|
||||
# 5. 15 PERTANYAAN DAN KATA KUNCI
|
||||
# 15 PERTANYAAN + KATA KUNCI
|
||||
# (disesuaikan dengan isi PDF probabilitas)
|
||||
# ==========================================
|
||||
|
||||
UJI = [
|
||||
@@ -101,124 +68,42 @@ UJI = [
|
||||
("What is a random variable?", "random variable"),
|
||||
]
|
||||
|
||||
|
||||
# ==========================================
|
||||
# 6. FUNGSI HIT@K
|
||||
# ==========================================
|
||||
|
||||
def hit_at_k(koleksi, uji, k):
|
||||
|
||||
benar = 0
|
||||
jumlah = min(k, koleksi.count())
|
||||
|
||||
if jumlah == 0:
|
||||
return 0
|
||||
|
||||
for pertanyaan, kunci in uji:
|
||||
|
||||
docs = koleksi.query(
|
||||
query_texts=[pertanyaan],
|
||||
n_results=jumlah
|
||||
)["documents"][0]
|
||||
|
||||
docs = koleksi.query(query_texts=[pertanyaan], n_results=k)["documents"][0]
|
||||
if any(kunci.lower() in d.lower() for d in docs):
|
||||
benar += 1
|
||||
|
||||
return benar / len(uji)
|
||||
|
||||
|
||||
# ==========================================
|
||||
# 7. MEMBUAT DUA KOLEKSI BERBEDA
|
||||
# JALANKAN: BUAT 2 KOLEKSI
|
||||
# ==========================================
|
||||
|
||||
print("=== MEMBUAT KOLEKSI ===")
|
||||
kol_500 = buat_koleksi("chunk_500", 500, 75)
|
||||
kol_1500 = buat_koleksi("chunk_1500", 1500, 225)
|
||||
|
||||
print("\n=== CEK ISI KOLEKSI ===")
|
||||
print(f" chunk_500 : {kol_500.count()} dokumen")
|
||||
print(f" chunk_1500 : {kol_1500.count()} dokumen")
|
||||
|
||||
# ==========================================
|
||||
# 8. MENAMPILKAN TABEL HASIL HIT@K
|
||||
# HITUNG HIT@K
|
||||
# ==========================================
|
||||
|
||||
print("\n========== TABEL HIT@K ==========")
|
||||
|
||||
print(f"{'k':<5}{'Chunk 500':<15}{'Chunk 1500':<15}")
|
||||
|
||||
hasil = {}
|
||||
|
||||
print("\n=== TABEL HIT@K ===")
|
||||
print(f"{'k':<4}{'Chunk 500':<14}{'Chunk 1500':<14}")
|
||||
for k in (1, 3, 5):
|
||||
print(f"{k:<4}{hit_at_k(kol_500, UJI, k):<14.2f}{hit_at_k(kol_1500, UJI, k):<14.2f}")
|
||||
|
||||
h500 = hit_at_k(kol_500, UJI, k)
|
||||
h1500 = hit_at_k(kol_1500, UJI, k)
|
||||
|
||||
hasil[k] = (h500, h1500)
|
||||
|
||||
print(f"{k:<5}{h500:<15.2f}{h1500:<15.2f}")
|
||||
|
||||
|
||||
# ==========================================
|
||||
# 9. MENAMPILKAN PERTANYAAN YANG GAGAL
|
||||
# ==========================================
|
||||
|
||||
print("\n========== PERTANYAAN GAGAL DI k=3 ==========")
|
||||
|
||||
gagal = []
|
||||
|
||||
print("\n=== PERTANYAAN GAGAL di k=3 ===")
|
||||
for pertanyaan, kunci in UJI:
|
||||
ok_500 = any(kunci.lower() in d.lower()
|
||||
for d in kol_500.query(query_texts=[pertanyaan], n_results=3)["documents"][0])
|
||||
ok_1500 = any(kunci.lower() in d.lower()
|
||||
for d in kol_1500.query(query_texts=[pertanyaan], n_results=3)["documents"][0])
|
||||
if not ok_500 and not ok_1500:
|
||||
print(f"X {pertanyaan} (kunci: '{kunci}')")
|
||||
|
||||
docs_500 = kol_500.query(
|
||||
query_texts=[pertanyaan],
|
||||
n_results=min(3, kol_500.count())
|
||||
)["documents"][0]
|
||||
|
||||
docs_1500 = kol_1500.query(
|
||||
query_texts=[pertanyaan],
|
||||
n_results=min(3, kol_1500.count())
|
||||
)["documents"][0]
|
||||
|
||||
ok_500 = any(kunci.lower() in d.lower() for d in docs_500)
|
||||
ok_1500 = any(kunci.lower() in d.lower() for d in docs_1500)
|
||||
|
||||
if not ok_500 or not ok_1500:
|
||||
|
||||
gagal.append(pertanyaan)
|
||||
|
||||
print(f"\nPertanyaan: {pertanyaan}")
|
||||
print(f"Kata kunci: {kunci}")
|
||||
print(f"Chunk 500 : {'Berhasil' if ok_500 else 'Gagal'}")
|
||||
print(f"Chunk 1500: {'Berhasil' if ok_1500 else 'Gagal'}")
|
||||
|
||||
if not gagal:
|
||||
print("Semua pertanyaan berhasil ditemukan pada kedua koleksi.")
|
||||
|
||||
|
||||
# ==========================================
|
||||
# 10. KESIMPULAN OTOMATIS
|
||||
# ==========================================
|
||||
|
||||
print("\n========== KESIMPULAN ==========")
|
||||
|
||||
rata_500 = sum(v[0] for v in hasil.values()) / len(hasil)
|
||||
rata_1500 = sum(v[1] for v in hasil.values()) / len(hasil)
|
||||
|
||||
print(f"Rata-rata Hit@K Chunk 500 : {rata_500:.2f}")
|
||||
print(f"Rata-rata Hit@K Chunk 1500 : {rata_1500:.2f}")
|
||||
|
||||
if rata_500 > rata_1500:
|
||||
print("Chunk 500 memiliki hasil pencarian lebih baik.")
|
||||
elif rata_1500 > rata_500:
|
||||
print("Chunk 1500 memiliki hasil pencarian lebih baik.")
|
||||
else:
|
||||
print("Kedua ukuran chunk memiliki hasil rata-rata yang sama.")
|
||||
|
||||
print(
|
||||
f"Jumlah pertanyaan yang gagal pada minimal satu koleksi "
|
||||
f"di k=3: {len(gagal)} dari {len(UJI)}."
|
||||
)
|
||||
|
||||
print(
|
||||
"Kegagalan pencarian dapat disebabkan oleh perbedaan istilah, "
|
||||
"informasi yang tersebar di beberapa chunk, atau hasil embedding "
|
||||
"yang kurang relevan."
|
||||
)
|
||||
|
||||
print("\n========== PENGUJIAN SELESAI ==========")
|
||||
print("\n=== SELESAI ===")
|
||||
Reference in New Issue
Block a user