2 - 2 데이터 전처리
앞의 모델에서, height = 25 , weight = 150의 데이터를 입력하면 도미가 아닌 빙어라고 예측한다.
이 문제를 해결하기 전, 먼저 데이터를 더 학습해보자.
데이터 다시 준비
fish_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, 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]
fish_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, 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]
넘파이를 이용하여 간편하게 만들자 삐리삐리
import numpy as np
np.columns_stack(([1,2,3],[4,5,6]))
array([[1,4],
[2,5],
[3,6]])
np.column_stack() = 전달받은 리스트를 일렬로 세운 다음 차례대로 나란히 연결해준다. [columns=열]
쉽게 말해, 리스트 안의 index끼리 차례대로 묶어 2개씩 리스트를 생성함. (이게 쉽게 말한거야?)
이 방법을 통해 fish data를 새로 만들어보자.
import numpy as np
fish_Data = np.columns_stack((fish_length,fish_weight))
# 잘 되었는지 확인하기 위해 5개의 표본만 살펴보자.
fish_Data[:5]
[[25.4 , 242], [26.3 , 290], [26.5 , 340], [29 , 340], [29 , 430]
ㅇㅋ 잘 되었다.
학교때 배운 numpy의 다양한 메서드들을 이용해 타겟도 만들어보자.
np.concatenate() = 배열 합치기
fish_target = np.concatenate((np.ones(35), np.zeros(14)))
print(fish_target)
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,,0,0,0,0,0,0,0,0,0,0,0]
# 사이킷런으로 훈련 세트와 테스트 세트 나누기
앞의 인덱스 섞는 방법(random.shuffle) 보다 쉽게 쓸 수 있는 방법이 있다.
사이킷런은 머신러닝을 포함한 다양한 유틸리티 도구를 제공한다.
from sklearn.model_selection import train_test_split
tarin_set , test_set, train_target, test_target = train_test_split(fish_Data, fish_target, random_state=42)
train_test_split() : 매개변수의 리스트나 배열을 비율에 맞게 훈련세트와 테스트 세트로 나누어 준다 !
위에서는 2개의 배열을 전달했으므로 총 4개의 배열이 반환된다.
첫 번째 배열의 훈련,테스트 세트,
두 번째 배열의 훈련,테스트 세트
train_test_split(input, target, 랜덤시드)
# 복습 : [ 데이터 = 입력 = input ] + [ 정답 = target ] = 훈련 데이터
이제 맨 위에서 도미 분류 오류를 살펴보자!
from sklearn.neighbors import KNeighborsClassifier
kn = KNeighborsClassifier()
kn.fit(train_set, train_target)
kn.score(test_set, test_target)
1.0
print(kn.predict([[25, 150]])
0.0 # 도미= 1, 빙어 = 0
코드만 보고 문제는 해결되지 않으니 그림이라도 그려보자.
import matplotlib.pyplot as plt
plt.scatter(train_set[:,0],train_set[:,1])
plt.scatter(test_set[:,0], test_set[:,1])
plt.xlable("length")
plt.ylabel("weight")
plt.show()
직관적으로 그림만 보면 도미데이터와 가까워 보인다. 하지만 컴퓨터는 빙어로 인식한다. 왜일까? (x,y축 비율때문이다.)
우선 그 전에 Kneighborsclassifier()의 5가지 기준샘플들을 보기좋게 표시해보자.
distances , indexes = kn.kneighbors([[25,150]]) # 25,150의 k최근접이웃 5개의 거리와 인덱스번호
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') #깊생
plt.show()
5개의 기준샘플 중 다수(3개)는 빙어였다 !
직접 거리를 출력해보자.
print(distances)
array([[ 92.00086956, 130.48375378, 138.32150953, 140.00603558,
140.62090883]])
92,130,138,140 이상하다. 기준을 맞춰보자!
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')
plt.xlim((0,1000))
plt.show()
x축과 y축의 비율을 같게 했더니 일직선으로 나온다!! 이렇게 보면 직관적으로 봐도 k최근접 알고리즘과 유사하게 도출할 수 있다.
★★★이렇게 데이터를 일정한 기준으로 맞춰주는 것을 데이터 전처리라고 한다.★★★
가장 널리 사용하는 전처리 방법 중 하나느 표준점수이다.
표준점수 = 각 특성값이 평균에서 표준편차의 몇 배 만큼 떨어져 있는지를 나타낸다.
표준점수 = 각 값에서 평균을 빼고 표준편차로 나누어 주면 된다. [ 넘파이를 통해 도출 ]
mean = np.mean(train_input, axis = 0) # axis = 0, axis = 1 차이점?
std = np.std(train_input, axis = 1 )
axis = 0 : 행을 따라 각 열의 값들을 계산 ( 이게 맞다 !)
axis = 1 : 열을 따라 각 행들의 값들을 계산 ( 행마다 값이 나옴 !) (책 그림 p.100참조)
print(mean,std)
[ 26.175 418.08888889] [ 10.21073441 321.67847023]
표준점수 구하기 !!!! 값-평균/표편
train_scaled = (train_input - mean) / std # 자동으로 해줌 = 브로드캐스팅
다시 산점도를 그려보자!
new = ([25,150]-mean/std)
plt.scatter(train_scaled[:,0],train_scaled[:,1])
plt.scatter(new[0],new[1],marker='^')
plt.show()
x,y축의 값이 -1.5~1.5로 바뀜!
다시 훈련시켜보자.
from sklearn.kneighbors import KNeighborsClassifier()
kn = KNeighborsClassifier()
kn.fit(train_scaled,train_target)
테스트 세트 또한 훈련 세트와 마찬가지로 변환해야함!!
test_scaled = (test_input-mean) / std
kn.score(test_scaled,test_target)
1.0
다시 문제의 그 데이터를 변환시켜 예측시켜보자.
new = ([25,150]-mean) / std
kn.predict(new)
1. (도미 = 1)
정답 !
그림으로 그려볼까?
distances , indexes = kn.kneighbors([new])
plt.scatter(train_scaled[:,0],train_scaled[:,1])
plt.scatter(new[0],new[1],marker = '^')
plt.scatter(train_scaled[indexes,0],train_scaled[indexes,1],marker ='D')
plt.show()
5개의 기준 데이터 모두 도미로 성공!
'머신러닝 & 딥러닝 기초 > 2장 - 데이터다루기' 카테고리의 다른 글
2-1 훈련세트와 테스트세트 (0) | 2022.12.30 |
---|