본문 바로가기
공부기록/데이터사이언스

K-최근접 이웃(KNN) -데싸노트

by tankwoong 2024. 3. 24.
반응형

K-최근접 이웃(KNN) 모델은 거리 기반 모델로 종속변수가 범주형이며, 개수가 3개 이상인 다중 분류(Multicalssification)를 다룬다. 직관적이고 간단하며, 선형관계를 가정 안 해도 되지만, 데이터가 커질수록 상당히 느려질 수 있고, 아웃라이어(이상치)에 취약하다. 

문제 정의

각각의 성분에 따라서 와인등급이 어떻게 되는지 예측하기

데이터 확인하기

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

file_url = 'https://media.githubusercontent.com/media/musthave-ML10/data_source/main/wine.csv'
data=pd.read_csv(file_url)

필수 라이브러리를 한번에 불러오고, csv파일도 불러온다..

alchohol과 nonflavanoid_pheols가 결측치가 있는 것을 확인할 수 있다.

countplot을 통하여 클래스 별로 개수가 몇 개 있는지 알 수 있다.

결측치 처리하기 

isna함수를 통해서 결측치가 있는 것을 확인할 수 있다.

isna 함수 뒤에 mean함수를 통해서 어느 정도 결측치가 있는지 확인할 수 있다. alchohol과 nonflavanoid_pheols은 각각 1.1%, 2.8% 정도의 결측치를 갖는다. 

결측치를 보고 결측치를 어떻게 할지 정해야한다.

- 결측치가 있는 행을 제거하기 

결측치 비중이 매우 낮아야 하고, 데이터 크기도 충분히 커야 함 

data.dropna() 
#결측치 행 제거 
data = data.dropna()
data.dropna(inplace=True)
#데이터 프레임까지 바꿔버림
data.dropna(subset=['alcohol'])
#특정 행만 제거할 수 있음

-변수를 제거하기 

신중하게 판단 

data.drop(['alchohol','nonflavanoid_phenols'], axis=1)

- 결측값 채우기: fillna()

평균값으로 채울 수 있지만 이상치의 영향을 받을 수 있으므로, 중윗값을 사용할 수 있다.

data.fillna(data.median(), inplace=True)

스케일링 적용하기

표준화 스케일링 평균 0, 표준편차 1 데이터를 고르게 하고 싶을 때 사용, outlier의 영향을 받음,
기존 분포 형태가 사라지고 정규분포를 따르는 결과물을 가져옴
로버스트 스케일링 데이터에 아웃라이어의 영향이 크고 피하고 싶을 때, 변환된 데이터의 범위는 다른 2개 보다 넓게 나타남 
최소-최대 스케일링 데이터 분포의 특성을 최대한 그대로 유지하고 싶을 경우 
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler

스케일링을 적용할 때, 종속변수를 제외해야 하고, 스케일링 전에 훈련 셋과 시험 셋을 나눠야 한다.

from sklearn.model_selection import train_test_split
X= data.drop('class',axis=1)
y = data['class']
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.2, random_state=100)

훈련셋과 시험셋을 나눠준다.

mm_scaler= MinMaxScaler()
mm_scaler.fit(X_train)

MinMaxScaler를 통해 X_train을 학습시킨다.

두 가지 방법 중 하나를 골라 학습 데이터와 테스트 데이터를 트랜스폼 해준다.

X_train_scaled = mm_scaler.transform(X_train)
X_test_scaled = mm_scaler.transform(X_test)
X_train_scaled = mm_scaler.fit_transform(X_train)
X_test_scaled= mm_scaler.transform(X_test)
from sklearn.neighbors import KNeighborsClassifier

knn = KNeighborsClassifier()
knn.fit(X_train_scaled,y_train)
pred = knn.predict(X_test_scaled)
from sklearn.metrics import accuracy_score
accuracy_score(y_test,pred)


0.8888888888888888

모델링 및 예측/평가를 해준다.

하이퍼파라미터 튜닝

scores = []
for i in range(1,21):
    knn = KNeighborsClassifier(n_neighbors=i)
    knn.fit(X_train_scaled,y_train)
    pred = knn.predict(X_test_scaled)
    acc = accuracy_score(y_test,pred)
    scores.append(acc)

scores를 통해 n_neighbors가 언제 최적의 값인지 살펴본다. 지금은 개수가 얼마 없지만 갯수가 많아지면 어디가 최대인지 확인하기가 어렵다.  그래서 그래프로 확인해 보겠다.

sns.lineplot(x=range(1,21), y=scores)
plt.xticks(range(1,21))
plt.show()

그래프로 확인했을 때 13 이후에는 성능이 좋아지지 않는다. 따라서 13이 최적의 매개변수가 된다.

 

만약 이웃을 고려할 때 동점일 경우가 생길 수 있는데, 고려할 이웃수를 항상 홀수로 유지하거나, 가중치를 주어서 해결할 수 있다.

 

반응형