Pembelajaran Tak Terawasi
What Is Unsupervised Learning?
Berbeda dari Supervised Learning yang belajar dari label, Unsupervised Learning menemukan pola tersembunyi dalam data secara mandiri — tanpa panduan jawaban yang benar. Ini seperti membiarkan model menjelajahi data sendiri dan menemukan strukturnya.
Supervised vs Unsupervised Learning
Perbedaan mendasar keduanya terletak pada ada tidaknya label (y). Di Supervised Learning, kita punya pasangan (X, y). Di Unsupervised Learning, kita hanya punya X — dan tugas model adalah menemukan struktur di dalamnya sendiri.
Dua Tugas Utama Unsupervised Learning
🔵 Clustering
Mengelompokkan data yang mirip ke dalam satu kelompok (cluster) tanpa tahu nama kelompoknya terlebih dahulu. Algoritma mencari sendiri batas antar kelompok berdasarkan jarak atau kemiripan.
K-Means DBSCAN Hierarchical
📉 Dimensionality Reduction
Menyederhanakan data berdimensi tinggi menjadi representasi yang lebih kecil, sambil mempertahankan informasi paling penting. Berguna untuk visualisasi dan mempercepat model ML.
PCA t-SNE UMAP
Kapan Menggunakan Unsupervised Learning?
-
1Data Tidak Punya Label Dalam banyak skenario nyata, melabeli data membutuhkan waktu dan biaya yang sangat besar. Unsupervised Learning memungkinkan kita mengekstrak nilai dari data yang belum dilabeli.
-
2Eksplorasi Awal — Memahami Struktur Data Sebelum membangun model prediktif, clustering dan PCA membantu kita memahami apakah ada kelompok alami dalam data, outlier tersembunyi, atau fitur yang redundan.
-
3Generasi Fitur Baru (Feature Engineering) Hasil clustering bisa dijadikan fitur baru untuk model supervised. Hasil PCA bisa menggantikan ratusan fitur asli dengan sedikit komponen yang merangkum informasi terpenting.
-
4Deteksi Anomali Data yang tidak cocok di cluster manapun bisa dianggap sebagai anomali — berguna untuk fraud detection, network intrusion, atau quality control manufaktur.
| Aspek | Supervised Learning | Unsupervised Learning |
|---|---|---|
| Data yang Dibutuhkan | X dan y (berlabel) | Hanya X (tanpa label) |
| Tujuan | Prediksi nilai/kelas | Temukan struktur/pola |
| Evaluasi | Akurasi, F1, RMSE, dll. | Silhouette, Inertia, visualisasi |
| Contoh Tugas | Klasifikasi spam, prediksi harga | Segmentasi pelanggan, kompresi data |
| Kesulitan Utama | Butuh data berlabel (mahal) | Validasi hasil lebih sulit |
🧠 Uji Pemahaman
K-Means Clustering Explained
K-Means adalah algoritma clustering paling populer di dunia. Idenya sederhana namun powerful: temukan K titik pusat (centroid) yang mewakili K kelompok, lalu iterasi hingga setiap titik data menetap di kelompok paling tepat.
Algoritma K-Means — 4 Langkah Sederhana
K-Means bekerja melalui proses iteratif yang terus berulang hingga centroid tidak lagi bergerak (konvergen). Setiap iterasi terdiri dari dua langkah utama: Assignment dan Update.
-
1Inisialisasi — Tempatkan K Centroid Secara Acak Pilih K titik secara acak sebagai centroid awal. Kualitas inisialisasi sangat mempengaruhi hasil akhir. Metode
K-Means++(default sklearn) menggunakan strategi cerdas agar centroid awal tersebar merata. -
2Assignment — Tetapkan Setiap Titik ke Centroid Terdekat Hitung jarak Euclidean dari setiap titik data ke semua centroid. Setiap titik bergabung dengan cluster yang centroid-nya paling dekat.
-
3Update — Geser Centroid ke Rata-Rata Cluster Hitung ulang posisi setiap centroid sebagai rata-rata koordinat semua titik dalam cluster-nya. Centroid bergerak mendekati “pusat berat” kelompoknya.
-
4Ulangi Langkah 2–3 Hingga Konvergen Proses berlanjut sampai tidak ada titik yang berpindah cluster (centroid tidak bergerak lagi). Biasanya hanya butuh 10–50 iterasi.
🎮 Simulator K-Means Interaktif
Klik Step untuk melihat satu iterasi K-Means secara live, atau Run All untuk langsung animasi hingga konvergen. Ubah nilai K untuk melihat perbedaan hasil clustering.
Implementasi K-Means dengan Scikit-learn
import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler from sklearn.datasets import make_blobs # ── Generate dataset sintetis ── X, y_true = make_blobs( n_samples=300, centers=4, cluster_std=0.8, random_state=42 ) # ── PENTING: Selalu scale sebelum K-Means ── scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # ── Inisialisasi & Training K-Means ── kmeans = KMeans( n_clusters=4, # Jumlah cluster yang diinginkan init='k-means++', # Inisialisasi cerdas (hindari local minima) n_init=10, # Ulangi 10x dengan inisialisasi berbeda max_iter=300, # Maksimum iterasi per run random_state=42 ) kmeans.fit(X_scaled) # ── Hasil ── labels = kmeans.labels_ # Cluster untuk setiap titik centers = kmeans.cluster_centers_ # Posisi centroid akhir inertia = kmeans.inertia_ # WCSS (semakin kecil = semakin rapat) n_iter = kmeans.n_iter_ # Jumlah iterasi hingga konvergen print(f"Inertia : {inertia:.2f}") print(f"Konvergen : {n_iter} iterasi") print(f"Distribusi cluster: {np.bincount(labels)}") # ── Visualisasi hasil clustering ── colors = ['#00c9ff', '#00e5a0', '#ff6b9d', '#ffd166'] plt.figure(figsize=(8, 6)) for i in range(4): mask = labels == i plt.scatter(X_scaled[mask, 0], X_scaled[mask, 1], c=colors[i], alpha=0.7, s=40, label=f'Cluster {i+1}') plt.scatter(centers[:, 0], centers[:, 1], c='white', s=200, marker='*', zorder=5, edgecolors='black', linewidths=1.5, label='Centroid') plt.title('K-Means Clustering Result (K=4)') plt.legend(); plt.show()
# Setelah model terlatih, prediksi cluster data baru new_data = np.array([[1.5, -0.8], [-2.1, 3.2], [0.3, 0.1]]) new_scaled = scaler.transform(new_data) predicted = kmeans.predict(new_scaled) print(f"Cluster prediksi: {predicted}") # Tambahkan label cluster ke DataFrame asli df = pd.DataFrame(X_scaled, columns=['feature_1', 'feature_2']) df['cluster'] = labels print(df.groupby('cluster').mean()) # Profil rata-rata tiap cluster
🧠 Uji Pemahaman
Choosing the Right Number of Clusters
Menentukan nilai K yang tepat adalah tantangan terbesar dalam K-Means. Tidak ada jawaban mutlak — namun ada beberapa metode sistematis yang membantu kita membuat keputusan yang lebih terinformasi.
Metode 1 — Elbow Method (Metode Siku)
Plot nilai Inertia (WCSS) untuk setiap K dari 1 hingga N. Inertia selalu turun seiring bertambahnya K. Carilah titik “siku” — di mana penurunan inertia mulai melambat drastis. Titik itu adalah K yang optimal.
💡 Titik kuning menunjukkan “elbow” — di K=4, penambahan cluster berikutnya tidak banyak mengurangi inertia
from sklearn.cluster import KMeans import matplotlib.pyplot as plt inertias = [] K_range = range(1, 12) for k in K_range: km = KMeans(n_clusters=k, init='k-means++', n_init=10, random_state=42) km.fit(X_scaled) inertias.append(km.inertia_) plt.figure(figsize=(9, 5)) plt.plot(K_range, inertias, 'o-', color='#00c9ff', lw=2, ms=7) plt.xlabel('Jumlah Cluster K') plt.ylabel('Inertia (WCSS)') plt.title('Elbow Method — Mencari K Optimal') plt.axvline(x=4, color='#ffd166', ls='--', label='Elbow K=4') plt.legend() plt.show()
Metode 2 — Silhouette Score
Silhouette Score mengukur seberapa baik setiap titik cocok di cluster-nya sendiri dibanding cluster lain. Nilainya antara −1 hingga +1. Semakin mendekati +1, semakin baik pemisahan cluster. Pilih K dengan Silhouette Score tertinggi.
b(i) = rata-rata jarak titik i ke semua titik di cluster terdekat lainnya (separation)
🎛️ Simulator: Silhouette Score vs K
from sklearn.metrics import silhouette_score, davies_bouldin_score import matplotlib.pyplot as plt sil_scores = [] db_scores = [] K_range = range(2, 10) for k in K_range: km = KMeans(n_clusters=k, n_init=10, random_state=42) labels = km.fit_predict(X_scaled) sil_scores.append(silhouette_score(X_scaled, labels)) db_scores.append(davies_bouldin_score(X_scaled, labels)) fig, axes = plt.subplots(1, 2, figsize=(12, 4)) # Silhouette Score (lebih tinggi = lebih baik) axes[0].plot(K_range, sil_scores, 'o-', color='#00e5a0', lw=2) axes[0].set_title('Silhouette Score (↑ lebih baik)') axes[0].set_xlabel('K') # Davies-Bouldin Index (lebih rendah = lebih baik) axes[1].plot(K_range, db_scores, 'o-', color='#ff6b9d', lw=2) axes[1].set_title('Davies-Bouldin Index (↓ lebih baik)') axes[1].set_xlabel('K') # Best K = tertinggi di Silhouette dan terendah di Davies-Bouldin best_k_sil = list(K_range)[sil_scores.index(max(sil_scores))] best_k_db = list(K_range)[db_scores.index(min(db_scores))] print(f"K terbaik (Silhouette) : {best_k_sil}") print(f"K terbaik (Davies-Bouldin) : {best_k_db}") plt.tight_layout(); plt.show()
Panduan Memilih K — Kombinasi Metode
| Metode | Yang Dicari | Kelebihan | Kekurangan |
|---|---|---|---|
| Elbow Method | Titik “siku” pada kurva inertia | Mudah dipahami secara visual | Titik siku kadang tidak jelas |
| Silhouette Score | Nilai tertinggi (mendekati +1) | Kuantitatif, lebih objektif | Lambat untuk dataset besar |
| Davies-Bouldin Index | Nilai terendah (mendekati 0) | Tidak perlu jarak ke centroid | Sensitif pada cluster tak beraturan |
| Domain Knowledge | Kebutuhan bisnis | Paling relevan untuk keputusan nyata | Subjektif, butuh expert |
🧠 Uji Pemahaman
Dimensionality Reduction with PCA
Principal Component Analysis (PCA) adalah teknik paling fundamental untuk mereduksi dimensi data. Dari 100 fitur menjadi 2 fitur — sambil mempertahankan sebanyak mungkin informasi. Ini kunci untuk visualisasi dan mempercepat model ML.
Mengapa Kita Perlu Reduksi Dimensi?
Semakin banyak fitur, semakin kompleks data. Di atas 10–20 fitur, banyak hal aneh terjadi — ini disebut “Curse of Dimensionality”: data menjadi sangat jarang, jarak antar titik kehilangan makna, dan model semakin lambat serta rentan overfit.
👁️ Visualisasi
Manusia hanya bisa melihat 2–3 dimensi. PCA memungkinkan kita memplot data 100-dimensi ke scatter plot 2D yang bisa dibaca.
⚡ Percepat Model
Kurangi 500 fitur menjadi 20 komponen → training 25x lebih cepat. Sangat berguna sebelum melatih model yang mahal secara komputasi.
🔇 Noise Reduction
Komponen dengan variance kecil seringkali hanya berisi noise. Menghapusnya justru meningkatkan generalisasi model.
Intuisi PCA — Menemukan Arah Variance Terbesar
PCA mencari sumbu baru (Principal Components) yang menangkap variance terbesar dalam data. PC1 adalah arah dengan variance terbesar, PC2 tegak lurus terhadap PC1 dengan variance terbesar berikutnya, dan seterusnya.
Kiri: Data asli 2D dengan 3 kelas. Kanan: Setelah PCA 1D — cluster tetap terpisah meski dimensi berkurang!
Implementasi PCA dengan Scikit-learn
from sklearn.decomposition import PCA from sklearn.preprocessing import StandardScaler from sklearn.datasets import load_breast_cancer import matplotlib.pyplot as plt import numpy as np # ── Load data ── data = load_breast_cancer() X, y = data.data, data.target # 30 fitur! # ── WAJIB: Scale sebelum PCA ── scaler = StandardScaler() X_scaled = scaler.fit_transform(X) # ── Step 1: Analisis berapa PC yang dibutuhkan ── pca_full = PCA() # Tanpa n_components = gunakan semua pca_full.fit(X_scaled) cumvar = np.cumsum(pca_full.explained_variance_ratio_) plt.figure(figsize=(9, 4)) plt.plot(range(1, len(cumvar)+1), cumvar * 100, 'o-', color='#00c9ff', lw=2) plt.axhline(y=95, color='#ffd166', ls='--', label='95% Variance') plt.xlabel('Jumlah PC') plt.ylabel('Cumulative Explained Variance (%)') plt.title('Scree Plot — Berapa PC yang Cukup?') plt.legend(); plt.show() # Berapa PC yang menjelaskan 95% variance? n_95 = np.argmax(cumvar >= 0.95) + 1 print(f"PC untuk 95% variance: {n_95} dari {X.shape[1]} fitur") # ── Step 2: Terapkan PCA dengan n_components optimal ── pca = PCA(n_components=n_95) X_pca = pca.fit_transform(X_scaled) print(f"Shape sebelum PCA : {X_scaled.shape}") print(f"Shape setelah PCA : {X_pca.shape}")
# ── Visualisasi 2D menggunakan PC1 dan PC2 ── pca_2d = PCA(n_components=2) X_2d = pca_2d.fit_transform(X_scaled) var_pc1 = pca_2d.explained_variance_ratio_[0] * 100 var_pc2 = pca_2d.explained_variance_ratio_[1] * 100 plt.figure(figsize=(8, 6)) for label, name, color in [(0,'Malignant','#ff6b9d'),(1,'Benign','#00e5a0')]: mask = y == label plt.scatter(X_2d[mask,0], X_2d[mask,1], c=color, alpha=0.7, s=40, label=name) plt.xlabel(f'PC1 ({var_pc1:.1f}% variance)') plt.ylabel(f'PC2 ({var_pc2:.1f}% variance)') plt.title(f'Breast Cancer Dataset — PCA 2D\n(Total: {var_pc1+var_pc2:.1f}% variance explained)') plt.legend(); plt.show() # ── PCA sebagai preprocessing untuk model ML ── from sklearn.pipeline import Pipeline from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score pipe = Pipeline([ ('scaler', StandardScaler()), ('pca', PCA(n_components=0.95)), # Otomatis pilih PC untuk 95% variance ('model', RandomForestClassifier(random_state=42)) ]) scores = cross_val_score(pipe, X, y, cv=5, scoring='accuracy') print(f"CV Accuracy dengan PCA: {scores.mean():.4f} ± {scores.std():.4f}")
| Teknik | Kecepatan | Cocok untuk ML | Interpretabilitas | Use Case Utama |
|---|---|---|---|---|
| PCA | ⚡ Sangat Cepat | ✅ Ya | Sedang (loading matrix) | Preprocessing, denoising, visualisasi |
| t-SNE | 🐢 Lambat | ❌ Tidak | Rendah | Visualisasi cluster 2D/3D |
| UMAP | 🐇 Cukup Cepat | ⚠️ Terbatas | Rendah | Visualisasi + eksplorasi data besar |
| Autoencoder | 🐢 Lambat (DL) | ✅ Ya | Rendah | Non-linear dimensionality reduction |
🧠 Uji Pemahaman
n_components=0.95. Apa artinya parameter ini?Use Cases of Clustering in Industry
Unsupervised Learning bukan sekadar teori akademis — ia bekerja keras di balik produk-produk digital yang kamu gunakan setiap hari. Mari kita telusuri implementasi nyata di berbagai industri beserta kode yang bisa langsung diaplikasikan.
5 Use Case Utama di Industri
🏪 1. Customer Segmentation — Retail & E-Commerce
Problem: Toko online memiliki jutaan pelanggan. Strategi marketing satu-untuk-semua tidak efektif dan boros. Solution: K-Means clustering pada data RFM (Recency, Frequency, Monetary) untuk membagi pelanggan ke segmen bermakna.
RFM tinggi semua
Frekuensi tinggi
Dulu aktif, kini jarang
Tidak pernah kembali
import pandas as pd import numpy as np from sklearn.cluster import KMeans from sklearn.preprocessing import StandardScaler from datetime import datetime # ── Hitung RFM dari data transaksi ── today = datetime.now() rfm = df.groupby('customer_id').agg({ 'order_date' : lambda x: (today - x.max()).days, # Recency 'order_id' : 'count', # Frequency 'total_amount' : 'sum' # Monetary }).rename(columns={ 'order_date' : 'Recency', 'order_id' : 'Frequency', 'total_amount': 'Monetary' }) # ── Scaling ── scaler = StandardScaler() rfm_sc = scaler.fit_transform(rfm) # ── K-Means Clustering ── kmeans = KMeans(n_clusters=4, n_init=10, random_state=42) rfm['Segment'] = kmeans.fit_predict(rfm_sc) # ── Beri nama segmen berdasarkan profil RFM ── segment_profile = rfm.groupby('Segment').mean().round(1) print(segment_profile) # Contoh output mapping nama segmen segment_map = {0:'Champions', 1:'Loyal', 2:'At Risk', 3:'Lost'} rfm['Segment_Name'] = rfm['Segment'].map(segment_map) print(rfm['Segment_Name'].value_counts())
🚨 2. Anomaly Detection — Perbankan & Cybersecurity
Problem: Transaksi fraudulent sangat jarang (<0.1%) sehingga tidak ada label yang cukup. Solution: Data normal akan membentuk cluster padat. Transaksi yang tidak cocok di cluster manapun (jarak jauh dari semua centroid) adalah anomali potensial.
from sklearn.ensemble import IsolationForest from sklearn.cluster import KMeans import numpy as np # ── Metode 1: Jarak dari Centroid ── kmeans = KMeans(n_clusters=5, n_init=10, random_state=42) kmeans.fit(X_scaled) # Hitung jarak setiap titik ke centroid cluster-nya distances = np.min(kmeans.transform(X_scaled), axis=1) # Threshold: titik dengan jarak di atas persentil 95 = anomali threshold = np.percentile(distances, 95) anomalies_kmeans = X_scaled[distances > threshold] print(f"Anomali terdeteksi (K-Means): {len(anomalies_kmeans)}") # ── Metode 2: Isolation Forest (lebih powerful) ── iso_forest = IsolationForest( contamination=0.05, # Perkiraan % anomali dalam data random_state=42, n_estimators=100 ) predictions = iso_forest.fit_predict(X_scaled) # -1 = anomali, 1 = normal anomalies_if = X_scaled[predictions == -1] print(f"Anomali terdeteksi (Isolation Forest): {len(anomalies_if)}")
🎬 3. Recommendation System — Streaming & Media
Problem: Netflix, Spotify, YouTube perlu merekomendasikan konten yang relevan dari jutaan pilihan. Solution: Collaborative Filtering menggunakan matrix factorization (mirip PCA) + clustering pengguna berdasarkan preferensi tontonan/dengaran.
📝 4. Topic Modeling — NLP & Media Sosial
Problem: Perusahaan menerima ribuan review/tweet setiap hari. Tidak mungkin dibaca manual. Solution: Representasikan teks sebagai vektor (TF-IDF/Embeddings), lalu cluster dokumen serupa untuk menemukan topik tersembunyi secara otomatis.
from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.cluster import KMeans from sklearn.decomposition import PCA import pandas as pd # Dataset: daftar review/artikel documents = [ "Laptop ini sangat cepat dan ringan", "Baterai tahan lama, cocok untuk kerja", "Harga mahal tapi worth it untuk profesional", "Film action terbaik tahun ini", "Cerita yang menarik dan visual memukau", "Akting pemain sangat natural dan mengharukan", ] # ── Step 1: Representasi teks menjadi vektor TF-IDF ── vectorizer = TfidfVectorizer(max_features=500) X_text = vectorizer.fit_transform(documents) # ── Step 2: Reduksi dimensi dengan PCA sebelum clustering ── pca = PCA(n_components=50) X_pca = pca.fit_transform(X_text.toarray()) # ── Step 3: K-Means clustering ── kmeans = KMeans(n_clusters=2, n_init=10, random_state=42) labels = kmeans.fit_predict(X_pca) # ── Step 4: Lihat hasil per cluster ── df_result = pd.DataFrame({'text': documents, 'cluster': labels}) for i in df_result['cluster'].unique(): print(f"\n=== Cluster {i} ===") print(df_result[df_result['cluster']==i]['text'].tolist()) # Top keywords per cluster order_centroids = kmeans.cluster_centers_.argsort()[:, ::-1] terms = vectorizer.get_feature_names_out() for i in range(2): top_words = [terms[ind] for ind in order_centroids[i, :5]] print(f"Topik Cluster {i}: {', '.join(top_words)}")
Ringkasan Use Cases per Industri
| Industri | Problem | Teknik Utama | Output |
|---|---|---|---|
| 🛒 Retail/E-Commerce | Segmentasi pelanggan | K-Means pada RFM | Persona pelanggan untuk marketing |
| 🏦 Perbankan | Deteksi fraud | Isolation Forest, DBSCAN | Alert transaksi mencurigakan |
| 🎬 Streaming | Rekomendasi konten | Matrix Factorization, Clustering | Daftar konten yang dipersonalisasi |
| 🏥 Healthcare | Pengelompokan pasien | Hierarchical Clustering | Subtype penyakit, personalized medicine |
| 📰 Media/NLP | Topic discovery | LDA, K-Means + TF-IDF | Kategori topik otomatis |
| 🏭 Manufaktur | Quality control | DBSCAN, Autoencoder | Deteksi produk cacat |
| 🌐 Cybersecurity | Network intrusion | K-Means, Isolation Forest | Alert aktivitas mencurigakan |
Checklist Praktis Sebelum Deploy Clustering
- ✓Selalu StandardScaler sebelum K-MeansK-Means sangat sensitif terhadap skala. Fitur dengan range besar (0–10000) akan mendominasi fitur dengan range kecil (0–1).
- ✓Validasi dengan minimal 2 metrik + domain expertJangan hanya bergantung pada Elbow Method. Konfirmasi dengan Silhouette Score dan tanyakan kepada stakeholder bisnis apakah segmen yang terbentuk masuk akal.
- ✓Beri nama dan interpretasi tiap clusterCluster angka (0, 1, 2) tidak berguna untuk bisnis. Analisis profil rata-rata tiap cluster dan beri nama deskriptif agar bisa dikomunikasikan ke non-teknis.
- ✓Pantau cluster drift secara berkalaPerilaku pelanggan berubah seiring waktu. Jalankan ulang clustering setiap bulan/kuartal dan bandingkan apakah ada pergeseran signifikan pada distribusi cluster.
- ✓Pertimbangkan DBSCAN untuk data tidak beraturanJika data memiliki cluster berbentuk tidak beraturan atau banyak outlier, DBSCAN lebih baik dari K-Means karena tidak butuh K dan bisa mendeteksi noise secara otomatis.
🎉 Selamat! Bab Unsupervised Learning Selesai!
Kamu telah menjelajahi dunia Unsupervised Learning secara menyeluruh — dari memahami konsep dasar, menguasai K-Means dengan simulator interaktif, memilih K yang tepat dengan Elbow & Silhouette, mereduksi dimensi dengan PCA, hingga mengaplikasikannya di 7 industri berbeda. Bab berikutnya akan membahas Neural Networks & Deep Learning — lompatan terbesar menuju AI modern!