Ada dua gaya bekerja dengan kode machine learning: menjalankan skrip seutuhnya, atau bereksperimen sepotong-sepotong sambil mengamati hasilnya. Jupyter Notebook melayani gaya kedua — dan untuk eksplorasi data, gaya ini jauh lebih produktif. Notebook menggabungkan kode, keluaran, visualisasi, dan catatan narasi dalam satu dokumen yang hidup. Chapter ini membahas cara memasang dan menjalankan JupyterLab, anatomi sel dan kernel, kapan notebook lebih tepat daripada skrip biasa, sampai membongkar format .ipynb yang ternyata hanyalah JSON.

Apa itu Notebook dan JupyterLab #

Tiga istilah perlu dipisahkan lebih dulu karena sering tertukar:

  • Notebook (*.ipynb): dokumen berisi kumpulan sel — kode, teks narasi, atau visualisasi — lengkap dengan keluaran eksekusi yang tersimpan di dalamnya.
  • JupyterLab: antarmuka berbasis peramban untuk mengedit notebook, berkas teks, dan terminal dalam satu ruang kerja. Inilah penerus tampilan klasik Jupyter Notebook.
  • Kernel: proses Python terpisah yang mengeksekusi sel kode notebook. Variabel yang Anda buat di satu sel disimpan kernel dan tetap hidup untuk sel berikutnya, sampai kernel dimatikan atau dimulai ulang.

Nama “Jupyter” sendiri adalah penghormatan kepada tiga bahasa awalnya — Julia, Python, dan R — dan proyek ini tumbuh dari IPython, shell interaktif Python yang dikembangkan sejak 2001. Untuk lingkungan belajar machine learning, kombinasi notebook + kernel Python memungkinkan alur kerja khas eksplorasi: muat data, lihat sepuluh baris pertama, buat grafik, ubah satu parameter, jalankan ulang satu sel saja — semuanya tanpa mengulang seluruh skrip dari awal.

Instalasi dan Menjalankan #

JupyterLab dipasang seperti pustaka lain — ke dalam venv proyek, bukan interpreter sistem:

bash
# pasang JupyterLab di venv proyek
python3 -m pip install jupyterlab

# jalankan antarmuka dari folder proyek
jupyter lab

Setelah server lokal menyala, peramban Anda akan terbuka pada alamat localhost:8888 lengkap dengan token keamanan — salin tautan yang tercetak di terminal jika peramban tidak membukanya otomatis. Selama sesi berlangsung, terminal tetap menampung server; tekan Ctrl+C di terminal tersebut ketika ingin menghentikannya. Karena notebook berjalan di atas venv, seluruh pustaka yang kita pasang pada chapter sebelumnya langsung tersedia di dalam kernel.

Anatomi Sel dan Kernel #

Notebook memiliki tiga jenis sel:

  1. Sel kode — dikirim ke kernel untuk dieksekusi; keluaran (teks, tabel, grafik) tampil tepat di bawahnya dan ikut tersimpan di berkas.
  2. Sel markdown — dirender sebagai teks berformat: judul, daftar, tautan, bahkan persamaan LaTeX untuk catatan metodologi.
  3. Sel mentah — teks apa adanya tanpa dieksekusi maupun dirender; jarang dipakai, biasanya untuk templat.

Setiap sel kode membawa nomor eksekusi (In [1], In [2], …) yang mencatat kapan sel dijalankan. Nomor ini penting karena kernel bersifat stateful: variabel dari sel nomor 5 masih tersedia saat Anda menjalankan sel nomor 3 — bahkan jika Anda mengubah sel 5 di antara keduanya.

Kapan Notebook, Kapan Skrip #

Notebook bukan pengganti skrip — keduanya punya wilayah kerja masing-masing:

AspekJupyter NotebookSkrip .py
Gaya kerjaInteraktif, sel demi selSekali jalan dari awal ke akhir
Kekuatan utamaEDA, visualisasi, narasi analisisOtomatisasi, pipeline, produksi
Kelemahan umumUrutan eksekusi bisa melompat-lompatIterasi lambat saat eksplorasi
Kontrol versiDiff JSON sulit dibacaDiff teks bersih
Cocok untuk tahapEksplorasi dan purwarupaPelatihan terjadwal, API, CI

Aturan praktis yang baik: notebook untuk menemukan (exploratory data analysis, uji hipotesis visual), skrip untuk mengulang (pelatihan model, evaluasi rutin, penyajian di produksi).

