Algoritma machine learning buat klasifikasi atau clustering berdasarkan "tetangga terdekat".
Ini cocok buat pemula yang lagi nyobain ML (kayak gue), terutama buat sistem rekomendasi seperti di Netflix atau Spotify. Yuk, kita bahas step by step!
Apa Itu KNN? Singkatnya...
KNN itu kayak nyari temen deket buat nentuin sesuatu. Misalnya, kita punya titik baru di data, KNN bakal liat K tetangga terdekatnya (pake jarak Euclidean biasanya), terus pilih kelas yang paling banyak dari tetangga itu. Gampang kan? Gak perlu training rumit, cuma hitung jarak doang.
Visualisasi KNN Dasar (k=3)
Ini plot sederhana buat nunjukin gimana KNN kerja di data 2D. Ada dua kelas: A (biru) dan B (merah). Titik test (hijau X) lagi dicek tetangganya.
Penjelasan Simpel:
- Data training: Titik-titik biru (A) dan merah (B).
- Test point (hijau): [8, 8] – KNN hitung jarak ke semua titik, ambil 3 terdekat (2 B, 1 A).
- Hasil: Prediksi 'B' karena mayoritas tetangga B.
- Lingkaran: Batas radius ke tetangga ke-3, biar kita liat area pengaruhnya. Kalo kita ubah K jadi 5, mungkin hasil beda. Ini nunjukin KNN sensitif sama K!
Kode buat bikin plot ini:
import matplotlib.pyplot as plt
import numpy as np
# Data contoh
training_data = [[1, 2], [2, 3], [3, 4], [6, 7], [7, 8]]
training_labels = ['A', 'A', 'A', 'B', 'B']
test_point = [8, 8]
k = 3
# Fungsi jarak (Euclidean)
def euclidean_distance(p1, p2):
return np.sqrt(np.sum((np.array(p1) - np.array(p2)) ** 2))
# Hitung tetangga
distances = [(euclidean_distance(test_point, p), lbl, p) for p, lbl in zip(training_data, training_labels)]
distances.sort(key=lambda x: x[0])
k_nearest = distances[:k]
# Plot
plt.figure(figsize=(8, 6))
colors = {'A': 'blue', 'B': 'red'}
for p, lbl in zip(training_data, training_labels):
plt.scatter(p[0], p[1], color=colors[lbl], label=f'Class {lbl}')
plt.scatter(test_point[0], test_point[1], color='green', marker='X', s=200, label='Test Point')
for dist, lbl, p in k_nearest:
plt.scatter(p[0], p[1], color=colors[lbl], edgecolor='black', linewidth=2)
plt.plot([test_point[0], p[0]], [test_point[1], p[1]], 'k--')
# Lingkaran radius
if k > 0:
radius = distances[k-1][0]
circle = plt.Circle(test_point, radius, color='gray', fill=False, linestyle='--')
plt.gca().add_patch(circle)
plt.title('KNN Visualization with k=3')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.legend()
plt.grid(True)
plt.show()
KNN di Sistem Rekomendasi (User-Based Collaborative Filtering)
Sekarang, aplikasinya ke rekomendasi film. Ide dasar: Cari user yang selera ratingnya mirip sama kita (pake KNN), terus rekomen film yang mereka suka tapi kita belum nonton. Mirip "orang mirip kita suka ini nih!"
Visualisasi User Similarity (k=2)
Ini plot rating film A vs B. User digambarin sebagai titik berdasarkan ratingnya. TargetUser (hijau X) lagi dicek tetangganya.
Penjelasan Simpel:
- Sumbu: Rating Film A (x) vs Film B (y). Semakin deket titik, semakin mirip selera.
- TargetUser (hijau X): kita nih, ratingnya [4, np.nan, np.nan, np.nan] – film C & D belum dirating.
- Nearest Neighbors (orange): User2 (jarak 0, super mirip) & User1 (jarak 1.41). Mereka dipilih karena KNN.
- Anotasi kuning: Rekomendasi film yang belum kita rating, prediksi dari rata-rata rating neighbors. Film C (4.0) lebih direkomendasikan daripada Film D (2.5) karena skor lebih tinggi. Panah nunjukin hubungannya langsung dari posisi kita .
- Other Users (abu/abu muda): Yang lain, gak terlalu mirip, jadi gak dipake. Ini bikin kita paham visually gimana KNN nyari "temen selera" dan kasih saran film.
Kode buat plot rekomendasi (pake Pandas buat data rating):
import pandas as pd
import matplotlib.pyplot as plt
# Data rating contoh
data = {'Film A': [4, 5, 3, 2, 4], 'Film B': [5, 4, 4, 3, 2], 'Film C': [3, 5, 2, 4, np.nan], 'Film D': [2, 3, 5, 1, np.nan]}
users = ['User1', 'User2', 'User3', 'User4', 'TargetUser']
df = pd.DataFrame(data, index=users)
# Fungsi jarak dengan NaN
def euclidean_distance_with_nan(r1, r2):
mask = ~r1.isna() & ~r2.isna()
if mask.sum() == 0: return np.inf
return np.sqrt(((r1[mask] - r2[mask]) ** 2).sum())
# Hitung neighbors (contoh k=2)
target = df.loc['TargetUser']
distances = {u: euclidean_distance_with_nan(target, df.loc[u]) for u in df.index if u != 'TargetUser'}
sorted_dist = sorted(distances.items(), key=lambda x: x[1])
neighbors = [u for u, d in sorted_dist[:2]] # User2, User1
# Prediksi rekomendasi (rata-rata sederhana)
unrated = target[target.isna()].index
preds = {m: df.loc[neighbors, m].mean() for m in unrated} # {'Film C': 4.0, 'Film D': 2.5}
# Plot
plt.figure(figsize=(10, 8))
for u in df.index:
color = 'green' if u == 'TargetUser' else 'orange' if u in neighbors else 'lightgray'
marker = 'X' if u == 'TargetUser' else 'o'
size = 200 if u == 'TargetUser' or u in neighbors else 100
plt.scatter(df.loc[u, 'Film A'], df.loc[u, 'Film B'], color=color, marker=marker, s=size, label=u if color != 'lightgray' else 'Other Users')
# Anotasi rekomen
tx, ty = df.loc['TargetUser', 'Film A'], df.loc['TargetUser', 'Film B']
offset = 0.5
for m, p in sorted(preds.items(), key=lambda x: x[1], reverse=True):
plt.annotate(f'Rec: {m} ({p:.1f})', (tx, ty), (tx + 0.5, ty + offset), arrowprops={'facecolor': 'purple', 'connectionstyle': 'arc3,rad=-0.2'})
offset -= 0.5
plt.title('User Similarity and Recommendations (k=2) based on Film A and B Ratings')
plt.xlabel('Rating for Film A')
plt.ylabel('Rating for Film B')
plt.grid(True)
plt.legend()
plt.show()
Kesimpulan dan Tips
KNN gampang dipake buat rekomendasi karena cuma butuh data rating, gak ribet model. Tapi hati-hati sama skalanya (bisa lambat kalo data gede) dan pilih K yang pas. kita bisa improve pake weighted average atau cosine similarity buat kemiripan lebih akurat.


Top comments (0)