BelajarKoding Logobelajarkoding

Platform belajar web development Indonesia. Artikel, cheat sheets, roadmap, dan code challenges untuk developer Indonesia.

Navigasi

  • Artikel
  • Cheat Sheets
  • Roadmap
  • Challenges
  • Pricing
  • Search

Produk Lain

  • JagoHermes
  • KelasClaude
  • KilatKoding
  • BelajarVibeCoding
  • JualanKoding

Support

  • Privacy Policy
  • Terms of Service
  • Email

© 2026 BelajarKoding. All rights reserved.

Galih PratamaBagian dari ekosistem Galih Pratama
belajarkoding LogobyGalih Pratama
RoadmapArtikelCheat SheetsChallengesUpgrade
belajarkoding LogobyGalih Pratama
RoadmapArtikelCheat SheetsChallengesUpgrade
belajarkoding LogobyGalih Pratama
RoadmapArtikelCheat SheetsChallengesUpgrade

Daftar Isi

Peta masalahSiapkan dataPilih fitur dan buang kebocoranSkala numerikEncoding kategori dan sparse matrixJarak dan kemiripanK-MeansMemilih jumlah clusterMembaca centroidHierarchical clusteringDBSCAN dan HDBSCANGaussian Mixture ModelReduksi dimensiPCATruncatedSVD, t-SNE, dan UMAPEvaluasi clusterMetrik internalMetrik eksternalDeteksi anomali singkatPola kerja yang bisa diulangKesalahan yang sering bikin hasil menipuGlossary
Machine LearningUnsupervised LearningPythonscikit-learn

Unsupervised Learning Cheat Sheet

Referensi cepat unsupervised learning. Clustering, reduksi dimensi, PCA, K-Means, DBSCAN, evaluasi cluster, dan preprocessing data. Buat AI engineer yang mengolah data tanpa label.

Python12 min read2.283 kata
Silakan login atau daftar untuk membaca cheat sheet ini.

#Peta masalah

Unsupervised learning mencari struktur pada data yang tidak punya target y. Kamu memberi matriks fitur X, lalu algoritme mencoba menemukan kelompok, arah variasi, atau titik yang menyimpang. Hasilnya bukan jawaban mutlak. Ia hipotesis yang perlu kamu cek dengan pengetahuan domain.

Pakai supervised learning saat kamu punya label seperti churn atau fraud. Pakai unsupervised learning saat kamu ingin membagi pelanggan, menemukan dokumen mirip, mengurangi ribuan fitur menjadi beberapa komponen, atau menandai transaksi aneh sebelum label tersedia.

TujuanKeluaran umumContoh metode
Segmentasilabel clusterK-Means, Gaussian Mixture, DBSCAN
Visualisasi atau kompresifitur berdimensi lebih kecilPCA, TruncatedSVD, UMAP
Deteksi anomaliskor atau label anomaliIsolation Forest, Local Outlier Factor
Pencarian pola itemkomponen laten atau aturanNMF, topic modeling, association rules

Jangan menganggap cluster sebagai fakta bisnis hanya karena grafiknya terlihat rapi. Jika satu cluster sulit dijelaskan, bisa jadi fitur, skala, atau metode yang kamu pilih tidak cocok.

#Siapkan data

#Pilih fitur dan buang kebocoran

Setiap kolom memberi definisi jarak. Kolom pendapatan bulanan, jumlah pesanan, dan hari sejak pesanan terakhir masuk akal untuk segmentasi pelanggan. ID pelanggan tidak. ID acak membuat dua baris tampak jauh padahal tidak ada arti bisnisnya.

Hapus target yang baru kamu ketahui setelah kejadian, misalnya is_churned, saat tujuanmu mencari kelompok pelanggan sebelum churn. Itu kebocoran informasi. Periksa juga duplikasi, unit berbeda, nilai hilang, dan kategori dengan ejaan yang tidak konsisten.

python
import pandas as pd
 
features = ["orders_90d", "spend_90d", "days_since_last_order"]
X = customers[features].copy()
 
# Nilai hilang tidak boleh masuk mentah ke K-Means atau PCA.
X = X.fillna(X.median())

#Skala numerik

K-Means, PCA, nearest neighbors, dan DBSCAN berbasis jarak. Fitur berskala besar akan mendominasi hasil. Jika spend_90d bernilai jutaan dan orders_90d bernilai puluhan, Euclidean distance lebih banyak berbicara tentang uang daripada frekuensi pesanan.

