본문 바로가기
두두 IT/머신런닝(ML)

TODO와 함께하는 복습 - 5 (KNN & SVM)

by DoDo's 2026. 5. 25.
반응형

📦 패키지 1: 직관과 거리의 마술사 (KNN & SVM)

1. 08_최근접이웃 (K-Nearest Neighbors, KNN)

"KNN은 한마디로 **'근묵자흑'**이나 '유유상종' 알고리즘이야.

새로운 데이터가 들어왔을 때, '너랑 가장 가까운 거리에 있는 이웃 $K$명 손들어봐!'라고 시키는 거지.

만약 $K=3$으로 정했는데 주변에 가장 가까운 이웃 3명 중 2명이 짜장면을 먹고 있고 1명이 짬뽕을 먹고 있다면, 이 새로운 데이터의 정답도 '짜장면'이라고 다수결로 분류하는 아주 직관적인 방식이야."

💻 핵심 이론 및 코드 규칙

  • 핵심 다이얼(하이퍼파라미터): n_neighbors (몇 명의 이웃을 볼 것인가?)
    • 이 숫자가 너무 작으면 주변의 아주 작은 노이즈에도 쉽게 흔들리고(과적합), 너무 크면 데이터의 세밀한 경계를 무시하고 뭉뚱그려 판단하게 됩니다.
  • 데이터 전처리 필수: 거리를 재는 모델이기 때문에, 아까 배웠던 스케일링(StandardScaler)이 무조건 필수입니다. 안 그러면 체급이 큰 특징(예: 집값)에만 거리가 압도당합니다.

2. 07_서포트 벡터 머신 (Support Vector Machine, SVM)

🗣️ 남에게 가르칠 때 (이해하기 쉬운 비유)

"SVM은 두 클래스 사이에 '가장 넓고 안전한 중앙분리대(도로)'를 건설하는 건설소장님이야.

빨간 팀과 파란 팀이 싸우지 않게 땅 한가운데에 선을 그어야 하는데, 빨간 팀의 가장 직전 최전방격 군인(서포트 벡터)과 파란 팀의 최전방 군인 사이의 **거리(마진, Margin)**를 계산해서 정확히 그 한가운데에 최대한 넓은 도로를 뚫어 경계를 나누는 깐깐한 알고리즘이지."

💻 핵심 이론 및 코드 규칙

  • 핵심 다이얼(하이퍼파라미터):
    • C (규제 파라미터): 도로 안에 상대편 군인이 조금 들어오는 것을 허용할지 말지 정하는 척도입니다. C가 너무 크면 깐깐해져서 도로 폭이 좁아지고(과적합), C가 너무 작으면 도로를 너무 대충 넓게 잡아서 분류를 못 하게 됩니다.
    • kernel: 직선으로 도저히 안 나눠지는 복잡한 데이터를 차원을 높여서 3차원 큐브 형태로 구부려 자르는 기술입니다. 보통 기본값인 'rbf'를 씁니다.
  • 이것도 거리를 기반으로 작동하므로 스케일링이 무조건 필수입니다.

📝 TODO 실습 문제: KNN과 SVM을 파이프라인에 장착하기

방금 배운 두 알고리즘의 성질(스케일링 필수)을 기억하시죠?

그리드 서치 에러를 극복하셨으니, 이번에는 파이프라인과 결합된 KNN 모델의 최적의 이웃 개수(n_neighbors)를 찾는 코드를 작성해 보겠습니다.

아래 코드의 빈칸(___) 4개를 채워 완성해 보세요.

Python
 
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier # KNN 모델 소환

# 데이터 준비
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
    cancer.data, cancer.target, test_size=0.3, random_state=0, stratify=cancer.target
)

# 1. 파이프라인 생성: StandardScaler와 KNN 모델을 연결하세요.
knn_pipe = make_pipeline(StandardScaler(), ________())

# 2. 파라미터 후보군 만들기: 이웃의 개수 후보를 3, 5, 7로 지정하려고 합니다.
# [🚨주의] 모델이름소문자 + 언더바2개(__) + 파라미터명 규칙을 잊지 마세요!
# KNeighborsClassifier의 파이프라인 내부 소문자 이름은 'kneighborsclassifier' 입니다.
params = {
    '____________________': [3, 5, 7]
}

# 3. 그리드 서치 객체 생성 (파이프라인, params 연결, cv=5)
grid_search = ________(knn_pipe, param_grid=params, cv=5)

# 4. 학습 시작
grid_search.________(X_train, y_train)

# 최적의 결과 확인
print("최적의 이웃 개수:", grid_search.best_params_)
print("최고 모의고사 점수:", grid_search.best_score_)

 

 

 

정답

#준비물 
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier # KNN 모델 소환

cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(
    cancer.data, cancer.target, test_size=0.3, random_state=0, stratify=cancer.target
)

# 1. 파이프라인 생성: StandardScaler와 KNN 모델을 연결하세요.
knn_pipe = make_pipeline(StandardScaler(), KNeighborsClassifier())

# 2. 파라미터 후보군 만들기: 이웃의 개수 후보를 3, 5, 7로 지정하려고 합니다.
# [🚨주의] 모델이름소문자 + 언더바2개(__) + 파라미터명 규칙을 잊지 마세요!
# KNeighborsClassifier의 파이프라인 내부 소문자 이름은 'kneighborsclassifier' 입니다.
params = {
    'kneighborsclassifier__n_neighbors': [3, 5, 7]
}

# 3. 그리드 서치 객체 생성 (파이프라인, params 연결, cv=5)
grid_search = GridSearchCV(knn_pipe, param_grid=params, cv=5)

# 4. 학습 시작
grid_search.fit(X_train, y_train)

# 5. 최적의 결과 확인
print("최적의 이웃 개수:", grid_search.best_params_)
print("최고 모의고사 점수:", grid_search.best_score_)

 

결과값

최적의 이웃 개수: {'kneighborsclassifier__n_neighbors': 7}
최고 모의고사 점수: 0.9699367088607594

 

반응형