위의 그림과 같이 사용자가 지정한 K에 따라 검증표본인 파란색 동그라미가 분류되는 집단이 달라진다.
✔ 유클리드 거리란?
피.타.고.라.스 떠올리면 된다!!
x(1,2) y(5,5) 두 점 사이의 거리는?
맨하튼 거리란?
x(1,2) y(5,5) 두 점 사이의 거리는?
정규화가 필요한 이유?
예를들어, 평균이 10,000정도, 소수점이 특성(feature)인 것을 생각해보자. 똑같은 기준으로 고려해서 반영하면 당연히 평균이 10,000인 특성들이 압도적으로 반영되기 때문에 터무니 없는 결론이 나올 수 있다.
최소-최대 정규화 VS Z-점수 표준화
1개월 간 매출액이라는 변수를 이용한다고 할 때, 훈련 데이터 셋의 최대값이 500만원인데, 예측할 미래의 데이터에는 500만원 이상인 값이 충분히 있을 수 있다. 그렇기 때문에 실무에서 보통 z-점수 표준화를 더 사용하기도 한다.
만약 1개월 간 구매일수라는 변수를 이용한다고 하면 최소(0일) 최대(30일)이 정해져 있기 때문에 이러한 경우에는 최소-최대 정규화를 사용해도 문제가 발생하지 않는다.
장점
1) 비교적 단순한 알고리즘으로 구현하기 쉽다.
2) 훈련 데이터를 그대로 가지고 있기 때문에, 훈련 속도가 매우 빠르다.
단점
1) 모델을 생성하지 않기 때문에 특징과 클래스 간 관계를 이해하는 데 제한적이다.
(모델의 결과를 통해 해석하지 않고, 미리 변수와 클래스 간 관계를 파악해 이를 알고리즘에 적용해야 원하는 결과를 얻을 수 있기 때문)
KNN에서의 관건은 최적의 K를 찾는 것이다.
(모델이 훈련 세트의 각 샘플에 너무 가깝게 맞춰져서 새로운 데이터에 일반화가 어려움)
(모델이 너무 단순해서 데이터의 내재적인 구조를 학습하지 못할 때 발생)
knn에서는 교차검증을 통해서 오분류율이 낮은 k를 선정한다.
k = 5 / train: test = 8:2
위의 비율로 전체 데이터셋이 train, test에 사용되도록 교차로 변경 된다.
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
data = load_breast_cancer()
df = pd.DataFrame(data.data, columns = data.feature_names)
df['target'] = data.target
df.head(3)
X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.2,random_state=100)
model = KNeighborsClassifier(n_neighbors = 5, weights = 'distance') #가중치 함수
model.fit(X_train,y_train)
n_neighbors = k (이웃의 수)
weights = 가중치 함수(default = 'uniform')
- 'uniform' : 균일 가중치로, 각 이웃의 모든 지점은 동일하게 가중치를 부여하는 것
- 'distance' : 거리역수로, 더 가까운 이웃이 멀리 있는 이웃보다 더 영향을 많이주는 것
from sklearn.metrics import roc_curve, auc
pred = model.predict(X_test)
#roc 곡선을 그리기 위해서 fpr, tpr을 구함
fpr, tpr, thresholds = roc_curve(y_test, pred)
AUC = auc(fpr,tpr)
print(AUC)
#fpr = false positive rate 실제로 아닌데 맞다고 '잘못' 판단
#tpr = true positive rate 실제로 맞는데, 맞다고 판단
#threshold = 분류기준
ex) threshold = 1 , 1 을 기준으로 1 이상이면 예측(분류)헌다.