Format .ipynb adalah JSON Biasa #

Salah satu kesalahpahaman umum yang layak dibongkar: .ipynb bukan format biner misterius. Ia adalah berkas JSON dengan skema baku. Versi ringkasnya tampak seperti ini:

json
{
  "nbformat": 4,
  "nbformat_minor": 5,
  "metadata": {
    "kernelspec": {
      "name": "python3",
      "display_name": "Python 3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "id": "sel-judul",
      "metadata": {},
      "source": "# Analisis data pelanggan"
    },
    {
      "cell_type": "code",
      "id": "sel-kode",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": "print('Halo notebook')"
    }
  ]
}

Perhatikan anatomi pentingnya: nbformat mencatat versi skema; cells adalah daftar sel yang urut; setiap sel memiliki cell_type, source (bisa berupa string utuh atau daftar baris), dan id unik sejak skema 4.5. Sel kode tambahan membawa execution_count — null berarti belum pernah dijalankan — serta outputs yang akan terisi keluaran setelah eksekusi. Karena semua itu teks, notebook dapat dibaca, dibuat, dan dimanipulasi dari program Python biasa — seperti dua contoh berikut.

Membangun Notebook secara Programatik #

Pustaka nbformat adalah cara resmi membuat notebook dari kode. Skrip berikut membangun notebook dua sel, menyimpannya ke folder sementara, lalu membacanya kembali dengan modul json standar sebagai bukti formatnya:

python
# Anatomi berkas .ipynb: notebook Jupyter adalah berkas JSON biasa.
# Skrip ini membangun notebook kecil dengan nbformat, menyimpannya ke
# folder sementara, lalu membacanya kembali sebagai JSON murni.

import json
import tempfile
from pathlib import Path

import nbformat as nbf

nb = nbf.v4.new_notebook()
nb.cells = [
    nbf.v4.new_markdown_cell("# Latihan NumPy"),
    nbf.v4.new_code_cell(
        "import numpy as np\n"
        "rng = np.random.default_rng(42)\n"
        "print(rng.integers(0, 10, size=5))"
    ),
]

with tempfile.TemporaryDirectory() as tmp:
    berkas = Path(tmp) / "latihan.ipynb"
    nbf.write(nb, str(berkas))

    # Baca kembali sebagai JSON biasa untuk membuktikan formatnya.
    data = json.loads(berkas.read_text(encoding="utf-8"))

print("nbformat   :", data["nbformat"], f"(minor {data['nbformat_minor']})")
print("jumlah sel :", len(data["cells"]))
for i, sel in enumerate(data["cells"]):
    jenis = sel["cell_type"]
    # Field source bisa berupa string atau list baris; gabungkan dulu.
    sumber = sel["source"]
    if isinstance(sumber, list):
        sumber = "".join(sumber)
    baris_pertama = sumber.split("\n")[0]
    if jenis == "code":
        if sel["execution_count"] is None:
            status = "belum dieksekusi"
        else:
            status = f"dieksekusi {sel['execution_count']}x"
        print(f"sel {i}: code | {status} | {baris_pertama}")
    else:
        print(f"sel {i}: {jenis} | {baris_pertama}")

Output yang Dihasilkan:

text
nbformat   : 4 (minor 5)
jumlah sel : 2
sel 0: markdown | # Latihan NumPy
sel 1: code | belum dieksekusi | import numpy as np

Bedah singkat skrip di atas:

  1. Baris 5–9 (impor): json, tempfile, dan pathlib bawaan Python dipadukan dengan nbformat — pustaka resmi untuk skema notebook.
  2. Baris 11–19 (membangun sel): new_notebook() membuat kerangka kosong; new_markdown_cell() dan new_code_cell() mengisi sel bernarasi dan sel berkode. Isi sel kode ditulis sebagai beberapa string yang disambung agar mudah dibaca.
  3. Baris 21–26 (tulis dan baca ulang): notebook disimpan ke folder sementara dengan nbf.write(), lalu dibaca kembali memakai json.loads() — pembaca JSON standar, bukan pustaka khusus notebook. Inilah bukti bahwa .ipynb sungguh berformat JSON.
  4. Baris 28–36 (mengurai struktur): skrip menampilkan versi skema nbformat, jumlah sel, dan baris pertama tiap sel. Field source ditangani sebagai string maupun daftar baris karena skema mengizinkan dua bentuk tersebut.
  5. Baris 37–44: sel kode diperiksa execution_count-nya — notebook baru selalu menunjukkan belum dieksekusi karena belum pernah dijalankan kernel.

Mengeksekusi Notebook Tanpa Antarmuka #

Sifat JSON notebook membuka satu kemampuan penting untuk otomatisasi: notebook dapat dieksekusi tanpa membuka peramban. Pustaka nbclient menjalankan seluruh sel di dalam kernel sungguhan, mengumpulkan keluarannya, dan menuliskannya kembali ke berkas — teknik yang dipakai alat seperti jupyter nbconvert --execute dan papermill:

python
# Eksekusi notebook secara programatik dengan nbclient.
# Skrip ini menjalankan sel kode di dalam kernel sungguhan, lalu
# membuktikan output tersimpan permanen di dalam berkas .ipynb.

import tempfile
from pathlib import Path

import nbformat as nbf
from nbclient import NotebookClient

nb = nbf.v4.new_notebook()
nb.cells = [
    nbf.v4.new_markdown_cell("## Rata-rata nilai ujian"),
    nbf.v4.new_code_cell(
        "nilai = [70, 85, 90, 60]\n"
        "print('rata-rata:', sum(nilai) / len(nilai))"
    ),
]

klien = NotebookClient(nb, timeout=60, kernel_name="python3")
klien.execute()

sel_kode = nb.cells[1]
print("jenis sel      :", sel_kode.cell_type)
print("jumlah eksekusi:", sel_kode.execution_count)
for keluaran in sel_kode.outputs:
    if keluaran.output_type == "stream":
        teks = keluaran.text.rstrip("\n")
        print("output stream  :", teks)

with tempfile.TemporaryDirectory() as tmp:
    berkas = Path(tmp) / "latihan.ipynb"
    nbf.write(nb, str(berkas))

    # Baca kembali: output tetap tersimpan di dalam berkas.
    nb2 = nbf.read(str(berkas), as_version=4)
    teks_tersimpan = nb2.cells[1].outputs[0].text.rstrip("\n")
    print("tersimpan      :", teks_tersimpan)

Output yang Dihasilkan:

text
jenis sel      : code
jumlah eksekusi: 1
output stream  : rata-rata: 76.25
tersimpan      : rata-rata: 76.25

Poin penting dari bedah berikut:

  1. Baris 8–9: dua pustaka bekerja berpasangan — nbformat untuk struktur dokumen, nbclient untuk eksekusi.
  2. Baris 20–21 (NotebookClient(...).execute()): parameter kernel_name="python3" memilih kernel yang sama dengan yang dipakai JupyterLab, sementara timeout=60 membatasi durasi tiap sel. Panggilan execute() menyalakan kernel sungguhan di latar belakang, menjalankan semua sel berurutan, lalu mematikannya kembali.
  3. Baris 23–29: setelah eksekusi, keluaran menempel pada objek sel — execution_count menjadi 1 dan outputs berisi keluaran bertipe stream (teks dari print). Model data inilah yang dilihat JupyterLab saat menampilkan hasil di bawah sel.
  4. Baris 31–38 (persistensi): notebook dieksekusi ditulis ke berkas sementara, dibaca ulang, dan keluarannya masih utuh di dalamnya. Inilah alasan berkas .ipynb hasil sesi terlihat “gemuk”: keluaran dan grafik ikut tersimpan secara permanen di dalam dokumen.

Mengekspor Notebook ke Bentuk Lain #

Notebook yang sudah matang sering perlu diubah menjadi bentuk lain. Alat resminya adalah jupyter nbconvert:

bash
# ubah notebook menjadi skrip .py (sel markdown jadi komentar)
jupyter nbconvert --to script notebooks/01-eksplorasi.ipynb

# eksekusi semua sel dari terminal tanpa membuka peramban
jupyter nbconvert --to notebook --execute notebooks/01-eksplorasi.ipynb \
    --output 01-eksplorasi-tereksekusi.ipynb

Konversi ke .py menarik dilakukan menjelang akhir proyek: logika yang terbukti di notebook dipindahkan ke skrip agar bisa dijadwalkan, diuji, dan dikontrol versinya dengan rapi.

Kita kini punya interpreter yang benar, lingkungan yang terisolasi, pustaka yang terverifikasi, dan alat eksplorasi interaktif. Satu bahan terakhir sebelum masuk ke materi inti: tata letak folder proyek yang menjaga data, kode, dan artefak model tetap tertib. Lanjut ke Chapter Menyiapkan Struktur Proyek Machine Learning.

Referensi Resmi #