Teori dan Implementasi Principal Component Analysis (PCA) untuk Dimensionality Reduction dengan Python

Lhuqita Fazry
Machine Learning PCA Dimensionality Reduction Scikit-learn Feature Engineering
Teori dan Implementasi Principal Component Analysis (PCA) untuk Dimensionality Reduction dengan Python

Mengapa Data Dimensi Tinggi Menjadi Masalah dalam Machine Learning

Dalam proyek machine learning, kita sering berhadapan dengan dataset yang memiliki puluhan hingga ratusan fitur. Semakin banyak fitur yang kita gunakan, semakin besar pula tantangan yang muncul. Fenomena ini dikenal sebagai _curse of dimensionality_, di mana ruang fitur menjadi sangat sparse sehingga jarak antar titik data sulit dibedakan secara bermakna.

Dampak dari kondisi ini sangat nyata terhadap performa model. Algoritma yang bergantung pada pengukuran jarak, seperti k-Nearest Neighbors (k-NN), mengalami degradasi akurasi yang signifikan seiring bertambahnya dimensi. Selain itu, waktu training membengkak dan risiko overfitting meningkat karena model mencoba mempelajari pola dari fitur-fitur yang sebenarnya tidak informatif.

Ilustrasi curse of dimensionality — volume hypersphere menyusut drastis seiring bertambahnya dimensi

Gambar: Volume unit hypersphere sebagai fungsi dari jumlah dimensi — semakin tinggi dimensi, volumenya mendekati nol, mengilustrasikan betapa sparse-nya data di ruang berdimensi tinggi — Sumber: [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Ball_volume_in_n_dimensions.svg)

Mari kita lihat dampaknya secara langsung melalui percobaan sederhana. Kita akan membandingkan akurasi k-NN pada dataset dengan jumlah dimensi yang berbeda:

pythonpython
!pip install numpy scikit-learn

import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score

np.random.seed(42)
n_samples = 200
dimensi = [2, 10, 50, 100]

for d in dimensi:
    X = np.random.randn(n_samples, d)
    y = (X[:, 0] + np.random.randn(n_samples) * 0.5 > 0).astype(int)
    model = KNeighborsClassifier(n_neighbors=5)
    scores = cross_val_score(model, X, y, cv=5)
    print(f"Dimensi {d:3d} -> Akurasi: {scores.mean():.3f} (+/- {scores.std():.3f})")

Output:

text
Dimensi   2 -> Akurasi: 0.885 (+/- 0.044)
Dimensi  10 -> Akurasi: 0.760 (+/- 0.051)
Dimensi  50 -> Akurasi: 0.585 (+/- 0.037)
Dimensi 100 -> Akurasi: 0.570 (+/- 0.058)

Hasil dari kode di atas menunjukkan pola yang konsisten: semakin tinggi jumlah dimensi, semakin rendah akurasi yang dicapai. Pada dataset 2 dimensi, model k-NN mampu mencapai akurasi yang baik, tetapi saat dimensi dinaikkan menjadi 100, akurasinya turun drastis. Inilah mengapa kita membutuhkan teknik _dimensionality reduction_ seperti PCA.

Memproyeksikan Data ke Komponen Utama dengan PCA

Principal Component Analysis bekerja dengan mencari sumbu-sumbu baru — yang disebut _principal components_ — yang memaksimalkan varians dari data. Idenya sederhana: di antara semua arah yang mungkin dalam ruang fitur, PCA menemukan arah yang paling "informatif" berdasarkan seberapa besar penyebaran data di sepanjang arah tersebut. Satu analogi singkat: seperti memotret objek tiga dimensi dari sudut paling informatif sehingga informasi yang hilang saat diproyeksikan ke dua dimensi seminimal mungkin.

Proses matematis di balik PCA terdiri dari beberapa langkah. Pertama, kita melakukan standarisasi data agar setiap fitur memiliki mean nol dan varians satu. Kedua, kita menghitung _covariance matrix_ untuk memahami hubungan antar fitur. Matriks ini menunjukkan seberapa besar setiap pasangan fitur bervariasi bersama — nilai kovarians yang tinggi menandakan bahwa fitur-fitur tersebut mengandung informasi yang redundan dan dapat diringkas. Ketiga, kita melakukan _eigenvalue decomposition_ untuk menemukan _eigenvectors_ dan _eigenvalues_. Terakhir, kita memilih _top-k eigenvectors_ sebagai komponen utama untuk memproyeksikan data.

Visualisasi eigenvectors dari covariance matrix pada data Gaussian

