K-NN 분류기(범주형 결과)
•
학습
◦
Lazy learning
◦
모델을 학습하는 단계가 존재하지 않음
◦
비모수적 방법
•
예측
◦
분류하고자 하는 새로운 관측치와 유사한 k개의 관측치를 식별하여, 해당 관측치들의 다수가 속한 Class로 분류
•
유사도 측정 방식
◦
Euclidean Distance
▪
▪
계산 비용이 낮다
▪
대부분의 경우 독립 변수의 척도를 균등하게 하기 위해, 독립 변수 표준화 과정을 거친다.
▪
각 특성(feature)의 단위에 민감
▪
표준화를 거치지 않으면, 의미 없는 기준으로 최근접 이웃이 결정될 위험이 있다.
◦
Manhattan Distance
▪
▪
각 특성(feature)의 단위에 민감
◦
Cosine Similarity
▪
▪
각 특성(feature)의 단위에 민감하지 않음
▪
벡터의 방향만 고려하게 됨
•
분류 규칙
◦
▪
최근접 이웃을 하나 찾아, 새로운 관측치를 해당 Class로 분류
◦
▪
다수결 결정 규칙 사용
▪
가 커질수록 학습 데이터에 존재하는 노이즈로 인해 발생하는 과적합의 위험을 줄일 수 있으나 지역적 구조 파악에 어려울 수 있다.
▪
가 작으면 데이터의 노이즈를 적합할 위험이 있다.
▪
→ 학습 데이터의 다수를 차지하는 Class로 분류 → 나이브 규칙과 일치
•
범주형 변수에서 이진 가변수로 변환
◦
회귀모델에서는 m개의 가변수 중 하나는 나머지 합으로 표현 가능 → 다중공선성 문제가 생김
◦
K-nn 모델에서는 m개의 가변수를 모두 사용하여야 함
▪
m-1개만 사용하는 경우 서로 다른 범주를 같은 거리로 판정할 위험이 있다.
K-NN 예측기(수치형 결과)
•
분류 규칙
◦
거리를 계산해 이웃 결정
◦
최근접 이웃들의 평균 결과 값을 사용하여 수치 결정
▪
가중 평균 사용 → 예측하고자하는 관측치로부터 먼 거리의 관측치는 영향을 줄임
K-NN 알고리즘의 장단점
•
장점
◦
모수에 대한 가정이 거의 존재하지 않음
◦
학습 데이터가 충분히 많고, 각 Class의 특성이 독립 변수 값들의 조합으로 결정될 때 성능 우수
•
단점
◦
추론(활용) 단계에서 근접 이웃을 찾는데 소요되는 시간 多
▪
차원 축소 → 거리 계산 시간 줄이기
◦
데이터의 차원이 크면, 학습 데이터의 양이 굉장히 많이 필요함
코드
import pandas as pd
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn.neighbors import NearestNeighbors, KNeighborsClassifier
df = pd.read_csv('dmba/RidingMowers.csv')
df['Number'] = df.index+1
trn, val = train_test_split(df, test_size=0.4, random_state=26)
predictors = ['Income','Number']
# 정규화
scaler = preprocessing.StandardScaler()
scaler.fit(trn[['Income','Lot_Size']])
df_Norm = pd.concat([pd.DataFrame(scaler.transform(df[['Income','Lot_Size']]), columns=['zIncome','zLot_size']), df[['Ownership','Number']]], axis=1)
trn_ = df_Norm.iloc[trn.index]
val_ = df_Norm.iloc[val.index]
new = pd.DataFrame([{'Income': 60, 'Lot_Size': 20}])
new_ = pd.DataFrame(scaler.transform(new), columns = ['zIncome','zLot_size'])
# 단순히 가장 가까운 데이터 포인트들의 거리와 인덱스를 반환
knn = NearestNeighbors(n_neighbors=3)
knn.fit(trn_.iloc[:, 0:2])
dist , idx = knn.kneighbors(new_)
trn_.iloc[idx[0],:]
# 새로운 데이터가 주어졌을 때, 가까운 이웃을 보고 어떤 클래스인지 예측
X = trn_[['zIncome','zLot_size']]
Y = trn['Ownership']
knn = KNeighborsClassifier(n_neighbors=4).fit(X,Y)
y = knn.predict(new_)
print(y)
Python
복사