안녕하세요 IT`s닝겐입니다.
이전 글 K-최근접 이웃#1에 이어 진행하도록 하겟습니다.
이번 진행은 기존 생선데이터를 Numpy배열로 변환 한 뒤, 그 데이터를 분리하여, 각 훈련 데이터와, 테스트 데이터로 분리하고 K-최근접 이웃을 통해 훈련하고, 평가해보며, 임의의 데이터에 대한 산점도를 찍어 K-최근접 이웃이 어떠한 데이터를 참고하는지 확인해보록 하겠습니다.
1. 과정
- 기존 Bream, Smelt생선 데이터를 무게와 길이 별로 합칩니다.
- 합쳐진 데이터를 기존과 동일하게 (길이, 무게)인 2차원 배열로 변환하고, Bream과, smelt에 대한 target 데이터를 생성합니다.
- 생성된 2차원 배열데이터와 타겟데이터를 Numpy 배열로 변환하고, numpy의 random.shffle 메서드를 활용 하여, 49에 대한 랜던값을 생성하여, index에 저장합니다.
- 생성된 49개의 index배열데이터를 가지고, 변환된 numpy 생선데이터 배열의 인덱스로 사용하여, 데이터를 랜덤하게 훈련데이터와 테스트 데이터로 분리합니다.
- 이후 K-최근접 이웃 알고리즘으로 훈련데이터를 활용하여 훈련하고, 테스트 데이터로 평가하도록합니다.
- 훈련데이터와, 테스트 데이터에 대한 산점도를 그려봅니다.
- 임의의 데이터를 가지고 산점도에 표현하여 K-최근접 이웃이 어떠한 데이터를 참고하는지 확인합니다.
2. 코딩
# 생선데이터 준비
bream_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0, 31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0, 35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0]
bream_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0, 500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0, 700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0]
smelt_length = [9.8, 10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]
smelt_weight = [6.7, 7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]
# 준비된 생선데이터를 길이, 무게 별로 합칩니다.
length = bream_length + smelt_length
weight = bream_weight + smelt_weight
# 합쳐진 길이, 무게 데이터를 2차원 배열로 변환하며, bream은 '1' Smelt는 '0'으로 생선의 타겟데이터를 생성합니다.
fish_data = [[l, w] for l, w in zip(length, weight)]
fish_target = [1]*35 + [0]*14
# 2차원 배열의 생선데이터와, 새로 생성된 생선타겟데이터를 numpy 배열로 변환
import numpy as np
input_arr = np.array(fish_data)
target_arr = np.array(fish_target)
# 생선데이터 총 갯수에 맞쳐 index배열 생성, 이 index배열을 random.shuffle 메서드를 이용하여, randum데이터 생성
index = np.arange(49)
np.random.shuffle(index)
# 생선데이터의 일부를 random한 index배열의 값을 인덱스로 활용하여, random한 훈련데이터 생성(35)
train_input = input_arr[index[:35]]
train_target = target_arr[index[:35]]
# 생선데이터의 일부를 random한 index배열의 값을 인덱스로 활용하여, random한 테스트데이터 생성(14)
test_input = input_arr[index[35:]]
test_target = target_arr[index[35:]]
# 사이킷런의 K-최근접 이웃
from sklearn.neighbors import KNeighborsClassifier
kn = KNeighborsClassifier()
kn = kn.fit(train_input, train_target)
print(kn.score(test_input, test_target))
# 평가 값을 1.0으로 100프로의 평가 율을 가지고있습니다. 당연한 결과 입니다. 생선데이터와 타겟이터가 동일한 인덱스 값으로 움직였기에, 35개와 14개를 랜덤하게 나누었지만 결과적으론 같은데이터를 그냥 섞었을뿐이기 때문입니다.
# 임의 데이터 길이 25, 무게 150 데이터의 거리값 확인
distances, indexes = kn.kneighbors([[25, 150]])
# 산점도 그리기
import matplotlib.pyplot as plt
plt.scatter(train_input[:,0], train_input[:,1]) # 전체 데이터를 표시
plt.scatter(25, 150, marker='^') # 타겟 데이터 '^' 로 표시
plt.scatter(train_input[indexes, 0], train_input[indexes, 1], marker='D') # K-최근접 이웃 알고리즘의 Knightbors 메서드를 사용하여 얻은 인덱스 값으로, 타겟데이터에 가까운 데이터 5개를 마름모로 표기
# plt.xlim((0, 1000)) # 축을 임의로 정의
plt.xlabel('length') # xlabel 내용 표기
plt.ylabel('weight') # ylabel 내용 표기
plt.show() # plt.데이터 출력


4. 결과
- 위 산점도를 볼때 임의 데이터는 삼각형 모양의 노란 점이고, K-최근접이웃에 알고리즘에(기본값: 5) 따라 최근접 데이터 5개를 녹색으로 표기하였습니다.
- 앞서 생선데이터에 대한 산점도를 그려봤을때, 왼쪽하단의 경우 Smelt데이터가 존재하엿으며, 우측 상단으로 Bream에 대한 데이터가 많이 분포했었습니다. 그림상으로 볼 때 길이 25에 무게 150인 데이터는 Bream에 더 근접한것으로 보여집니다.
- 이처럼 머신러닝은 준비된 데이터가 있다면, 머신러닝을 통해 학습하고, 평가하여, 임의의 데이터에 대한 분류나 예측을 할 수 있습니다.
- 즉, 기존 코딩의 경우 데이터가 입력이되고, 그 고유에 값들이 항상 업데이트가 이루어져야지만, 추가된 데이터에 대한 결과를 얻을 수 있는반면, 머신러닝의 경우 데이터를 통학 학습으로, 새로운 데이터에 대한 결과를 예측하거나, 분류 할수 있음을 의미합니다.
'Python ML, Deep Learning' 카테고리의 다른 글
Python 머신러닝 #분류하기 (K-최근접 이웃#1) (0) | 2021.04.20 |
---|---|
Python 머신러닝 #기계학습 이해하기 (0) | 2021.04.19 |
Python 머신러닝 #1 colab환경 준비 (1) | 2021.04.19 |
Python 머신러닝 시작하기 (1) | 2021.04.19 |