StandardScaler memusatkan fitur ke rata-rata 0 dan skala deviasi standar 1. RobustScaler lebih tahan terhadap outlier karena memakai median dan interquartile range. Untuk data sangat miring, pertimbangkan log1p sebelum scaling.

python
import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
 
X["spend_90d"] = np.log1p(X["spend_90d"])
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

Jangan menormalisasi kolom biner secara refleks. Untuk data campuran numerik dan kategorikal, ColumnTransformer lebih aman daripada memaksa semua kolom ke satu preprocessing yang sama.

python
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
 
preprocess = ColumnTransformer([
    ("num", StandardScaler(), ["orders_90d", "spend_90d"]),
    ("cat", OneHotEncoder(handle_unknown="ignore"), ["city", "channel"]),
])

#Encoding kategori dan sparse matrix

OneHotEncoder cocok untuk kategori nominal seperti kota atau channel akuisisi. Hati-hati pada kolom dengan ribuan nilai unik, misalnya nama produk atau email. One hot encoding dapat membuat matriks sangat lebar dan jarak antarbari menjadi kurang bermakna.

Untuk teks, gunakan TfidfVectorizer lalu cosine similarity atau TruncatedSVD. Pada data sparse seperti TF-IDF, jangan gunakan StandardScaler(with_mean=True) karena pemusatan akan mengubah matriks sparse menjadi padat dan boros memori.

python
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.decomposition import TruncatedSVD
 
vectorizer = TfidfVectorizer(stop_words="english", max_df=0.8, min_df=3)
X_tfidf = vectorizer.fit_transform(documents)
X_reduced = TruncatedSVD(n_components=100, random_state=42).fit_transform(X_tfidf)

#Jarak dan kemiripan

Pemilihan metrik jarak menentukan bentuk cluster yang bisa ditemukan.

MetrikRumus ringkasCocok untuk
Euclideanakar jumlah kuadrat selisihdata numerik berskala serupa
Manhattanjumlah nilai absolut selisihdata numerik yang lebih tahan terhadap satu selisih besar
Cosine distance1 - cosine_similaritydokumen, embedding, vektor arah
Hammingjumlah posisi yang berbedafitur biner atau kategori yang sudah diencode
Jaccard distance1 - intersection / unionset tag, fitur biner yang sparse

Euclidean distance sensitif pada outlier. Cosine similarity tidak peduli panjang vektor, hanya arah. Untuk embedding teks yang sudah L2 normalized, cosine dan Euclidean punya hubungan monotonic, tapi tetap gunakan metrik yang sesuai dengan cara embedding itu dilatih.

python
from sklearn.metrics.pairwise import cosine_similarity
 
similarities = cosine_similarity(embeddings)
nearest_index = similarities[0].argsort()[-6:-1][::-1]
print(nearest_index)

#K-Means

K-Means membagi data menjadi k cluster dengan centroid. Algoritme bergantian antara dua langkah: tiap titik masuk ke centroid terdekat, lalu tiap centroid dipindah ke rata-rata titik anggotanya. Proses berhenti saat penugasan atau centroid stabil.

K-Means mencari nilai inertia kecil, yaitu jumlah kuadrat jarak setiap titik ke centroid clusternya. Metode ini paling masuk akal saat cluster cenderung bulat, padat, dan ukurannya mirip. Ia buruk untuk bentuk bulan sabit, kepadatan yang berbeda jauh, atau data dengan banyak outlier.

python
from sklearn.cluster import KMeans
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
 
model = Pipeline([
    ("scale", StandardScaler()),
    ("cluster", KMeans(n_clusters=4, n_init="auto", random_state=42)),
])
 
labels = model.fit_predict(X)
customers["cluster"] = labels
centers = model.named_steps["cluster"].cluster_centers_

random_state membuat inisialisasi dapat diulang. n_init="auto" meminta scikit-learn menjalankan inisialisasi sesuai strategi yang dipakai. Untuk data penting, coba beberapa seed dan lihat apakah anggota cluster stabil. Satu nilai inertia tidak cukup untuk percaya diri.

#Memilih jumlah cluster

Elbow method mencari titik saat tambahan cluster hanya sedikit menurunkan inertia. Namun elbow kadang tidak jelas. Silhouette score, stabilitas antarsampel, biaya operasional, dan keterbacaan segmen sama pentingnya.

python
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
 
scores = []
for k in range(2, 11):
    labels = KMeans(n_clusters=k, n_init="auto", random_state=42).fit_predict(X_scaled)
    scores.append({"k": k, "silhouette": silhouette_score(X_scaled, labels)})
 
