first commit

This commit is contained in:
2026-11-02 10:49:47 +07:00
commit 1414eb9295
16 changed files with 340 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+57
View File
@@ -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])
@@ -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.
+130
View File
@@ -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)
+152
View File
@@ -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.")