first commit
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,57 @@
|
||||
import chromadb
|
||||
from chromadb.utils import embedding_functions
|
||||
|
||||
# Menggunakan model embedding yang sama
|
||||
emb = embedding_functions.SentenceTransformerEmbeddingFunction(
|
||||
model_name="paraphrase-multilingual-MiniLM-L12-v2"
|
||||
)
|
||||
|
||||
# Membuka database
|
||||
client = chromadb.PersistentClient(path="./chroma_db")
|
||||
|
||||
# Membuka koleksi ukuran 1000
|
||||
koleksi = client.get_collection(
|
||||
name="pedoman_1000",
|
||||
embedding_function=emb
|
||||
)
|
||||
|
||||
# 5 pertanyaan biasa + 2 parafrase
|
||||
PERTANYAAN = [
|
||||
("Biasa", "Apa yang dimaksud dengan airworthiness?"),
|
||||
("Biasa", "Apa kepanjangan dan pengertian MRO?"),
|
||||
("Biasa", "Apa perbedaan line maintenance dan base maintenance?"),
|
||||
("Biasa", "Apa tujuan utama aircraft maintenance?"),
|
||||
("Biasa", "Apa itu Non-Destructive Testing?"),
|
||||
|
||||
("Parafrase", "Bagaimana mengetahui bahwa sebuah pesawat layak diterbangkan dengan aman?"),
|
||||
("Parafrase", "Jenis perawatan rutin apa yang dilakukan ketika pesawat masih beroperasi?")
|
||||
]
|
||||
|
||||
if koleksi.count() == 0:
|
||||
print("Database masih kosong.")
|
||||
|
||||
else:
|
||||
for nomor, (jenis, pertanyaan) in enumerate(PERTANYAAN, 1):
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print(f"Pertanyaan {nomor} ({jenis})")
|
||||
print(pertanyaan)
|
||||
|
||||
hasil = koleksi.query(
|
||||
query_texts=[pertanyaan],
|
||||
n_results=min(3, koleksi.count())
|
||||
)
|
||||
|
||||
for peringkat, (doc, meta, jarak) in enumerate(
|
||||
zip(
|
||||
hasil["documents"][0],
|
||||
hasil["metadatas"][0],
|
||||
hasil["distances"][0]
|
||||
),
|
||||
start=1
|
||||
):
|
||||
print(f"\nPeringkat {peringkat}")
|
||||
print(f"Sumber: {meta['sumber']}")
|
||||
print(f"Chunk: {meta['chunk']}")
|
||||
print(f"Jarak: {jarak:.3f}")
|
||||
print(doc[:300])
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
invalid type: string "llapse of this dam in China resulted in one of \nthe deadliest floods in history, with estimates of up to 240,000 fatalities. The \ndisaster was caused by inadequate design and failure to account for extreme \nweather conditions. \n6. Bhopal Gas Tragedy (1984): A gas leak at a pesticide plant in Bhopal, India, \ne in Figure 3.1 as a model as you compose your e-mail \nÿÿÿÿÿÿÿ
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,130 @@
|
||||
import chromadb
|
||||
from chromadb.utils import embedding_functions
|
||||
|
||||
# Model embedding yang sama
|
||||
emb = embedding_functions.SentenceTransformerEmbeddingFunction(
|
||||
model_name="paraphrase-multilingual-MiniLM-L12-v2"
|
||||
)
|
||||
|
||||
client = chromadb.PersistentClient(path="./chroma_db")
|
||||
|
||||
# 15 pertanyaan dan kata kunci dari PDF
|
||||
UJI = [
|
||||
("Apa arti airworthiness?", "fit for safe flight"),
|
||||
("Apa kepanjangan MRO?", "Maintenance, Repair, and Overhaul"),
|
||||
("Apa tugas line maintenance?", "Routine maintenance tasks"),
|
||||
("Apa itu base maintenance?", "taken out of service"),
|
||||
("Apa tujuan NDT?", "without causing damage"),
|
||||
("Apa tujuan utama aircraft maintenance?", "safety and performance"),
|
||||
("Apa itu pendekatan RCM?", "Reliability-Centered Maintenance"),
|
||||
("Strategi apa yang menggunakan data real-time?", "Condition-Based Maintenance"),
|
||||
("Siapa yang melakukan perawatan pesawat pada masa awal penerbangan?", "Wright brothers"),
|
||||
("Kapan prosedur standar perawatan mulai dikembangkan maskapai?", "1920s"),
|
||||
("Apa layanan yang digunakan maskapai untuk merawat armada?", "MRO services"),
|
||||
("Apa tujuan perawatan pesawat militer?", "mission readiness"),
|
||||
("Teknologi apa yang digunakan untuk pelatihan perawatan?", "Augmented Reality"),
|
||||
("Kendaraan apa yang diteliti untuk inspeksi dan perbaikan?", "Unmanned Aerial Vehicles"),
|
||||
("Material apa yang digunakan Boeing 787 Dreamliner?", "composite materials")
|
||||
]
|
||||
|
||||
|
||||
# Mencari peringkat pertama yang mengandung kata kunci
|
||||
def cari_peringkat(koleksi, pertanyaan, kunci, k=5):
|
||||
|
||||
jumlah = min(k, koleksi.count())
|
||||
|
||||
if jumlah == 0:
|
||||
return None
|
||||
|
||||
hasil = koleksi.query(
|
||||
query_texts=[pertanyaan],
|
||||
n_results=jumlah
|
||||
)
|
||||
|
||||
# Mengambil daftar dokumen hasil pencarian
|
||||
docs = hasil["documents"][0]
|
||||
|
||||
# Membersihkan kata kunci dari spasi dan baris baru
|
||||
kunci_bersih = " ".join(kunci.lower().split())
|
||||
|
||||
for peringkat, doc in enumerate(docs, start=1):
|
||||
|
||||
doc_bersih = " ".join(doc.lower().split())
|
||||
|
||||
if kunci_bersih in doc_bersih:
|
||||
return peringkat
|
||||
|
||||
return None
|
||||
|
||||
|
||||
# Menghitung Hit@K
|
||||
def hit_at_k(koleksi, uji, k=3):
|
||||
|
||||
benar = 0
|
||||
|
||||
for pertanyaan, kunci in uji:
|
||||
|
||||
peringkat = cari_peringkat(
|
||||
koleksi, pertanyaan, kunci, k
|
||||
)
|
||||
|
||||
if peringkat is not None:
|
||||
benar += 1
|
||||
|
||||
return benar / len(uji)
|
||||
|
||||
|
||||
# Menghitung MRR@5
|
||||
def hitung_mrr(koleksi, uji):
|
||||
|
||||
total = 0
|
||||
|
||||
for pertanyaan, kunci in uji:
|
||||
|
||||
peringkat = cari_peringkat(
|
||||
koleksi, pertanyaan, kunci, 5
|
||||
)
|
||||
|
||||
if peringkat is not None:
|
||||
total += 1 / peringkat
|
||||
|
||||
return total / len(uji)
|
||||
|
||||
|
||||
# Membandingkan dua koleksi
|
||||
for nama in ("pedoman_500", "pedoman_1000"):
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print(f"EVALUASI KOLEKSI: {nama}")
|
||||
|
||||
koleksi = client.get_collection(
|
||||
name=nama,
|
||||
embedding_function=emb
|
||||
)
|
||||
|
||||
if koleksi.count() == 0:
|
||||
print("Koleksi kosong!")
|
||||
continue
|
||||
|
||||
print("Jumlah pertanyaan:", len(UJI))
|
||||
|
||||
for k in (1, 3, 5):
|
||||
|
||||
nilai = hit_at_k(koleksi, UJI, k)
|
||||
|
||||
print(f"Hit@{k} = {nilai:.2f}")
|
||||
|
||||
mrr = hitung_mrr(koleksi, UJI)
|
||||
|
||||
print(f"MRR@5 = {mrr:.2f}")
|
||||
|
||||
print("\nPERTANYAAN YANG GAGAL DITEMUKAN:")
|
||||
|
||||
for pertanyaan, kunci in UJI:
|
||||
|
||||
peringkat = cari_peringkat(
|
||||
koleksi, pertanyaan, kunci, 5
|
||||
)
|
||||
|
||||
if peringkat is None:
|
||||
print("-", pertanyaan)
|
||||
@@ -0,0 +1,152 @@
|
||||
import random
|
||||
import chromadb
|
||||
from pathlib import Path
|
||||
from pypdf import PdfReader
|
||||
from chromadb.utils import embedding_functions
|
||||
|
||||
# FUNGSI MEMBACA PDF
|
||||
def baca_pdf(path):
|
||||
reader = PdfReader(path)
|
||||
|
||||
return "\n".join(
|
||||
(p.extract_text() or "")
|
||||
for p in reader.pages
|
||||
)
|
||||
|
||||
# FUNGSI MEMOTONG TEKS
|
||||
def potong(teks, ukuran=800, tumpang=100):
|
||||
|
||||
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()]
|
||||
|
||||
# MENCARI PDF DI FOLDER DOKUMEN
|
||||
daftar_pdf = list(Path("dokumen").glob("*.pdf"))
|
||||
|
||||
if not daftar_pdf:
|
||||
print("Tidak ada file PDF di folder dokumen!")
|
||||
|
||||
else:
|
||||
# Mengambil PDF pertama
|
||||
pdf = daftar_pdf[0]
|
||||
|
||||
# Membaca isi PDF
|
||||
teks = baca_pdf(pdf)
|
||||
|
||||
print(f"\nNama PDF: {pdf.name}")
|
||||
print(f"Total karakter: {len(teks)}")
|
||||
|
||||
# Menampilkan 500 karakter pertama
|
||||
print("\n===== 500 KARAKTER PERTAMA =====")
|
||||
print(teks[:500])
|
||||
|
||||
# Eksperimen tiga ukuran chunk
|
||||
for ukuran in (500, 1000, 1500):
|
||||
|
||||
overlap = int(ukuran * 0.1)
|
||||
|
||||
chunks = potong(
|
||||
teks,
|
||||
ukuran=ukuran,
|
||||
tumpang=overlap
|
||||
)
|
||||
|
||||
print("\n" + "=" * 50)
|
||||
print(f"UKURAN CHUNK: {ukuran}")
|
||||
print(f"OVERLAP: {overlap}")
|
||||
print(f"JUMLAH CHUNK: {len(chunks)}")
|
||||
|
||||
# Mengambil maksimal 3 chunk secara acak
|
||||
sampel = random.sample(
|
||||
range(len(chunks)),
|
||||
min(3, len(chunks))
|
||||
)
|
||||
|
||||
for nomor in sampel:
|
||||
print(f"\n--- CHUNK {nomor} ---")
|
||||
print(chunks[nomor])
|
||||
|
||||
|
||||
# LAB 2: EMBEDDING DAN CHROMADB
|
||||
|
||||
if daftar_pdf:
|
||||
|
||||
# Model embedding multilingual
|
||||
emb = embedding_functions.SentenceTransformerEmbeddingFunction(
|
||||
model_name="paraphrase-multilingual-MiniLM-L12-v2"
|
||||
)
|
||||
|
||||
# Membuat database lokal
|
||||
client = chromadb.PersistentClient(path="./chroma_db")
|
||||
|
||||
def bangun_indeks(nama_koleksi, ukuran):
|
||||
|
||||
# Menghapus koleksi lama agar tidak tercampur
|
||||
try:
|
||||
client.delete_collection(name=nama_koleksi)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Membuat koleksi baru
|
||||
koleksi = client.create_collection(
|
||||
name=nama_koleksi,
|
||||
embedding_function=emb,
|
||||
metadata={"hnsw:space": "cosine"}
|
||||
)
|
||||
|
||||
for pdf in daftar_pdf:
|
||||
|
||||
teks = baca_pdf(pdf)
|
||||
|
||||
overlap = int(ukuran * 0.1)
|
||||
|
||||
chunks = potong(
|
||||
teks,
|
||||
ukuran=ukuran,
|
||||
tumpang=overlap
|
||||
)
|
||||
|
||||
if not chunks:
|
||||
print(pdf.name, "tidak memiliki teks.")
|
||||
continue
|
||||
|
||||
koleksi.upsert(
|
||||
ids=[
|
||||
f"{pdf.stem}-{ukuran}-{i}"
|
||||
for i in range(len(chunks))
|
||||
],
|
||||
documents=chunks,
|
||||
metadatas=[
|
||||
{
|
||||
"sumber": pdf.name,
|
||||
"chunk": i,
|
||||
"ukuran": ukuran
|
||||
}
|
||||
for i in range(len(chunks))
|
||||
]
|
||||
)
|
||||
|
||||
print(
|
||||
pdf.name,
|
||||
"->",
|
||||
len(chunks),
|
||||
"chunk"
|
||||
)
|
||||
|
||||
print(
|
||||
f"\nKoleksi {nama_koleksi} berhasil dibuat."
|
||||
)
|
||||
print("Total data:", koleksi.count())
|
||||
|
||||
|
||||
# Membuat dua koleksi untuk eksperimen
|
||||
bangun_indeks("pedoman_500", 500)
|
||||
bangun_indeks("pedoman_1000", 1000)
|
||||
|
||||
else:
|
||||
print("Tidak ada PDF untuk indexing.")
|
||||
Reference in New Issue
Block a user