print(pd.DataFrame(scores))

Jangan mulai dari k=1 untuk silhouette. Metrik itu hanya terdefinisi jika ada minimal dua label dan jumlah label lebih kecil dari jumlah sampel.

#Membaca centroid

Centroid dari data yang sudah distandardisasi sulit dibaca langsung. Profilkan label dengan data pada skala asli. Beri nama segmentasi setelah melihat angkanya, bukan sebelum proses clustering.

python
profile = (
    customers.groupby("cluster")
    .agg(
        customers=("customer_id", "size"),
        avg_orders=("orders_90d", "mean"),
        avg_spend=("spend_90d", "mean"),
        avg_recency=("days_since_last_order", "mean"),
    )
    .round(1)
)
print(profile)

#Hierarchical clustering

Agglomerative clustering mulai dari tiap titik sebagai cluster sendiri, lalu menggabungkan pasangan terdekat sampai jumlah cluster yang kamu tentukan. Hasilnya dapat ditampilkan sebagai dendrogram. Ini berguna saat kamu ingin melihat hubungan bertingkat, misalnya kategori produk.

linkage menentukan jarak antarcluster. ward cenderung membuat cluster padat dan hanya cocok untuk Euclidean distance. complete memakai jarak titik paling jauh. average memakai rata-rata jarak pasangan titik.

python
from sklearn.cluster import AgglomerativeClustering
 
hierarchical = AgglomerativeClustering(
    n_clusters=4,
    linkage="ward",
)
labels = hierarchical.fit_predict(X_scaled)

Kelemahannya: biaya komputasi dapat besar saat sampel bertambah. Untuk jutaan baris, mulai dari MiniBatchKMeans atau lakukan sampling saat eksplorasi.

#DBSCAN dan HDBSCAN

DBSCAN mencari area padat. Ia memakai eps sebagai radius tetangga dan min_samples sebagai jumlah titik minimum untuk menganggap area padat. Titik inti punya cukup tetangga. Titik batas menempel pada titik inti. Titik yang tidak masuk cluster diberi label -1 sebagai noise.

DBSCAN tidak meminta nilai k di awal dan bisa menemukan bentuk cluster tidak bulat. Tapi satu nilai eps sulit bekerja jika kepadatan tiap kelompok jauh berbeda. HDBSCAN sering lebih nyaman untuk data dengan kepadatan bervariasi, walau bukan bagian dari scikit-learn inti.

python
from sklearn.cluster import DBSCAN
from sklearn.preprocessing import StandardScaler
 
X_scaled = StandardScaler().fit_transform(X)
model = DBSCAN(eps=0.45, min_samples=8)
labels = model.fit_predict(X_scaled)
 
noise_rate = (labels == -1).mean()
print(f"Noise: {noise_rate:.1%}")

Untuk menaksir eps, hitung jarak ke tetangga ke-min_samples, urutkan, lalu lihat titik tekuk pada grafik k-distance. Ini hanya titik awal. Uji parameter dan cek apakah cluster masih bisa dijelaskan.

python
from sklearn.neighbors import NearestNeighbors
import matplotlib.pyplot as plt
 
neighbors = NearestNeighbors(n_neighbors=8).fit(X_scaled)
distances, _ = neighbors.kneighbors(X_scaled)
k_distances = np.sort(distances[:, -1])
plt.plot(k_distances)
plt.ylabel("Jarak tetangga ke-8")
plt.xlabel("Sampel setelah diurutkan")
plt.show()

Jangan memasukkan label noise ke silhouette score secara buta. Ukur dengan dan tanpa noise, lalu jelaskan keputusanmu. Menghapus noise bisa menaikkan skor sambil menyembunyikan masalah parameter.

#Gaussian Mixture Model

Gaussian Mixture Model atau GMM menganggap data berasal dari campuran beberapa distribusi Gaussian. Berbeda dengan K-Means yang memberi satu label keras, GMM memberi probabilitas anggota setiap cluster. Ini berguna saat batas kelompok tidak tegas.

python
from sklearn.mixture import GaussianMixture
 
gmm = GaussianMixture(
    n_components=4,
    covariance_type="full",
    n_init=5,
    random_state=42,
)
gmm.fit(X_scaled)
labels = gmm.predict(X_scaled)
probabilities = gmm.predict_proba(X_scaled)
 
customers["cluster"] = labels
customers["cluster_confidence"] = probabilities.max(axis=1)

