KNN
K-Nearest Neighbors
K개 최근접 이웃 기반 분류/회귀 알고리즘. 간단하지만 효과적.
K-Nearest Neighbors
K개 최근접 이웃 기반 분류/회귀 알고리즘. 간단하지만 효과적.
KNN(K-Nearest Neighbors)은 가장 가까운 K개의 이웃 데이터를 기반으로 분류나 회귀를 수행하는 지도 학습 알고리즘입니다. 새로운 데이터가 들어오면 기존 데이터 중 가장 가까운 K개를 찾아 다수결(분류) 또는 평균(회귀)으로 예측합니다.
1951년 Evelyn Fix와 Joseph Hodges가 제안한 KNN은 "lazy learning" 알고리즘으로 불립니다. 학습 단계가 없이 모든 데이터를 저장하고, 예측 시에만 계산을 수행하기 때문입니다. 이해하기 쉽고 구현이 간단해 기초 ML 교육에 자주 사용됩니다.
거리 계산에는 유클리드 거리, 맨해튼 거리, 민코프스키 거리 등이 사용됩니다. 고차원 데이터에서는 "차원의 저주" 문제로 성능이 저하되므로 PCA 등으로 차원 축소가 필요합니다.
실무에서 KNN은 추천 시스템, 이상 탐지, 이미지 분류의 베이스라인으로 활용됩니다. K값은 보통 홀수(3, 5, 7)로 설정하며, 교차 검증으로 최적값을 찾습니다. 대용량 데이터에는 Ball Tree나 KD Tree로 검색 속도를 개선합니다.
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import cross_val_score, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris
from sklearn.pipeline import Pipeline
import numpy as np
# 데이터 로드
X, y = load_iris(return_X_y=True)
# 파이프라인 구성 (정규화 + KNN)
# KNN은 거리 기반이므로 정규화 필수!
pipeline = Pipeline([
('scaler', StandardScaler()),
('knn', KNeighborsClassifier())
])
# 최적 K값 찾기 (GridSearchCV)
param_grid = {
'knn__n_neighbors': [1, 3, 5, 7, 9, 11],
'knn__weights': ['uniform', 'distance'], # uniform: 동일 가중, distance: 거리 반비례
'knn__metric': ['euclidean', 'manhattan']
}
grid_search = GridSearchCV(
pipeline, param_grid, cv=5, scoring='accuracy', n_jobs=-1
)
grid_search.fit(X, y)
print(f"최적 파라미터: {grid_search.best_params_}")
print(f"최고 정확도: {grid_search.best_score_:.4f}")
# 최적 모델로 예측
best_model = grid_search.best_estimator_
new_sample = [[5.1, 3.5, 1.4, 0.2]] # 새로운 꽃 데이터
prediction = best_model.predict(new_sample)
proba = best_model.predict_proba(new_sample)
print(f"\n새 샘플 예측 클래스: {prediction[0]}")
print(f"클래스별 확률: {proba[0]}")
# K값에 따른 정확도 시각화
k_values = range(1, 21)
accuracies = []
for k in k_values:
knn = Pipeline([
('scaler', StandardScaler()),
('knn', KNeighborsClassifier(n_neighbors=k))
])
scores = cross_val_score(knn, X, y, cv=5)
accuracies.append(scores.mean())
print(f"\n최적 K: {k_values[np.argmax(accuracies)]} (정확도: {max(accuracies):.4f})")
"베이스라인으로 KNN을 먼저 돌려봤는데 정확도 89%가 나왔습니다. K=5, distance 가중치로 설정했고요. 복잡한 모델 도입 전에 이 수치가 비교 기준이 됩니다."
"KNN은 lazy learning이라 학습 단계가 없고 모든 데이터를 저장합니다. 예측 시 O(n*d)의 시간 복잡도가 발생해서 대용량 데이터에는 Ball Tree나 KD Tree로 O(log n) 검색을 구현합니다."
"고차원에서는 차원의 저주 때문에 모든 점이 비슷한 거리에 있게 됩니다. PCA로 차원을 줄이거나, Locality-Sensitive Hashing 같은 근사 최근접 이웃 알고리즘을 고려해야 해요."
스케일이 큰 피처가 거리 계산을 지배합니다. StandardScaler나 MinMaxScaler로 반드시 정규화하세요.
다수결 시 동점이 발생할 수 있습니다. 3, 5, 7 같은 홀수를 사용하세요.
weights='distance'로 설정하면 더 가까운 이웃에 높은 가중치를 부여해 정확도가 향상됩니다.