Data nyata jarang berhemat fitur. Satu profil pelanggan toko ritel bisa memuat total belanja, jumlah transaksi, jumlah kategori produk, durasi kunjungan, dan belasan ukuran lain — dan sebagian besar saling berkorelasi karena menggambarkan aktivitas yang sama. PCA (Principal Component Analysis) meringkas situasi seperti itu: algoritme memproyeksikan data ke beberapa sumbu baru yang saling tegak lurus, dipilih agar variansi data yang tertangkap sebanyak mungkin. Section ini berganti fokus dari mengelompokkan menjadi meringkas, dan data uji kita sederhana: 100 pelanggan dengan tiga fitur aktivitas belanja yang sengaja dibuat saling berkorelasi — cukup kecil untuk dibaca utuh, cukup nyata untuk bercerita.
Mengapa Dimensi Perlu Dikurangi #
Motivasi reduksi dimensi datang dari lima masalah yang berulang di praktik:
- Visualisasi: mata manusia berhenti di dua–tiga dimensi; data 50 fitur mustahil dilihat langsung tanpa diproyeksikan.
- Multikolinearitas: fitur yang saling berkorelasi membuat koefisien regresi goyah dan sulit ditafsirkan — PCA menggantinya dengan sumbu yang secara konstruksi tidak berkorelasi.
- Kompresi: menyimpan atau mengirim 10 angka komponen lebih murah daripada 500 fitur mentah, dengan galat yang terukur.
- Kecepatan: model melatih dan memprediksi lebih cepat pada dimensi kecil.
- Curse of dimensionality: ruang berdimensi tinggi tumbuh eksponensial luasnya, sehingga data menjadi renggang dan ukuran jarak kehilangan daya pembeda — masalah yang sudah kita temui pada KNN dan DBSCAN.
Cara Kerja: Proyeksi yang Maksimalkan Variansi #
Bayangkan awan titik dua dimensi yang membentang diagonal. Proyeksi terbaik yang mempertahankan bentuk awan itu bukan sumbu x atau y, melainkan garis diagonalnya. PCA melakukan hal yang sama secara umum: dari kovariansi data berdimensi d, algoritme mencari d arah (eigenvector matriks kovariansi), diurutkan berdasarkan eigenvalue — jumlah variansi yang tertangkap tiap arah. Arah pertama disebut PC1, arah kedua (wajib tegak lurus PC1) PC2, dan seterusnya.
Dua istilah teknis yang akan terus muncul: komponen adalah vektor arah tersebut (atribut components_), sedangkan skor adalah koordinat data hasil proyeksi (hasil transform) — skor inilah “fitur baru” yang dipakai model lanjutan. Rasio variansi tiap komponen dilaporkan explained_variance_ratio_, dan jumlah kumulatifnya menjadi dasar pemilihan jumlah komponen: aturan praktis yang umum adalah berhenti saat variansi kumulatif melampaui 95% — komponen sisanya dianggap membawa derau, bukan informasi.
Kompresi yang Bisa Dikembalikan #
Berbeda dengan sebagian teknik reduksi dimensi, PCA punya arah balik: inverse_transform memetakan skor kembali ke ruang fitur asli. Hasilnya tidak persis sama — komponen yang dibuang membawa sebagian informasi, dan itulah galat rekonstruksi. Sifat ini membuat PCA bisa diuji sebagai kompresi: bandingkan data asli dengan hasil rekonstruksinya, lalu putuskan apakah galatnya masih terjangkau untuk kebutuhan Anda. Sifat ini pula yang dipakai deteksi anomali berbasis rekonstruksi — titik yang galat rekonstruksinya besar adalah kandidat pencilan.
Praktik: Tiga Fitur Menjadi Dua Komponen #
# PCA: ringkas tiga fitur berkorelasi menjadi dua komponen utama.
# Kisah: 100 pelanggan dengan tiga fitur aktivitas belanja.
import numpy as np
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
# Data sintetis: jumlah transaksi dan kategori unik bergantung pada belanja.
rng = np.random.default_rng(42)
n = 100
total_belanja = rng.normal(4.0, 1.0, n) # juta Rp per bulan
jumlah_transaksi = 2.5 * total_belanja + rng.normal(0.0, 1.0, n)
kategori_unik = 0.5 * total_belanja + rng.normal(3.0, 1.2, n)
X = np.column_stack([total_belanja, jumlah_transaksi, kategori_unik])
NAMA_FITUR = ["total_belanja", "jumlah_transaksi", "kategori_unik"]
# 1) Standarisasi dulu: PCA peka terhadap skala fitur.
scaler = StandardScaler()
X_std = scaler.fit_transform(X)
# 2) PCA penuh: berapa variansi yang dijelaskan tiap komponen?
pca3 = PCA(n_components=3).fit(X_std)
print("Rasio variansi yang dijelaskan tiap komponen:")
for k in range(3):
kumulatif = float(np.cumsum(pca3.explained_variance_ratio_)[k])
print(f" PC{k + 1}: {pca3.explained_variance_ratio_[k]:.3f} "
f"(kumulatif {kumulatif:.3f})")
# 3) Muatan (loadings): kontribusi tiap fitur pada arah komponen.
print("\nMuatan dua komponen pertama:")
for k in range(2):
bagian = " ".join(f"{nama}={nilai:+.3f}"
for nama, nilai in zip(NAMA_FITUR, pca3.components_[k]))
print(f" PC{k + 1}: {bagian}")
# 4) Verifikasi: variansi skor PC1 == explained_variance_[0].
skor = pca3.transform(X_std)
var_manual = float(skor[:, 0].var(ddof=1))
print(f"\nVariansi skor PC1 (hitung manual) : {var_manual:.6f}")
print(f"explained_variance_[0] (API) : {pca3.explained_variance_[0]:.6f}")
# 5) Kompresi ke 2 komponen + rekonstruksi dua pelanggan baru.
pca2 = PCA(n_components=2).fit(X_std)
pelanggan_baru = np.array([
[4.0, 10.5, 5.0], # pelanggan A (nilai mentah)
[5.5, 14.0, 6.5], # pelanggan B (nilai mentah)
])
z_baru = pca2.transform(scaler.transform(pelanggan_baru))
rekon = scaler.inverse_transform(pca2.inverse_transform(z_baru))
print("\nKompresi 3 fitur -> 2 komponen -> rekonstruksi:")
for i, nama in enumerate(["A", "B"]):
print(f" pelanggan {nama}: asli {pelanggan_baru[i].tolist()}")
print(f" z (2 dim) {np.round(z_baru[i], 3).tolist()}")
print(f" rekonstruksi {np.round(rekon[i], 3).tolist()}")
galat_maks = np.abs(pelanggan_baru - rekon).max(axis=1)
print(f" galat maksimum per pelanggan : {np.round(galat_maks, 3).tolist()}")Output yang Dihasilkan:
Rasio variansi yang dijelaskan tiap komponen:
PC1: 0.685 (kumulatif 0.685)
PC2: 0.283 (kumulatif 0.967)
PC3: 0.033 (kumulatif 1.000)
Muatan dua komponen pertama:
PC1: total_belanja=+0.663 jumlah_transaksi=+0.659 kategori_unik=+0.356
PC2: total_belanja=-0.237 jumlah_transaksi=-0.266 kategori_unik=+0.934
Variansi skor PC1 (hitung manual) : 2.075032
explained_variance_[0] (API) : 2.075032
Kompresi 3 fitur -> 2 komponen -> rekonstruksi:
pelanggan A: asli [4.0, 10.5, 5.0]
z (2 dim) [0.258, -0.018]
rekonstruksi [4.085, 10.255, 4.996]
pelanggan B: asli [5.5, 14.0, 6.5]
z (2 dim) [2.988, 0.203]
rekonstruksi [5.444, 14.162, 6.503]
galat maksimum per pelanggan : [0.245, 0.162]Mari kita bedah hasil eksekusinya:
- Baris 11–13 (data berkorelasi):
jumlah_transaksi = 2.5 * total_belanja + derau— fitur kedua memuat ulang fitur pertama plus gangguan acak;kategori_unikberkorelasi lebih longgar. Redundansi semacam ini persis bahan baku PCA. - Baris 23–28 (spektrum variansi): PC1 menampung 0,685 variansi, PC2 menambah 0,283 sehingga kumulatif 0,967 — sudah melampaui ambang 95%, dan PC3 hanya menyisakan 0,033. Dua komponen memadai; fitur ketiga boleh dibuang tanpa kehilangan banyak informasi.
- Baris 31–35 (membaca muatan): seluruh muatan PC1 positif, didominasi
total_belanja(+0,663) danjumlah_transaksi(+0,659) — PC1 adalah arah aktivitas belanja umum: pelanggan aktif ke segala arah mendapat skor besar. PC2 hampir seluruhnyakategori_unik(+0,934) dengan muatan kecil negatif pada dua fitur lain — arah “pereksplor kategori di tengah belanja biasa”. Komponen PCA bisa ditafsirkan lewat muatan seperti ini; kelemahannya, pada data ratusan fitur penafsiran menjadi pekerjaan serius. - Baris 38–41 (verifikasi API): skor PC1 dihitung dengan
transform, variansinya dihitung manualvar(ddof=1)— hasilnya 2,075032, identik denganexplained_variance_[0]. Kata “variansi yang dijelaskan” bukan janji pemasaran: ia benar-benar variansi dari skor komponen itu. - Baris 44–57 (kompresi pulang-pergi): pelanggan A
[4.0, 10.5, 5.0]menjadi dua angka[0.258, -0.018], lalu direkonstruksi[4.085, 10.255, 4.996]— galat terbesar 0,245 (pada total belanja, satuan juta rupiah). Pelanggan B bahkan lebih akurat: 0,162. Membuang PC3 yang hanya berisi 3,3% variansi memang tidak mengubah wajah data secara berarti — kompresi PCA pada dasarnya membuang komponen berperingkat paling rendah terlebih dahulu.
PCA mempertahankan struktur global: arah variansi terbesar, jarak antar kelompok besar. Namun untuk melihat data berdimensi tinggi, sering kali struktur lokal — tetangga mana yang berdekatan — yang jauh lebih menentukan kejelasan peta. Chapter penutup section ini, t-SNE untuk Visualisasi Data Berdimensi Tinggi, menukar jaminan global PCA dengan ketajaman lokal, dan mengajarkan batas-batas tafsirannya.
Referensi Resmi #
- PCA — scikit-learn User Guide (decomposition) — penjelasan resmi matematis PCA, contoh penggunaan, dan interpretasi komponen.
- sklearn.decomposition.PCA — API Reference
— atribut
components_,explained_variance_ratio_, dan metodeinverse_transform.