covariance_type="full" memberi tiap komponen matriks kovarians sendiri. Lebih fleksibel, juga lebih mahal. diag menganggap fitur tidak berkorelasi dalam komponen. Pilih jumlah komponen dengan BIC atau AIC, lalu cek hasilnya secara domain.

python
rows = []
for k in range(1, 11):
    model = GaussianMixture(n_components=k, n_init=3, random_state=42).fit(X_scaled)
    rows.append({"k": k, "aic": model.aic(X_scaled), "bic": model.bic(X_scaled)})
print(pd.DataFrame(rows))

Nilai AIC dan BIC lebih kecil lebih baik untuk perbandingan model pada data yang sama. Mereka bukan skor kualitas bisnis.

#Reduksi dimensi

#PCA

Principal Component Analysis atau PCA memutar ruang fitur ke arah dengan variasi terbesar. Komponen pertama menangkap variasi paling besar, komponen kedua menangkap variasi terbesar yang tegak lurus komponen pertama, lalu seterusnya. PCA sering dipakai sebelum K-Means untuk mengurangi noise dan mempercepat perhitungan.

PCA mengasumsikan hubungan linear dan sensitif terhadap skala, jadi standardisasi biasanya perlu. explained_variance_ratio_ memberi proporsi variasi yang ditangkap setiap komponen.

python
from sklearn.decomposition import PCA
from sklearn.pipeline import Pipeline
 
pipeline = Pipeline([
    ("scale", StandardScaler()),
    ("pca", PCA(n_components=0.9, random_state=42)),
])
X_pca = pipeline.fit_transform(X)
print(X_pca.shape)
print(pipeline.named_steps["pca"].explained_variance_ratio_)

n_components=0.9 memilih komponen minimum yang menjelaskan setidaknya 90 persen variasi. Angka itu bukan aturan wajib. Untuk visualisasi dua dimensi, kamu sengaja membuang informasi. Jangan menilai kualitas cluster hanya dari plot 2D.

#TruncatedSVD, t-SNE, dan UMAP

TruncatedSVD mirip PCA tetapi cocok untuk matriks sparse seperti TF-IDF karena tidak memusatkan data. t-SNE dan UMAP bagus untuk visualisasi struktur lokal, bukan alat default untuk feature engineering produksi. Posisi global pada plot t-SNE dapat menipu, ukuran cluster pada gambar juga tidak menyatakan ukuran populasi.

python
from sklearn.decomposition import TruncatedSVD
from sklearn.manifold import TSNE
 
X_svd = TruncatedSVD(n_components=100, random_state=42).fit_transform(X_tfidf)
X_plot = TSNE(n_components=2, perplexity=30, random_state=42).fit_transform(X_svd)

Jika kamu memakai t-SNE setelah clustering, warnai titik dengan label yang sudah dihitung dari ruang fitur asli. Jangan menjalankan K-Means pada koordinat t-SNE lalu menganggap hasilnya final.

#Evaluasi cluster

#Metrik internal

Silhouette coefficient tiap titik memakai a, rata-rata jarak ke titik dalam cluster sendiri, dan b, rata-rata jarak ke cluster terdekat lain.

silhouette = (b - a) / max(a, b)

Nilai mendekati 1 berarti titik dekat dengan clusternya dan jauh dari cluster lain. Nilai sekitar 0 berarti area tumpang tindih. Nilai negatif memberi sinyal titik lebih mirip cluster lain.

MetrikArah baikCatatan
Inertialebih kecilselalu turun saat k naik
Silhouettelebih besarbias ke cluster padat dan terpisah
Davies-Bouldinlebih kecilmembandingkan sebaran dengan jarak centroid
Calinski-Harabaszlebih besarrasio dispersi antarcluster terhadap dalam cluster
python
from sklearn.metrics import (
    calinski_harabasz_score,
    davies_bouldin_score,
    silhouette_score,
)
 
print("silhouette", silhouette_score(X_scaled, labels))
print("davies_bouldin", davies_bouldin_score(X_scaled, labels))
print("calinski_harabasz", calinski_harabasz_score(X_scaled, labels))

Metrik internal mengukur geometri, bukan kegunaan. Dua cluster dengan silhouette tinggi tetap tidak berguna jika tim marketing tidak bisa mengambil tindakan berbeda untuk masing-masing kelompok.

#Metrik eksternal

Jika kamu punya label referensi untuk audit, jangan melatih dengan label itu lalu mengklaim unsupervised. Gunakan label hanya sesudah clustering untuk memeriksa kecocokan. Adjusted Rand Index atau ARI mengukur kesamaan dua partisi dengan koreksi peluang.