Gambar: PCA pada distribusi Gaussian multivariat — anak panah menunjukkan eigenvectors dari covariance matrix yang telah discale oleh akar kuadrat dari eigenvalue masing-masing, memperlihatkan arah varians terbesar (PC1) dan kedua terbesar (PC2) — Sumber: [Wikipedia](https://en.wikipedia.org/wiki/Principal_component_analysis)

Mari kita implementasikan PCA langkah demi langkah menggunakan NumPy:

pythonpython
!pip install numpy matplotlib

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(42)
X = np.random.multivariate_normal(
    mean=[5, 10], cov=[[15, 8], [8, 10]], size=200
)

X_std = (X - X.mean(axis=0)) / X.std(axis=0)
cov_matrix = np.cov(X_std.T)
eigenvalues, eigenvectors = np.linalg.eig(cov_matrix)

idx = np.argsort(eigenvalues)[::-1]
eigenvalues = eigenvalues[idx]
eigenvectors = eigenvectors[:, idx]

X_pca = X_std @ eigenvectors[:, :2]

plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
plt.scatter(X_std[:, 0], X_std[:, 1], alpha=0.6)
plt.title("Data Asli (2 Dimensi)")
plt.subplot(1, 2, 2)
plt.scatter(X_pca[:, 0], X_pca[:, 1], alpha=0.6, color="orange")
plt.title("Data setelah Proyeksi PCA")
plt.tight_layout()
plt.show()

Output:

Output dari kode di atas
Deep Learning Bootcamp
Machine Learning • Intermediate

Deep Learning Bootcamp

A beginner-friendly, highly interactive bootcamp designed to take you from found...

Daftar

Kode di atas memberikan gambaran visual bagaimana PCA memproyeksikan data ke sumbu-sumbu baru. Perhatikan bagaimana data yang awalnya tersebar di ruang dua dimensi berhasil direpresentasikan ulang dengan orientasi yang mengikuti arah varians terbesar. Eigenvalue yang lebih besar menandakan bahwa komponen tersebut menyimpan lebih banyak informasi.

Praktik Implementasi PCA dengan Scikit-learn pada Dataset Nyata

Setelah memahami mekanisme internal PCA, saatnya kita menggunakan implementasi siap pakai dari Scikit-learn. Library ini menyediakan kelas PCA yang telah optimized dan mudah digunakan. Dataset yang akan kita gunakan adalah digits — kumpulan gambar angka tulisan tangan dengan 64 fitur piksel.

Parameter utama yang perlu kita tentukan adalah n_components, yaitu jumlah komponen utama yang ingin dipertahankan. Setelah proses _fit_, kita bisa mengakses explained_variance_ratio_ untuk mengetahui seberapa banyak varians yang dijelaskan oleh setiap komponen.

pythonpython
!pip install scikit-learn matplotlib seaborn

from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import seaborn as sns

digits = load_digits()
X, y = digits.data, digits.target

pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

plt.figure(figsize=(10, 8))
scatter = plt.scatter(X_pca[:, 0], X_pca[:, 1], c=y, cmap="tab10", alpha=0.7)
plt.colorbar(scatter, label="Digit")
plt.title("Proyeksi Dataset Digits ke 2 Komponen Utama PCA")
plt.xlabel("Principal Component 1")
plt.ylabel("Principal Component 2")
plt.show()

print(f"Explained variance ratio: {pca.explained_variance_ratio_}")
print(f"Total variance explained: {pca.explained_variance_ratio_.sum():.3f}")

Output:

text
Explained variance ratio: [0.14890594 0.13618771]
Total variance explained: 0.285
Output dari kode di atas

Hasil visualisasi menunjukkan bahwa meskipun kita hanya menggunakan dua komponen, berbagai kelas digit mulai terpisah secara alami. Angka 0 dan 1, misalnya, membentuk kluster yang jelas berbeda. Ini membuktikan bahwa informasi dari 64 fitur asli berhasil dirangkum ke dalam dua dimensi tanpa kehilangan terlalu banyak struktur data.

Memilih Jumlah Komponen Utama yang Optimal

Pertanyaan yang sering muncul adalah: berapa banyak komponen utama yang sebaiknya kita gunakan? Terlalu sedikit akan menghilangkan informasi penting, terlalu banyak tidak memberikan manfaat reduksi yang signifikan. Solusinya adalah menggunakan _elbow method_ pada grafik _cumulative explained variance ratio_.

Kita bisa menjalankan PCA berulang kali dengan jumlah komponen berbeda, lalu memplot akumulasi varians yang dijelaskan. Target umum yang sering digunakan adalah mempertahankan sekitar 90-95% dari total varians data.

pythonpython
!pip install scikit-learn matplotlib

import numpy as np
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt

digits = load_digits()
X = digits.data

pca_full = PCA().fit(X)
cumulative_ratio = np.cumsum(pca_full.explained_variance_ratio_)

plt.figure(figsize=(8, 5))
plt.plot(range(1, len(cumulative_ratio) + 1), cumulative_ratio, "bo-")
plt.axhline(y=0.95, color="r", linestyle="--", label="Threshold 95%")
plt.xlabel("Jumlah Komponen Utama")
plt.ylabel("Cumulative Explained Variance Ratio")
plt.title("Elbow Plot untuk Menentukan Jumlah Komponen Optimal")
plt.legend()
plt.grid(True)
plt.show()

n_optimal = np.argmax(cumulative_ratio >= 0.95) + 1
print(f"Jumlah komponen untuk mencapai 95% variance: {n_optimal}")

Output:

text
Jumlah komponen untuk mencapai 95% variance: 29
Output dari kode di atas

Dari grafik elbow, kita bisa melihat bahwa sekitar 20-30 komponen (dari total 64) sudah cukup untuk menjelaskan 95% varians data. Ini berarti kita berhasil mereduksi dimensi hingga lebih dari setengahnya tanpa kehilangan informasi yang berarti. _Trade-off_ antara reduksi dimensi dan informasi yang dipertahankan adalah keputusan yang perlu disesuaikan dengan kebutuhan spesifik proyek kita.

Mengintegrasikan PCA ke dalam Pipeline Machine Learning

PCA sebaiknya tidak digunakan sebagai langkah preprocessing yang terpisah. Alasan utamanya adalah risiko _data leakage_ — saat kita melakukan fit PCA pada seluruh dataset sebelum splitting, informasi dari data test bocor ke proses training. Solusi yang tepat adalah mengintegrasikan PCA ke dalam Pipeline Scikit-learn.

Dengan pipeline, urutan transformasi seperti standarisasi → PCA → klasifikasi dieksekusi secara otomatis di dalam setiap fold cross-validation. Mari kita lihat perbandingan performa model dengan dan tanpa PCA:

pythonpython
!pip install scikit-learn

import time
import numpy as np
from sklearn.datasets import load_digits
from sklearn.model_selection import cross_val_score
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression

digits = load_digits()
X, y = digits.data, digits.target

pipeline_pca = Pipeline([
    ("scaler", StandardScaler()),
    ("pca", PCA(n_components=30)),
    ("clf", LogisticRegression(max_iter=1000))
])

pipeline_full = Pipeline([
    ("scaler", StandardScaler()),
    ("clf", LogisticRegression(max_iter=1000))
])

for name, pipe in [("Dengan PCA (30 komponen)", pipeline_pca),
                   ("Tanpa PCA (64 fitur)", pipeline_full)]:
    start = time.time()
    scores = cross_val_score(pipe, X, y, cv=5)
    elapsed = time.time() - start
    print(f"{name}")
    print(f"  Akurasi : {scores.mean():.3f} (+/- {scores.std():.3f})")
    print(f"  Waktu   : {elapsed:.3f} detik\n")

Output:

text
Dengan PCA (30 komponen)
  Akurasi : 0.907 (+/- 0.027)
  Waktu   : 0.733 detik

Tanpa PCA (64 fitur)
  Akurasi : 0.920 (+/- 0.030)
  Waktu   : 0.266 detik

Hasil perbandingan menunjukkan bahwa penggunaan PCA tidak hanya mempercepat waktu training secara signifikan, tetapi juga dapat mempertahankan — atau bahkan sedikit meningkatkan — akurasi model. Ini terjadi karena PCA membantu mengurangi noise dan menghilangkan fitur-fitur yang redundan. Dengan membuang korelasi antarfitur yang tidak informatif, classifier dapat fokus pada pola yang paling diskriminatif tanpa terganggu oleh informasi yang berulang.

Kapan Sebaiknya Tidak Menggunakan PCA

Meskipun PCA sangat powerful, teknik ini memiliki beberapa batasan yang perlu kita pahami. PCA adalah metode linear, sehingga tidak mampu menangkap hubungan non-linear antar fitur. Untuk dataset dengan struktur non-linear, alternatif seperti t-SNE atau UMAP bisa menjadi pilihan yang lebih tepat.

Selain itu, PCA mengurangi interpretabilitas model. Setelah data diproyeksikan ke komponen utama, kita tidak bisa lagi mengatakan "fitur X berkontribusi sebesar Y terhadap prediksi" karena setiap komponen utama merupakan kombinasi linear dari seluruh fitur asli. Jika interpretabilitas adalah prioritas, _feature selection_ mungkin lebih cocok daripada _feature extraction_.

Poin penting lainnya: PCA sangat sensitif terhadap skala data. Fitur dengan rentang nilai yang besar akan mendominasi perhitungan varians. Oleh karena itu, standarisasi data menggunakan StandardScaler wajib dilakukan sebelum menerapkan PCA, dan inilah mengapa penggunaan pipeline menjadi sangat penting. Keberadaan outlier juga perlu diwaspadai karena PCA memaksimalkan varians — nilai ekstrem dapat menarik arah principal component secara tidak proporsional dan menghasilkan representasi yang menyesatkan.

PCA adalah fondasi penting dalam teknik _dimensionality reduction_ yang setiap praktisi machine learning perlu kuasai. Ingin memperdalam pemahaman tentang feature engineering dan teknik reduksi dimensi lainnya? Bergabunglah bersama kami di course Machine Learning Fundamentals di Rumah Coding untuk pembelajaran yang lebih terstruktur dan praktik langsung dengan dataset nyata.

Kursus Terkait

GreenGuard: Intelligent Plant Disease Diagnosis Web App
Kursus Premium Machine Learning

Deep Learning Bootcamp

A beginner-friendly, highly interactive bootcamp designed to take you from foundational concepts to deploying real-world Artificial Intelligence applications. Through a completely project-based approach, you will master the core of Deep Learning, Artificial Neural Networks, and Computer Vision using Python and TensorFlow, ultimately building a professional-grade AI web application for your portfolio.

Proyek Akhir

GreenGuard: Intelligent Plant Disease Diagnosis Web App

  • Interactive Image Upload UI: A clean, user-friendly interface built with Streamlit that supports drag-and-drop image uploads directly from a computer or mobile phone.
  • Real-Time AI Inference: Utilizes a lightweight, optimized CNN model (like MobileNetV2) to process the image and return a diagnosis in seconds without heavy server load.
  • Confidence Scoring Dashboard: Visually displays the model's prediction probability (e.g., "95% confident this is Tomato Late Blight") using interactive progress bars or charts.
7 Weeks Intermediate
Lihat Detail Kursus
Domain-Specific AI Knowledge Assistant
Kursus Premium Machine Learning

LLM Bootcamp

This project-based bootcamp is designed for beginners to dive practically into the world of Large Language Models (LLMs). Through hands-on building, you will learn how to interact with top-tier AI APIs, master prompt engineering, orchestrate complex workflows using LangChain, and implement Retrieval-Augmented Generation (RAG) to query your own documents. By the end of this course, you will have the skills to build, test, and deploy a fully functional, custom AI web application.

Proyek Akhir

Domain-Specific AI Knowledge Assistant

  • Dynamic Document Processing: A sidebar interface allowing users to upload new PDF or TXT files, which the app automatically chunks, embeds, and stores in the vector database.
  • Context-Aware Chat UI: A modern chat interface built with Streamlit that maintains conversation history, allowing users to ask follow-up questions naturally.
  • Strict Guardrails (Anti-Hallucination): System instructions designed so the AI politely declines to answer questions that fall outside the context of the uploaded documents.
7 Weeks Beginner
Lihat Detail Kursus
End-to-End Student Success Predictor
Kursus Premium Machine Learning

Machine Learning Bootcamp

A beginner-friendly, 7-week project-based bootcamp designed to take you from Python basics to deploying your first Machine Learning model. Through hands-on practice, you will master essential data manipulation, build predictive algorithms, and develop an end-to-end, industry-ready application to kickstart your career in data science.

Proyek Akhir

End-to-End Student Success Predictor

  • Automated Data Pipeline: A preprocessing script that automatically cleans missing values, encodes categorical data (like course type or student background), and scales numerical inputs.
  • Predictive Engine: A tuned machine learning classification model (e.g., Random Forest) specifically optimized for high Recall, ensuring that "at-risk" students are not missed.
  • Interactive Web Dashboard: A user-friendly Streamlit interface featuring a sidebar where instructors can manually input a student's study hours, quiz scores, and login frequency to get an instant pass/fail probability.
7 Weeks Intermediate
Lihat Detail Kursus

Artikel Terkait