신이 되고 싶은 갓지이

3. Python 머신러닝 - 지도학습1(KNN, 의사결정나무)의 실습 후 모델 성능 측정하기 본문

Python

3. Python 머신러닝 - 지도학습1(KNN, 의사결정나무)의 실습 후 모델 성능 측정하기

갓지이 2024. 1. 25. 22:52

1. 지도학습

: 여러 feature(input variable)의 패턴을 파악하여 target(target variable)을 예측. 지도학습의 종류는 선형회귀, KNN, RandomForest, Xgboost, Neural Network등이 있다. 

 

1) KNN(k 근접 이웃)

1. KNN 알고리즘 프로세스

  1. 가장 가까운 k개의 점을 찾는다 (k는 마음대로 설정 가능)
  2. k개의 점이 어느 target에 속해있는지 확인
  3. 많은 범주 쪽으로 분류

 

2. k값의 결정

  • k가 너무 작으면 노이즈에 민감한 과적합(overfitting)의 우려가 있음
  • k가 너무 크면 지역적 구조를 파악 하 수 있는 능력을 잃어 과소적합(underfitting)의 우려가 있음
  • 검증 데이터에 대한 에러가 가장 낮은 적절한 k를 찾아야 우수한 KNN 모델을 만들 수 있음

 

3. k값 결정 프로세스

  1. 학습 데이터를 이용해 k별로 KNN모델을 학습
  2. 만들어진 모델을 이용해 검증 데이터에서 예측
  3. 검증 데이터에서 실제값과 예측치의 에러율을 확인
  4. 에러율이 가장 작은 k가 최적의 k값

 

 

2) KNN 실습 (분류)

: 범주형 데이터의 결과를 예측하는 분류를 위한 학습

import pandas as pd
import os

# 경로설정
os.chdir(r'C:\Users\kmlam\Documents\data')  # 데이터 파일이 작업중인 ipynb의 경로와 다른 경로에 있는 경우

# 파일 불러오기
iris = pd.read_csv("./data/IRIS.csv")

# 타겟 변수의 구성을 확인
iris['species'].value_counts()

# 아이디를 생성
iris['id'] = range(len(iris))  # 고유 번호 부여

 

 

1단계 train, test 데이터 생성

- train = iris.sample(n, replace=False, random_state=####).reset_index().drop(['index'], axis=1)

  • 학습 데이터 생성
  • n개의 데이터를 비복원 추출로 랜덤하게(이 추출 패턴은 ####) 추출하여 sample을 만든 후, 인덱스를 삭제

 

- test = iris.loc[ ~iris['id'].isin(train['id'])]

  • 테스트 데이터 생성
  • train의 id를 제외한 id만 추출
# iris 중에서 100개를 랜덤으로 추출해 train 데이터로 지정
train = iris.sample(100, replace=False, random_state=2020).reset_index().drop(['index'],axis=1)

# 추출되지 않은 나머지를 test 데이터로 지정
test = iris.loc[ ~iris['id'].isin(train['id'])]
test = test.reset_index().drop(['index'],axis=1)

 

 

2단계 KNN

- knn = KNeighborsClassifier(n_neighbors=n) 

  • k값을 n으로 하는 KNN 객체 생성

- knn.fit(train[['feature1', 'feature2', 'feature3']], train['target'])

  • train 데이터로 학습시키기

- predictions = knn.predict(test[['feature1', 'feature2', 'feature3']])

  • test 데이터를 통해 예측 확인
# knn을 위한 패키지를 임포트
from sklearn.neighbors import KNeighborsClassifier

knn = KNeighborsClassifier(n_neighbors=3)

# knn 모델을 train 데이터에서 학습
knn.fit(train[['sepal_length','sepal_width','petal_length','petal_width']], train['species'])

# 예측 진행
predictions = knn.predict(test[['sepal_length','sepal_width','petal_length','petal_width']])

# 정확도 확인
test['pred'] = predictions
(test['pred'] == test['species']).mean()
# (pd.Series(predictions) == test['species']).mean()   # 칼럼을 붙이지 않고 사용 가능

 

 

3단계 최적의 k값 찾기

# 최적의 k 찾기
# 아래의 결과값들은 운영 컴퓨터에 따라 달라질 수 있음
for k in range(1,30):
    knn = KNeighborsClassifier(n_neighbors=k)
    knn.fit( train[['sepal_length','sepal_width','petal_length','petal_width']] , train['species'] )
    predictions = knn.predict( test[['sepal_length','sepal_width','petal_length','petal_width']] )
    print((pd.Series(predictions) == test['species']).mean())

결과적으로 가장 높은 0.98의 비율을 갖는 k값이 상당히 많다. 이들 중 가장 처음 0.98의 값을 보이는 k값을 선택하는것이 옳다. 이는 k값이 클 수 록 계산시간이 오래 걸리기 때문.

 

 

 

3) KNN 실습 (회귀)

: 연속형 데이터의 결과를 예측하는 분류를 위한 학습

 

1단계 train, test 데이터 생성

# 회귀를 위해 필요한 컬럼을 제거
del train['species']
del test['species']

 

 

2단계 KNN

위의 분류형과 패키지만 KNeighborsRegressor로 다를 뿐 방법은 동일하다.

# 필요 패키지 설치
from sklearn.neighbors import KNeighborsRegressor

# 모델 정의
knn = KNeighborsRegressor(n_neighbors=2)

# 모델 학습
knn.fit(train[['sepal_length','sepal_width','petal_length']], train['petal_width'])

# 예측
predictions = knn.predict(test[['sepal_length','sepal_width','petal_length']])

# 결과 확인
predictions

# mae : 회귀문제에서 모델의 성능을 평가하는 방법 (예측치와 실제값의 차이의 평균으로 예측 결과 확인)
abs(test['petal_width'] - pd.Series(predictions)).mean()   # 0.16799999999999998

 

 

3단계 최적의 K 찾기

# 최적의 k를 찾기 (아래의 결과값들은 운영하시는 컴퓨터에 따라 달라질 수 있음)
for k in range(1,30):
    knn = KNeighborsRegressor(n_neighbors=k)
    knn.fit( train[['sepal_length','sepal_width','petal_length']] , train['petal_width'] )
    predictions = knn.predict( test[['sepal_length','sepal_width','petal_length']] )
    print(str(k)+' :'+str(abs(test['petal_width'] - pd.Series(predictions)).mean()))

→ 8 : 0.16125으로 최적의 K값은 8이다.