좌충우돌 개발자의 길

5강 : 데이터 전처리 본문

STUDYING/머신러닝&딥러닝

5강 : 데이터 전처리

sustronaut 2021. 7. 14. 22:25

도미? 빙어?

  • 길이가 25cm이고 무게가 150g인 도미를 빙어로 예측한다??? → 확인해보자

넘파이로 데이터 준비

fish_data = np.column_stack((fish_length, fish_weight))

  • .column_stack((fish_length, fish_weight)) : 두 배열을 나란히 세운 다음, 열로 붙여주기
    • → fish_length가 첫번째 열(세로로 첫번째)로 들어가고, fish_weight가 두번째 열로 들어감

 

  • .row_stack( ) : column_stack과 반대로 붙여줌
  • concatenate( ) : 일렬로 붙여줌

fish_target = np.concatenate((np.ones(35), np.zeros(14)))

  • np.ones(35) == [1]*35 : 1로 채워진 특정크기(35)의 배열을 만들고 싶을 때 사용
  • np.zeros(14) == [0]*14 : 0으로 채워진 특정크기의 배열 만들고 싶을 때 사용
  • np.fulls([2,3],9) : 2*3의 배열이 9로 채워짐.
  • 튜플로 나타내기 : np.ones([2,3]) 2*3의 배열이 1로 채워진다

사이킷런으로 데이터 나누기

from sklearn.model_selecton import train_test_split


train_input, test_input, train_target, test_target = train_test_split(
		fish_data, fish_target, stratify=fish_target, random_state=42)
  • from sklearn.model_selecton import train_test_split : 데이터 나눌때 사용하는 사이킷런
  • 매개변수 안에 fish_data, fish_target뿐만 아니라 더 많은 배열을 넣어도 괜찮음
  • stratify : 훈련세트가 작거나 특정 클래스 대비 상대적으로 작으면 사용하는 것으로, fish_target을 넣었을 때, 그 타겟을 골고루 섞이게 도와줌
  • random_state는 실전에서 사용x(교재랑 같은 결과가 나오기 위해서 사용함)

→ 즉, 전달하는 배열을 각각 두개씩 쪼개서 나타냄 ( 3개 배열 전달하면 6개로 쪼개져서 나옴 )

 


수상한 도미

  • 이전 코드로 결과값을 찾았을 때

→ 100%의 정확도가 나왔지만 수상한 도미는 빙어라고 예측한 결과가 나와버림

# 25cm, 150g의 도미 데이터를 넣어 이웃 5개와 비교해 거리와 인덱스를 반환함
distances, indexes = kn.kneighbors([[25, 150]]

plt.scatter(train_input[:,0, train_input[:,1])
# 집어넣은 특정 데이터를 그래프 상 세모로 표시하겠다.
plt.scatter(25, 150, marker='^')
# 배열 인덱싱을 통해 나눈 후, 이웃 5개를 마름모로 나타내겠다.
plt.scatter(trian_input[indexes, 0, train_input[indexex, 1], marker='D')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

→ 세로가 0~1000이고 가로가 0~40까지이기에 빙어에 가깝다고 결과가 나와버림

→ 즉, y축의 스케일과 x축의 스케일이 맞지 않아 일어나게 된 현상

 

기준을 맞춰라

  • xlim 으로 축의 범위를 조절하자
plt.scatter(train_input[:,0, train_input[:,1])
plt.scatter(25, 150, marker='^')
plt.scatter(trian_input[indexes, 0, train_input[indexex, 1], marker='D')

# 축의 범위를 수동으로 조절할 수 있는 함수
plt.xlim((0,1000))
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

→ 0에서 1000으로 x축, y축 같아짐

그래프 분석 : kneighbor는 스케일의 영향을 많이 받기 때문에, 스케일이 큰쪽으로 끌려가게 되어 있음. 그래서 이 생선은 무게쪽으로 쏠려서 결과가 나온거다.

 

표준 점수로 바꾸기

  • 표준점수(Z점수) = (특성-평균)/표준편차
  • 길이와 무게 표준점수를 각각 구해야 한다
# mean : 평균, std : 표준편차, train_input : 변환하고자 하는 배열, axis : 축을 0으로 설정
mean = np.mean(train_input, axis=0)
std = np.std(train_input, axis=0)

print(mean, std)
[27.2972222 454.0972222] [9.98244256 323.29893931]

# (36, 2) 배열에서 (1, 2) 배열 빼기 -> 각각 빼줘서 (36, 2) 배열 유지가능 (그림 참고)
train_scaled = (trian_input - mean) /std
  • axis = 1 로 하면 가로(행)로 한줄한줄로 평균이 구해지기 때문에 axis = 0(각 특성별로 구함 == 열)으로 해야 세로로 한줄 다 평균과 표편 구해짐.

 

  • 넘파이 브로드캐스팅

 

수상한 도미 다시 표시하기

  • 훈련 세트의 평균과 표준편차로 테스트 세트를 변환해야함

→ 0을 중심으로 데이터가 고르게 퍼져있다는 것을 축을 보면 알 수 있음.

 

전처리 데이터에서 모델 훈련

# 각 매개 변수는 변환된 것이다.
kn.fit(train_scaled, trian_target)

# 훈련세트의 데이터로 test 변환하기
test_scaled = (test_input - mean) / std
# target data는 스케일 조정하는 대상이 아니라서 그냥 그대로 감
kn.score(test_scaled, test_target) #1.0

print(kn.predict([new])) #1 : 도미라고 출력됨.

# 그래프 그려보기 (그림 참고)
distances, indexes = kn.kneighbors([[new]] # new와 가장 가까운 애들 5가지 뽑아서 보여줌

plt.scatter(train_input[:,0, train_input[:,1])
plt.scatter(25, 150, marker='^')
plt.scatter(trian_input[indexes, 0, train_input[indexex, 1], marker='D')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

→ 도미라는 결과값이 나옴

 

전처리 : 입력 데이터를 머신러닝이 사용할 수 있도록 적절히 가공하는 것

'STUDYING > 머신러닝&딥러닝' 카테고리의 다른 글

7강 : 선형회귀  (0) 2021.07.18
6강 : k-최근접 이웃 회귀  (0) 2021.07.14
4강 : 훈련 세트와 테스트 세트  (0) 2021.07.14
3강 : 마켓과 머신러닝  (0) 2021.07.14
2강 : colab 사용하기  (0) 2021.07.14