Referensi cepat aljabar linear untuk machine learning. Vektor, matriks, transformasi, eigendecomposition, SVD, dan PCA dengan NumPy yang bisa langsung kamu pakai.
Model machine learning menampung data sebagai angka. Tabel fitur jadi matriks, satu pengamatan jadi vektor baris, dan bobot model jadi vektor. Kalau kamu paham cara vektor dan matriks berinteraksi, kamu bisa membaca kenapa sebuah model berperilaku tertentu alih alih hanya menebak dari error yang muncul.
Fokus di halaman ini bukan pembuktian teorema. Fokusnya adalah operasi yang paling sering kamu temui saat membangun model, apa artinya secara intuisi, dan bagaimana menulisnya dengan NumPy.
import numpy as np
np.set_printoptions(precision=3, suppress=True)suppress=True memaksa NumPy menampilkan angka kecil sebagai 0. alih alih notasi ilmiah. Ini membantu saat membaca hasil dekomposisi.
Vektor adalah daftar angka dengan satu arah dan panjang. Untuk kamu yang memakai Pandas, satu baris DataFrame yang hanya berisi fitur numerik adalah sebuah vektor.
u = np.array([3.0, 4.0])
v = np.array([1.0, 2.0])
penjumlahan = u + v
skala = 3 * u
print(penjumlahan) # [4. 6.]
print(skala) # [ 9. 12.]Dot product dari dua vektor mengukur seberapa searah keduanya. Nilai besar dan positif berarti searah, nol berarti tegak lurus, negatif berarti berlawanan arah. Norm adalah panjang vektor.
import numpy as np
u = np.array([3.0, 4.0])
v = np.array([1.0, 2.0])
dot = u @ v
norm_u = np.linalg.norm(u)
print(dot) # 11.0
print(norm_u) # 5.0Cosinus sudut antara dua vektor adalah dot product dibagi hasil kali norm keduanya. Ini dasar dari cosine similarity, yang dipakai untuk mengukur kemiripan teks, gambar, atau vektor embedding.
def cosinus(a, b):
return (a @ b) / (np.linalg.norm(a) * np.linalg.norm(b))
print(cosinus(u, v)) # ~0.984Kalau dua vektor embedding punya cosine similarity mendekati 1, mereka menunjuk ke arah yang hampir sama. Perhatikan bahwa ini mengabaikan panjang, jadi dua vektor dengan panjang berbeda tetap bisa dianggap mirip arah.
Matriks adalah kumpulan vektor yang disusun menjadi tabel. Dalam machine learning, matriks fitur biasanya berbentuk (jumlah_baris, jumlah_kolom), baris untuk pengamatan dan kolom untuk fitur.
A = np.array([[1.0, 2.0], [3.0, 4.0]])
B = np.array([[5.0, 6.0], [7.0, 8.0]])
print(A.shape) # (2, 2)
print(A.T) # transpose, kolom jadi barisTranspose membalik baris dan kolom. A.T mengembalikan view untuk banyak kasus, jadi perhatikan saat kamu mengubahnya. Gunakan .copy() bila perlu hasil mandiri.
Perkalian matriks bukan perkalian per elemen. A @ B menghitung dot product baris A dengan kolom B. Dimensi dalam harus cocok: (m, n) @ (n, p) menghasilkan (m, p).
A = np.array([[1.0, 2.0], [3.0, 4.0]])
B = np.array([[5.0, 6.0], [7.0, 8.0]])
hasil = A @ B
per_elemen = A * B
print(hasil)
# [[19. 22.]
# [43. 50.]]
print(per_elemen)
# [[ 5. 12.]
# [21. 32.]]Ini sumber bug paling umum untuk orang yang baru pindah dari spreadsheet. * pada array NumPy adalah perkalian per elemen, bukan perkalian matriks. Selalu pakai @ atau np.matmul() untuk perkalian matriks.
Mengalikan matriks dengan vektor berarti memetakan vektor itu ke posisi baru. Ini berguna untuk membaca transformasi linear seperti rotasi, skala, atau proyeksi.
A = np.array([[2.0, 0.0], [0.0, 0.5]])
v = np.array([1.0, 1.0])
hasil = A @ v
print(hasil) # [2. 0.5]Matriks [[2, 0], [0, 0.5]] merentangkan sumbu x dua kali lipat dan memampatkan sumbu y jadi setengah. Melihat matriks sebagai mesin pemeta ruang adalah kunci memahami lapisan linear pada neural network.
Matriks identitas tidak mengubah vektor saat dikalikan. Invers matriks A membatalkan efek A, tetapi hanya ada bila A persegi dan punya rank penuh.
I = np.eye(3)
A = np.array([[1.0, 2.0], [3.0, 4.0]])
invers = np.linalg.inv(A)
cek = A @ invers
print(np.allclose(cek, np.eye(2))) # Truenp.linalg.inv() hanya untuk matriks persegi yang tidak singular. Untuk sistem yang tidak persegi atau singular, gunakan np.linalg.lstsq() atau np.linalg.solve() sesuai kasus.
Determinan untuk matriks persegi mengukur seberapa besar transformasi mengubah volume ruang. Determinan nol berarti transformasi meratakan ruang ke dimensi lebih rendah dan matriksnya singular. Rank adalah jumlah dimensi independen pada kolom atau baris.
A = np.array([[1.0, 2.0], [3.0, 4.0]])
singular = np.array([[1.0, 2.0], [2.0, 4.0]])
print(np.linalg.det(A)) # -2.0
print(np.linalg.det(singular)) # 0.0
print(np.linalg.matrix_rank(A)) # 2
print(np.linalg.matrix_rank(singular)) # 1Matriks singular di atas punya baris kedua yang kelipatan baris pertama, jadi rank-nya 1 dan determinannya nol. Data dengan kolom yang saling bergantung seperti ini membuat model regresi tidak bisa menemukan solusi unik.
Banyak algoritma machine learning bermuara pada menyelesaikan A @ x = b, di mana A adalah matriks data, x adalah parameter yang dicari, dan b adalah target.
A = np.array([[3.0, 1.0], [1.0, 2.0]])
b = np.array([9.0, 8.0])
x = np.linalg.solve(A, b)
print(x) # [2. 3.]
print(A @ x) # [9. 8.]solve() memakai dekomposisi LU dari LAPACK dan hanya bekerja untuk matriks persegi ber-rank penuh. Regresi linear biasa dengan jumlah fitur sama dengan jumlah baris bisa ditulis seperti ini.
Kalau sistem punya lebih banyak baris daripada kolom, tidak ada solusi yang memenuhi semua persamaan sekaligus. lstsq() memberi solusi least squares, yang meminimalkan kuadrat selisih. Ini cara regresi linear OLS dihitung di balik layar.
X = np.array([[1.0, 1.0], [1.0, 2.0], [1.0, 3.0]])
y = np.array([1.0, 2.0, 3.0])
solusi, sisa, rank, singular_values = np.linalg.lstsq(X, y, rcond=None)
print(solusi) # parameter least squaresUntuk matriks persegi A, vektor eigen v dan eigenvalue w memenuhi A @ v = w * v. Vektor eigen tidak berubah arah saat ditransformasi oleh A. Konsep ini menopang PCA, analisis kestabilan, dan banyak metode reduksi dimensi.
A = np.array([[2.0, 1.0], [1.0, 2.0]])
w, V = np.linalg.eig(A)
print(w) # eigenvalues
print(V) # kolom-kolomnya vektor eigenSetiap kolom V[:, i] adalah vektor eigen untuk eigenvalue w[i]. Kamu bisa memverifikasi hubungan ini.
for i in range(len(w)):
kiri = A @ V[:, i]
kanan = w[i] * V[:, i]
print(np.allclose(kiri, kanan)) # True, TrueUntuk matriks simetris, gunakan np.linalg.eigh(). Matriks simetris punya eigenvalue real dan vektor eigen yang saling ortogonal, dan eigh() lebih efisien untuk kasus itu.
B = np.array([[2.0, 1.0], [1.0, 2.0]])
w, V = np.linalg.eigh(B)
print(w) # [1. 3.]eig() untuk matriks umum, eigh() untuk matriks simetris atau Hermitian. Salah memilih tidak membuat hasil salah total, tetapi eigh() memberi jaminan urutan dan ortogonalitas yang sering kamu andalkan.
SVD memfaktorkan matriks A menjadi U @ np.diag(s) @ Vh. Ini bekerja untuk matriks apa pun, tidak harus persegi, jadi lebih umum daripada dekomposisi eigen. SVD menopang PCA, kompresi gambar, rekomendasi, dan pseudo inverse.
A = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
U, s, Vh = np.linalg.svd(A, full_matrices=False)
print(U.shape) # (2, 2)
print(s) # nilai singular, urut menurun
print(Vh.shape) # (2, 3)Matriks dapat disusun ulang dari ketiga bagian ini. Nilai singular s menunjukkan seberapa kuat tiap arah dalam data. Nilai kecil berarti arah itu hampir tidak membawa variasi dan bisa dibuang saat mereduksi dimensi.
rekonstruksi = (U * s) @ Vh
print(np.allclose(A, rekonstruksi)) # TruePertahankan beberapa nilai singular terbesar untuk memperkirakan matriks dengan penyimpanan lebih kecil. Untuk gambar, ini berarti menyimpan pendekatan yang tetap mempertahankan struktur besar.
rng = np.random.default_rng(7)
gambar = rng.normal(size=(50, 30))
U, s, Vh = np.linalg.svd(gambar, full_matrices=False)
k = 5
pendekatan = (U[:, :k] * s[:k]) @ Vh[:k, :]
print(pendekatan.shape) # (50, 30)Semakin kecil k, semakin kasar pendekatannya. Pilih k dengan melihat seberapa banyak total energi nilai singular yang kamu pertahankan.
Pseudo inverse umum dipakai saat matriks tidak persegi atau tidak punya invers biasa. Dalam regresi, ini memberi solusi least squares untuk sistem yang overdetermined atau underdetermined.
A = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
b = np.array([1.0, 2.0, 3.0])
x = np.linalg.pinv(A) @ b
print(x) # solusi least squaresPseudo inverse memakai SVD dan stabil terhadap matriks singular, tetapi untuk masalah regresi besar, library khusus seperti lstsq atau model scikit learn biasanya lebih tepat.
Dekomposisi QR memecah matriks menjadi matriks ortogonal Q dan matriks segitiga atas R. Ini dipakai untuk least squares dan beberapa algoritma eigenvalue.
A = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]])
Q, R = np.linalg.qr(A)
print(np.allclose(A, Q @ R)) # True
print(Q.shape) # (3, 2) untuk mode reducedDekomposisi Cholesky memecah matriks definit positif menjadi L @ L.T, dengan L segitiga bawah. Matriks kovarians adalah contoh definit positif, jadi Cholesky sering muncul dalam sampling dan optimasi.
M = np.array([[4.0, 2.0], [2.0, 3.0]])
L = np.linalg.cholesky(M)
print(np.allclose(M, L @ L.T)) # True
print(L)Cholesky jauh lebih cepat daripada invers umum untuk matriks definit positif, tetapi akan gagal bila matriksnya tidak definit positif. np.linalg.cholesky() melempar LinAlgError pada kasus itu.
Norma mengukur panjang atau besaran. Untuk vektor, norm L2 adalah jarak Euclidean. Untuk matriks, norm Frobenius sering dipakai untuk membandingkan seberapa dekat dua matriks.
a = np.array([3.0, 4.0])
b = np.array([1.0, 1.0])
l2 = np.linalg.norm(a)
l1 = np.linalg.norm(a, ord=1)
jarak = np.linalg.norm(a - b)
A = np.array([[1.0, 2.0], [3.0, 4.0]])
fro = np.linalg.norm(A, ord="fro")
print(l2) # 5.0
print(l1) # 7.0
print(jarak) # ~3.606
print(fro) # ~5.477Norm L1 menghitung jumlah nilai mutlak dan cenderung menghasilkan bobot jarang pada regularisasi L1. Norm L2 menghitung jarak Euclidean dan memunculkan regularisasi L2 yang menjaga semua bobot kecil.
PCA memproyeksikan data ke arah dengan variasi terbesar. Langkahnya: pusatkan data, hitung matriks kovarians, cari vektor eigen, lalu proyeksikan ke beberapa vektor eigen teratas. Vektor eigen utama adalah komponen utama.
rng = np.random.default_rng(42)
data = rng.normal(size=(100, 3))
tengah = data - data.mean(axis=0)
kovarian = np.cov(tengah, rowvar=False)
w, V = np.linalg.eigh(kovarian)
urutan = np.argsort(w)[::-1]
w = w[urutan]
V = V[:, urutan]
komponen = tengah @ V
print(komponen.shape) # (100, 3)Untuk memakai PCA di pekerjaan nyata, gunakan sklearn.decomposition.PCA alih alih menulis ulang langkah di atas. Implementasi scikit learn menangani centering, scaling, dan urutan komponen dengan benar.
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
hasil = pca.fit_transform(data)
print(hasil.shape) # (100, 2)
print(pca.explained_variance_ratio_)explained_variance_ratio_ menunjukkan proporsi variasi yang ditangkap tiap komponen. Ini dipakai untuk memilih jumlah komponen saat kamu ingin menyeimbangkan akurasi dan ukuran data.
Catatan penting: centering berarti mengurangkan mean per kolom. Standard scaling, yaitu membagi dengan standar deviasi, adalah keputusan terpisah. PCA peka terhadap skala, jadi bila fitur punya satuan yang jauh berbeda, standarisasi dulu sebelum PCA.
Lapisan linear sederhana menghitung output = input @ W + b, dengan W adalah matriks bobot dan b adalah vektor bias. Aktivasi non linear diterapkan setelahnya.
rng = np.random.default_rng(0)
input_data = rng.normal(size=(4, 3)) # 4 pengamatan, 3 fitur
W = rng.normal(size=(3, 2)) # 3 masuk, 2 keluar
b = rng.normal(size=(2,))
linear = input_data @ W + b
print(linear.shape) # (4, 2)Perkalian matriks di sini menerapkan transformasi yang sama ke banyak pengamatan sekaligus. Inilah alasan GPU, yang jago perkalian matriks besar, jadi penting dalam pelatihan model modern.
Softmax dipakai untuk mengubah skor menjadi probabilitas pada klasifikasi multi kelas.
def softmax(z):
stabil = z - z.max(axis=1, keepdims=True)
exp = np.exp(stabil)
return exp / exp.sum(axis=1, keepdims=True)
logits = np.array([[1.0, 2.0, 3.0], [3.0, 2.0, 1.0]])
prob = softmax(logits)
print(prob.sum(axis=1)) # [1. 1.]stabil di atas mencegah overflow saat z besar. Menjumlahkan probabilitas per baris harus selalu menghasilkan 1.
@ untuk perkalian matriks, bukan *.np.allclose() untuk membandingkan hasil floating point.shape sebelum operasi yang bergantung pada dimensi.np.linalg.solve() untuk sistem persegi, lstsq() untuk least squares, pinv() untuk pseudo inverse.eigh() untuk matriks simetris, eig() untuk matriks umum.assert A.shape[0] == A.shape[1] # pastikan persegi untuk inv
assert np.allclose(np.linalg.inv(A) @ A, np.eye(A.shape[0]))Kesalahan dimensi yang tertangkap assertion lebih murah daripada model yang melatih semalaman lalu gagal di tengah.
L @ L.T.Login atau daftar akun gratis untuk membaca cheat sheet ini.