{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a682e14c",
   "metadata": {},
   "source": [
    "# Lab Minggu 18 — Simulasi UAS: Hitung Manual ➜ Verifikasi dengan Kode\n",
    "\n",
    "Cara pakai notebook ini:\n",
    "1. Baca soal. **Kerjakan dulu di kertas** (tanpa kalkulator kode).\n",
    "2. Tulis jawabanmu di variabel `jawaban_saya`.\n",
    "3. Jalankan sel verifikasi — kode menghitung jawaban yang benar dengan library standar.\n",
    "\n",
    "Topik mencakup seluruh semester (Minggu 1–17)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5c0be7f3",
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "sys.path.insert(0, \"..\")\n",
    "\n",
    "import math\n",
    "from collections import Counter\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import networkx as nx\n",
    "from sklearn.cluster import DBSCAN, KMeans\n",
    "from sklearn.metrics import confusion_matrix, f1_score, precision_score, recall_score, silhouette_score\n",
    "from mlxtend.preprocessing import TransactionEncoder\n",
    "from mlxtend.frequent_patterns import apriori, association_rules\n",
    "\n",
    "from common.datasets import play_tennis, transaksi_contoh, dokumen_teks\n",
    "\n",
    "def cek(nama, saya, benar, tol=1e-3):\n",
    "    if saya is None:\n",
    "        print(f\"{nama}: jawaban benar = {benar}\")\n",
    "    else:\n",
    "        ok = abs(saya - benar) <= tol\n",
    "        print(f\"{nama}: {'✅ BENAR' if ok else '❌ SALAH'} (kamu {saya}, kunci {round(benar, 4)})\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "86596f06",
   "metadata": {},
   "source": [
    "## Soal 1 — Asosiasi (Minggu 4–5)\n",
    "\n",
    "Dataset 9 transaksi Han & Kamber. Hitung support, confidence, lift untuk {I1, I2} → {I5}."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "64f401fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "transaksi = transaksi_contoh()\n",
    "for i, t in enumerate(transaksi, 1):\n",
    "    print(f\"T{i}: {t}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1f7a2f29",
   "metadata": {},
   "outputs": [],
   "source": [
    "jawaban_saya = {\"support\": None, \"confidence\": None, \"lift\": None}\n",
    "\n",
    "te = TransactionEncoder()\n",
    "X = pd.DataFrame(te.fit_transform(transaksi), columns=te.columns_)\n",
    "fi = apriori(X, min_support=0.2, use_colnames=True)\n",
    "rules = association_rules(fi, metric=\"confidence\", min_threshold=0.0)\n",
    "r = rules[(rules.antecedents == frozenset({\"I1\", \"I2\"})) & (rules.consequents == frozenset({\"I5\"}))].iloc[0]\n",
    "for k in [\"support\", \"confidence\", \"lift\"]:\n",
    "    cek(k, jawaban_saya[k], r[k])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e6f6d4c0",
   "metadata": {},
   "source": [
    "## Soal 2 — Decision Tree (Minggu 6)\n",
    "\n",
    "Hitung Entropy(play) dan Information Gain untuk keempat atribut. Atribut mana jadi akar?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "808832a7",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = play_tennis()\n",
    "df"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4b718be6",
   "metadata": {},
   "outputs": [],
   "source": [
    "jawaban_saya = {\"entropy\": None, \"outlook\": None, \"temperature\": None, \"humidity\": None, \"wind\": None}\n",
    "\n",
    "def entropy(s):\n",
    "    p = s.value_counts(normalize=True)\n",
    "    return -(p * np.log2(p)).sum()\n",
    "\n",
    "def gain(df, a, target=\"play\"):\n",
    "    return entropy(df[target]) - sum(len(g) / len(df) * entropy(g[target]) for _, g in df.groupby(a))\n",
    "\n",
    "cek(\"entropy\", jawaban_saya[\"entropy\"], entropy(df[\"play\"]))\n",
    "for a in [\"outlook\", \"temperature\", \"humidity\", \"wind\"]:\n",
    "    cek(f\"gain {a}\", jawaban_saya[a], gain(df, a))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "90dc12d7",
   "metadata": {},
   "source": [
    "## Soal 3 — Evaluasi model (Minggu 8)\n",
    "\n",
    "Confusion matrix: TP = 40, FP = 10, FN = 20, TN = 30. Hitung accuracy, precision, recall, F1."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "948c1048",
   "metadata": {},
   "outputs": [],
   "source": [
    "jawaban_saya = {\"accuracy\": None, \"precision\": None, \"recall\": None, \"f1\": None}\n",
    "\n",
    "y = np.array([1] * 40 + [0] * 10 + [1] * 20 + [0] * 30)\n",
    "p = np.array([1] * 40 + [1] * 10 + [0] * 20 + [0] * 30)\n",
    "print(confusion_matrix(y, p, labels=[1, 0]))\n",
    "cek(\"accuracy\", jawaban_saya[\"accuracy\"], (y == p).mean())\n",
    "cek(\"precision\", jawaban_saya[\"precision\"], precision_score(y, p))\n",
    "cek(\"recall\", jawaban_saya[\"recall\"], recall_score(y, p))\n",
    "cek(\"f1\", jawaban_saya[\"f1\"], f1_score(y, p))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d96d3770",
   "metadata": {},
   "source": [
    "## Soal 4 — K-Means satu iterasi (Minggu 10)\n",
    "\n",
    "Titik: A(1,1), B(1.5,2), C(4,4), D(5,7), E(3.5,5), F(4.5,5), G(3.5,4.5).\n",
    "Centroid awal: (1,1) dan (5,7). Tentukan klaster tiap titik dan centroid baru."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6c9c9d98",
   "metadata": {},
   "outputs": [],
   "source": [
    "P_ = np.array([[1, 1], [1.5, 2], [4, 4], [5, 7], [3.5, 5], [4.5, 5], [3.5, 4.5]])\n",
    "km = KMeans(2, init=np.array([[1, 1], [5, 7.0]]), n_init=1, max_iter=1).fit(P_)\n",
    "print(\"label   :\", km.labels_)\n",
    "print(\"centroid:\\n\", km.cluster_centers_)\n",
    "print(\"silhouette:\", round(silhouette_score(P_, km.labels_), 3))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dfde9259",
   "metadata": {},
   "source": [
    "## Soal 5 — DBSCAN (Minggu 11)\n",
    "\n",
    "Titik (0,0), (0,1), (1,0), (1,1), (2.5,1), (10,10); ε = 1.5, MinPts = 4.\n",
    "Tentukan core, border, noise."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "03f80df3",
   "metadata": {},
   "outputs": [],
   "source": [
    "Q = np.array([[0, 0], [0, 1], [1, 0], [1, 1], [2.5, 1], [10, 10]])\n",
    "db = DBSCAN(eps=1.5, min_samples=4).fit(Q)\n",
    "jenis = [\"noise\" if l == -1 else (\"core\" if i in db.core_sample_indices_ else \"border\")\n",
    "         for i, l in enumerate(db.labels_)]\n",
    "pd.DataFrame({\"titik\": list(map(tuple, Q)), \"jenis\": jenis})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2b6d0dc",
   "metadata": {},
   "source": [
    "## Soal 6 — HDFS & MapReduce (Minggu 12)\n",
    "\n",
    "a. File 1000 MB, blok 128 MB, replikasi 3: berapa blok dan total penyimpanan?\n",
    "b. Hitung frekuensi kata \"data\" di `dokumen_teks()` dengan pola map → shuffle → reduce."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cd15a1ee",
   "metadata": {},
   "outputs": [],
   "source": [
    "jawaban_saya = {\"blok\": None, \"total_mb\": None}\n",
    "cek(\"jumlah blok\", jawaban_saya[\"blok\"], math.ceil(1000 / 128), tol=0)\n",
    "cek(\"total MB\", jawaban_saya[\"total_mb\"], 1000 * 3, tol=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a90cf728",
   "metadata": {},
   "outputs": [],
   "source": [
    "peta = [(w, 1) for d in dokumen_teks() for w in d.split()]          # map\n",
    "grup = {}\n",
    "for w, v in peta:                                                   # shuffle\n",
    "    grup.setdefault(w, []).append(v)\n",
    "hasil = {w: sum(v) for w, v in grup.items()}                        # reduce\n",
    "print(\"frekuensi 'data':\", hasil[\"data\"], \"| cek Counter:\", Counter(w for d in dokumen_teks() for w in d.split())[\"data\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62035887",
   "metadata": {},
   "source": [
    "## Soal 7 — Stream, LSH, PageRank (Minggu 15)\n",
    "\n",
    "a. Decaying window c = 0.1, stream 10, 10, 10 → S₃?\n",
    "b. LSH b = 20, r = 5, s = 0.8 → P(kandidat)?\n",
    "c. Graf A→B, A→C, B→C, C→A, d = 0.85, mulai 1/3: PageRank setelah 1 iterasi?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dac504bb",
   "metadata": {},
   "outputs": [],
   "source": [
    "jawaban_saya = {\"S3\": None, \"p_lsh\": None, \"rA\": None, \"rB\": None, \"rC\": None}\n",
    "s = 0\n",
    "for x in [10, 10, 10]:\n",
    "    s = 0.9 * s + x\n",
    "cek(\"S3\", jawaban_saya[\"S3\"], s)\n",
    "cek(\"P(kandidat)\", jawaban_saya[\"p_lsh\"], 1 - (1 - 0.8 ** 5) ** 20)\n",
    "\n",
    "r0 = np.ones(3) / 3\n",
    "M = np.array([[0, 0, 1], [0.5, 0, 0], [0.5, 1, 0]])  # kolom = sumber A, B, C\n",
    "r1 = 0.15 / 3 + 0.85 * M @ r0\n",
    "for nama, val in zip([\"rA\", \"rB\", \"rC\"], r1):\n",
    "    cek(nama, jawaban_saya[nama], val)\n",
    "print(\"PageRank konvergen (networkx):\", {k: round(v, 4) for k, v in nx.pagerank(nx.DiGraph([(\"A\",\"B\"),(\"A\",\"C\"),(\"B\",\"C\"),(\"C\",\"A\")])).items()})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "12208e2d",
   "metadata": {},
   "source": [
    "## Soal 8 — Isolation Forest (Minggu 16)\n",
    "\n",
    "n = 256. Hitung c(n), lalu skor s untuk E[h(x)] = 3 dan E[h(x)] = 12."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5bfa47b2",
   "metadata": {},
   "outputs": [],
   "source": [
    "jawaban_saya = {\"c\": None, \"s3\": None, \"s12\": None}\n",
    "c = 2 * (math.log(255) + 0.5772156649) - 2 * 255 / 256\n",
    "cek(\"c(256)\", jawaban_saya[\"c\"], c)\n",
    "cek(\"s(E=3)\", jawaban_saya[\"s3\"], 2 ** (-3 / c))\n",
    "cek(\"s(E=12)\", jawaban_saya[\"s12\"], 2 ** (-12 / c))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "42efc660",
   "metadata": {},
   "source": [
    "## ✍️ Coba sendiri — Soal esai (tulis jawabanmu)\n",
    "\n",
    "1. Jelaskan perbedaan OLTP dan OLAP, dan di mana data warehouse berada dalam siklus KDD.\n",
    "2. Kapan kamu memilih Spark dibanding Pandas? Sebutkan minimal 3 kriteria.\n",
    "3. Jelaskan cara kerja hybrid autoencoder + Isolation Forest untuk 200 sensor.\n",
    "4. Rancang pertanyaan defense tersulit untuk proyekmu sendiri, lalu jawab."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd0f8858",
   "metadata": {},
   "source": [
    "**Jawaban:**\n",
    "\n",
    "1. ...\n",
    "2. ...\n",
    "3. ...\n",
    "4. ..."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "57dd71e1",
   "metadata": {},
   "source": [
    "## Selanjutnya\n",
    "Kerjakan kuis review UAS dan `exercise.py`, lalu jalankan `python check.py 18` dari folder utama."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