python
from sklearn.metrics import adjusted_rand_score
 
# audit_label tidak masuk ke X dan tidak dipakai saat fit.
ari = adjusted_rand_score(audit_label, labels)
print(ari)

#Deteksi anomali singkat

Anomali adalah observasi yang jauh atau jarang relatif terhadap data lain. Label anomali tidak selalu berarti fraud. Ia berarti data layak diperiksa.

python
from sklearn.ensemble import IsolationForest
 
anomaly_model = IsolationForest(
    contamination=0.02,
    random_state=42,
)
customers["anomaly"] = anomaly_model.fit_predict(X_scaled)
customers["anomaly_score"] = -anomaly_model.score_samples(X_scaled)
 
review_queue = customers.query("anomaly == -1").sort_values("anomaly_score", ascending=False)

contamination adalah asumsi proporsi outlier untuk menentukan ambang. Jangan isi angka ini tanpa dasar. Jika fraud asli hanya muncul setelah investigasi, simpan keputusan reviewer untuk membangun dataset berlabel di iterasi berikutnya.

#Pola kerja yang bisa diulang

  1. Definisikan keputusan yang ingin dibantu, misalnya strategi retensi per segmen.
  2. Pilih fitur yang tersedia sebelum keputusan dibuat.
  3. Bersihkan nilai hilang, outlier yang jelas salah, dan unit yang tidak seragam.
  4. Buat pipeline preprocessing agar proses fit dan transform konsisten.
  5. Bandingkan dua atau tiga metode dengan beberapa parameter dan seed.
  6. Buat profil setiap cluster memakai data asli.
  7. Minta pemilik domain memeriksa contoh anggota dari tiap cluster.
  8. Pantau drift. Segmentasi Januari bisa tidak cocok untuk perilaku pelanggan Juli.
python
from sklearn.pipeline import Pipeline
from sklearn.cluster import KMeans
 
segmenter = Pipeline([
    ("preprocess", preprocess),
    ("cluster", KMeans(n_clusters=4, n_init="auto", random_state=42)),
])
segmenter.fit(train_customers)
new_labels = segmenter.predict(new_customers)

Simpan versi fitur, parameter, tanggal data, dan aturan preprocessing. Tanpa itu, kamu tidak bisa menjelaskan kenapa pelanggan pindah cluster pada run berikutnya.

#Kesalahan yang sering bikin hasil menipu

  • Menjalankan K-Means pada kolom belum diskalakan.
  • Menganggap k yang memberi silhouette tertinggi selalu jawaban terbaik.
  • Memberi nama cluster sebelum melihat distribusi anggotanya.
  • Membaca plot 2D PCA atau t-SNE seolah itu seluruh ruang fitur.
  • Memasukkan customer ID, timestamp mentah, atau kategori ber-cardinality tinggi tanpa pertimbangan.
  • Membuang semua noise DBSCAN agar skor terlihat lebih bagus.
  • Menyimpulkan sebab akibat dari cluster. Cluster menggambarkan pola bersama, bukan alasan satu variabel menyebabkan variabel lain.
  • Menjalankan clustering sekali, lalu tidak memeriksa perubahan data atau kualitas segmen lagi.

#Glossary

IstilahArti praktis
CentroidTitik rata-rata anggota cluster pada K-Means.
ClusterKelompok observasi yang mirip menurut fitur dan metrik jarak yang kamu pilih.
CovarianceUkuran bagaimana dua fitur berubah bersama. GMM memakai ini untuk bentuk komponen.
Curse of dimensionalityJarak antar titik makin sulit dibedakan saat jumlah fitur sangat besar.
DensityBanyaknya titik dalam area lokal. DBSCAN memakai konsep ini untuk cluster.
EmbeddingVektor numerik yang mengkodekan makna atau karakteristik objek.
InertiaJumlah kuadrat jarak titik ke centroid clusternya dalam K-Means.
NoiseTitik yang DBSCAN tidak masukkan ke cluster, diberi label -1.
PCAMetode linear untuk memadatkan fitur ke principal component.
Silhouette scoreUkuran seberapa dekat titik dengan clusternya dibanding cluster terdekat lain.
StandardisasiMengubah fitur agar rata-rata 0 dan deviasi standar 1.

Baca Cheat Sheet Lengkap

Login atau daftar akun gratis untuk membaca cheat sheet ini.

LoginDaftar Gratis
Share: