Pipeline prediksi dari chapter sebelumnya kini bisa menerima data mentah — tetapi hanya dari dalam sesi Python kita sendiri. Aplikasi kasir tidak bisa mengimpor notebook, dan tim pemasaran tidak akan membuka terminal untuk memanggil predict_proba. Jembatan yang lazim dipakai industri adalah API model: model dibungkus menjadi layanan web yang menerima permintaan terstruktur dan mengembalikan jawaban terstruktur, sehingga siapa pun dengan akses jaringan bisa memakai model tanpa menyentuh Python. Pada chapter ini kita kenali konsep REST terlebih dahulu, lalu membangun kerangka layanan prediksi dengan FastAPI — tanpa menjalankan server, cukup definisi aplikasinya.

API dan REST dalam Beberapa Paragraf #

API (Application Programming Interface) adalah kontrak bagaimana satu program memanggil program lain. Pada konteks model, kontrak itu berwujud HTTP: aplikasi pengirim (klien) mengirim permintaan ke alamat tertentu, layanan model (server) mengirim balasan. Gaya perancangan yang paling umum adalah REST: setiap fungsi layanan dibuka lewat alamat bernama endpoint — misalnya /predict — dan operasinya dipilih lewat method HTTP seperti GET atau POST. Data pertukaran hampir selalu berformat JSON karena ringan dan terbaca semua bahasa pemrograman.

Untuk layanan prediksi kita, bagian-bagian permintaannya tampak seperti ini:

Bagian permintaanNilai pada layanan churn kitaPerannya
MethodPOSTmengirim data di badan permintaan, bukan sekadar meminta halaman
Path/predictalamat endpoint yang menandakan “prediksikan pelanggan ini”
HeaderContent-Type: application/jsonmemberi tahu server bahwa badan permintaan berformat JSON
Body{"kunjungan": 2, "belanja": 300}fitur pelanggan yang akan diprediksi
Response{"peluang_churn": 0.989, "label": "churn"}jawaban layanan dalam JSON yang sama terstruktur

Dua pertanyaan desain menentukan kontrak ini: bentuk data apa yang diterima, dan bentuk jawaban apa yang dikembalikan. Kita sengaja menerima kamus sederhana berisi dua fitur dan mengembalikan peluang plus label — kontrak sekecil mungkin yang tetap berfungsi penuh, sesuai prinsip mulai dari yang paling sederhana yang kita pelihara sejak awal Course.

Membangun Aplikasi FastAPI #

FastAPI adalah framework Python untuk membangun layanan web dengan kode sedikit dan dokumentasi otomatis. Kode berikut membangun seluruh kerangka layanan prediksi churn kita. Perhatikan bahwa tidak ada satu baris pun yang menjalankan server — kita cukup mendefinisikan aplikasi, lalu membuktikan logikanya dengan memanggil fungsi endpoint secara langsung seperti fungsi Python biasa.

python
import numpy as np
from fastapi import FastAPI
from sklearn.linear_model import LogisticRegression

rng = np.random.default_rng(42)
n = 60
kunjungan = rng.integers(1, 15, n)
belanja = rng.integers(50, 350, n)
skor = 0.8 * (8 - kunjungan) + 0.02 * (belanja - 180) + rng.normal(0, 3, n)
churn = (skor > np.quantile(skor, 0.6)).astype(int)
X = np.column_stack([kunjungan, belanja])
model = LogisticRegression(max_iter=1000).fit(X, churn)

app = FastAPI(title="API Model Churn Toko Kopi Kita")


@app.post("/predict")
def prediksi(pelanggan: dict):
    fitur = np.array([[pelanggan["kunjungan"], pelanggan["belanja"]]])
    peluang = float(model.predict_proba(fitur)[0, 1])
    return {
        "peluang_churn": round(peluang, 3),
        "label": "churn" if peluang >= 0.5 else "bertahan",
    }


permintaan_1 = {"kunjungan": 2, "belanja": 300}
permintaan_2 = {"kunjungan": 12, "belanja": 90}
print("permintaan 1:", permintaan_1)
print("jawaban    1:", prediksi(permintaan_1))
print("permintaan 2:", permintaan_2)
print("jawaban    2:", prediksi(permintaan_2))
print("jumlah rute terdaftar:", len(app.routes))

Output yang Dihasilkan:

text
permintaan 1: {'kunjungan': 2, 'belanja': 300}
jawaban    1: {'peluang_churn': 0.989, 'label': 'churn'}
permintaan 2: {'kunjungan': 12, 'belanja': 90}
jawaban    2: {'peluang_churn': 0.007, 'label': 'bertahan'}
jumlah rute terdaftar: 5

Mari kita telaah bagian-bagian pentingnya:

  1. Baris 12 (model di memori layanan): pada layanan sungguhan, model dimuat dari artefak joblib buatan chapter Menyimpan Model ; di sini kita melatihnya langsung agar contoh berdiri sendiri. Struktur kode produksinya sama, hanya baris pemuatan yang berbeda.
  2. Baris 14 (aplikasi FastAPI): objek app adalah wadah seluruh layanan; title-nya kelak muncul di dokumentasi otomatis yang dihasilkan FastAPI.
  3. Baris 17-18 (decorator dan fungsi endpoint): @app.post("/predict") mendaftarkan fungsi prediksi sebagai penangani method POST pada path /predict. Parameter pelanggan: dict memberi tahu FastAPI bahwa badan permintaan JSON akan diterima sebagai kamus.
  4. Baris 19-24 (inti layanan): kamus masukan diubah menjadi array fitur, model menghasilkan peluang, lalu jawaban dirakit sebagai kamus JSON — peluang dibulatkan tiga angka dan label diturunkan dari ambang 0,5.
  5. Baris 27-33 (uji tanpa server): kita memanggil prediksi(...) secara langsung untuk membuktikan logikanya. len(app.routes) memperlihatkan lima rute terdaftar: empat rute bawaan FastAPI (dokumentasi OpenAPI, /docs, dan sejenisnya) plus satu rute milik kita.

Menjalankan dan Memanggil Layanan #

Di lingkungan produksi, aplikasi ini dijalankan oleh server ASGI seperti uvicorn yang mendengarkan permintaan HTTP masuk. Perintah berikut adalah pola pemakaiannya — kita tidak menjalankannya di sesi materi ini karena cukup definisi di atas untuk memahami keseluruhan struktur:

bash
# Menjalankan layanan prediksi di mesin produksi:
# uvicorn main:app --host 0.0.0.0 --port 8000
#
# Mengirim satu permintaan prediksi dari terminal lain:
# curl -X POST http://localhost:8000/predict \
#   -H "Content-Type: application/json" \
#   -d '{"kunjungan": 2, "belanja": 300}'

Begitu layanan hidup, aplikasi kasir cukup mengirim permintaan POST dan membaca JSON jawabannya — tanpa perlu tahu bahwa di baliknya ada scikit-learn, penskalaan, atau koefisien regresi. Pemisahan inilah guna utama API: detail implementasi bersembunyi di balik kontrak yang stabil.

Rangkuman #

  • API model membungkus pipeline prediksi menjadi layanan HTTP: klien mengirim JSON berisi fitur, layanan mengembalikan JSON berisi peluang dan label.
  • Kontrak layanan kita: POST /predict dengan badan {"kunjungan": ..., "belanja": ...} dan jawaban {"peluang_churn": ..., "label": ...} — sekecil mungkin tetapi lengkap.
  • FastAPI mendefinisikan endpoint lewat decorator @app.post("/predict"); aplikasi bisa dibangun dan diuji logikanya tanpa menjalankan server.
  • Di produksi, uvicorn menjalankan aplikasi dan klien memanggil lewat HTTP; model sebaiknya dimuat dari artefak, bukan dilatih ulang di dalam layanan.

Layanan semacam ini bersinar ketika prediksi dibutuhkan seketika: satu pelanggan, satu permintaan, satu jawaban. Namun banyak kebutuhan kedai justru berbeda — daftar seluruh pelanggan mingguan diproses sekaligus, sekali seminggu, tanpa keharusan seketika. Pola itu adalah prediksi batch, bahasan chapter berikutnya: Menjalankan Prediksi Batch .

Referensi: