본문 바로가기
머신러닝 + 딥러닝/혼공머신

[혼공학습단 7기] WK01. 나의 첫 머신러닝&데이터 다루기 (3)

by 전전긍긍 2022. 1. 28.

👀1주차 220110 ~ 220116 공부기록

 

📍 본 포스팅은 <혼자 공부하는 머신러닝+딥러닝> 책을 바탕으로 작성함을 알립니다.

 

혼자 공부하는 머신러닝+딥러닝

혼자 해도 충분하다! 1:1 과외하듯 배우는 인공지능 자습서이 책은 수식과 이론으로 중무장한 머신러닝, 딥러닝 책에 지친 ‘독학하는 입문자’가 ‘꼭 필요한 내용을 제대로’ 학습할 수 있도

book.naver.com


 

2022.01.23 - [머신러닝 + 딥러닝/혼공머신] - [혼공학습단 7기] WK01. 나의 첫 머신러닝&데이터 다루기 (2)

이어서 (3)를 진행하겠습니다.

 

 Ch.02-2 데이터 전처리

K-NN 알고리즘 실습 (1월과 7월의 평균기온과 일강수량)

* 1월과 7월의 일강수량 중에서 측정이 되지 않은 강수량은 0으로 설정함.

그래서 일강수량은 차이가 있긴 하지만 극명한 차이를 볼 수 없음.

 

* K-NN 알고리즘이 평균기온을 14.1은 겨울로 판단하고 14.2를 여름으로 판단함. (강수량은 0으로 함)

보통 10월에 10~15도의 평균기온이 많다. 14도면 봄과 가을의 언저리이기 때문에 겨울과 여름을 이진분류 할 수 없음.

 

* 본인의 능력 부족으로 혼공머신 책처럼 예외의 데이터를 찾을 수 없었음.

ex. 예외의 데이터 → 7월의 평균기온 or 일강수량인데 알고리즘이 겨울로 판단

 

* 그래서 K-NN 알고리즘의 정확도를 파악하는 것보다 데이터 전처리를 통해 스케일을 조정하는 것에 의의를 두고 

블로그 글을 작성하겠습니다.


💦 넘파이를 이용해서 2차원 리스트 만들기

 

데이터 준비하기, 넘파이 임포트 해서 기온과 강수량을 2차원 배열로 만들기

data - column_stack() 함수를 이용해서 데이터 리스트 나란히 붙이기

target - concatenate() 함수 이용해서 타겟을 1차원 배열로 만들기

 

 

column_stack() 함수 : 전달받은 리스트를 일렬로 세운 대암 차례대로 나란히 연결 (1차원 배열을 2차원 배열로 쌓음)

concatenate() 함수 : 첫 번째 차원을 따라 배열을 연결

💦 사이킷런 함수를 사용해서 훈련 세트와 테스트 세트 나누기

 

train_test_splt() 함수 : 훈련 데이터를 훈련 세트와 테스트 세트로 나누는 함수.

  • - 여러 개의 배열을 전달할 수 있음.
  • 테스트 세트로 나눌 비율은 text_size 매개변수에서 지정할 수 있으며 기본값은 0.25(25%) 이다.
  • 나누기 전에 인덱스를 알아서 섞어줌. (이전에는 random과 shuffle을 이용해서 arange() 함수에 전달하는 방식으로 섞음)
  •  


 샘플링 편향 주의 - 비율

 

책에서는 비율이 안맞아서 샘플링 편향 발생. (본 실습에서는 1:1로 비율이 맞춰짐)

비율이 일정하지 않을 때 해결방법 : stratify() 매개변수에 타깃을 전달하면 클래스 비율에 맞게 데이터를 나눠준다.

(책과 같은 실습을 하기 위해서 한 번 더 비율을 맞춰줌)


💦 예외의 샘플로 테스트해보기 - (문제 발생)

K-NN알고리즘을 구현한 KNeighbors 클래스를 임포트하고 산점도 그려보기.

예외의 샘플은 🔺 로 표시함.

predict하였을 때, 0으로 판단하였다.

 

K-NN알고리즘 불러오고 산점도 그리기

 

이미지의 텍스트에 설명하였듯이, 시각적으로 보았을 때는 여름(1)에 더 가까운 이웃이 많아보인다.

[16, 7]은 애매한 평균기온, 일강수량이기 때문에 문제제기가 안될 수 있어서 본 실습의 결과를 예측하지 못했다.

(실습 덕분에 새로운 경험을 할 수 있다.)

 

distance, indexes는 [16, 7]과 가까운 특성의 거리와 인덱스를 구해준다.

그리고 알아보기 쉽게 초록색 마름모(🔷)로 마커 표시를 하였다.

 

가장 가까운 이웃의 거리과 인덱스 구하기

 

인덱스의 데이터와 타겟이 같다는 것을 알 수 있다.

예를 들어, 가장 첫 번쨰 있는 [23.0, 0]은 평균기온으로 보았을 때 여름이다.

그리고 그 밑에 target을 보면 가장 첫 번째 있는 타겟은 1임을 알 수 있다.

 

그리고 kneighbors() 메서드에서 반환하는 distances 배열을 출력해보면 이웃 샘플까지의 거리를 알 수 있다.

 


💦 데이터 전처리(표준 점수)로 기준 맞추기 - (문제 해결)

 

위에 과정에서 이웃 샘플까지의 거리를 구했다.

조합해서 따져보면 여름 쪽까지의 거리는 10.1139이고 겨울 쪽까지의 거리는 10.7056이다.

약 10으로 비슷하다고 할 수 있지만, 그래프 상에서는 거리 비율이 이상하다.

그 이유는 x축의 범위와 y축의 범위가 다르기 때문이다.

→ x축과 y축의 범위를 맞춰주면 된다.

(극적인 차이를 보고 싶은데 결과가 생각보다 극적이지 않아서 실망했다.)

 

* 범위를 변경해도 큰 차이가 없고, 일강수량이 원래 큰 차이가 없어서 처음부터 평균기온이 0과 1을 좌지우지 하는 고려대상임을 인지하고 있었다. 그래도 실습을 따라가기 위해 데이터 전처리를 공부해보자! 


 데이터 전처리

머신러닝 모델에 훈련 데이터를 주입하기 전에 가공하는 단계.

특히, 거리 기반 알고리즘에서 데이터를 표현하는 기준을 맞춰주기 위해서 하는 작업이다.

 

가장 널리 사용하는 전처리 방법 중 하나는 표준점수(standard score)이다.

  • 표준 점수 : 각 데이터가 원점에서 몇 표준편차만큼 떨어져 있는지
  • 표준 편차 : 분산의 제곱근으로 데이터가 분산된 정도를 나타낸다.

특성마다 값의 스케일이 다르므로 평균과 표준편차를 각 특성별로 계산하기 위해 axis를 사용한다.

axis = 0으로 지정하면 행을 따라 각 열의 통계 값을 계산한다.


💦 전처리 데이터로 모델 훈련하기

스케일이 조정 된 데이터셋으로 K-NN알고리즘 모델을 훈련한 결과이다.


💦 결과

(좌) 스케일 조정 전 (우) 스케일 조정 후
(좌) 스케일 조정 전 샘플 결과 (우) 스케일 조정 후 샘플 결과

가을, 봄의 기온을 골라서 테스트를 했기에 결과에 대한 확신은 없었다.

스케일 조정 후 다시 예측해 보았을 때, 1이 나와서 놀랐다.

내가 놀란 이유는 산점도를 시각적으로 보았을 때, 드라마틱하게 변한게 없었기 때문이다.

 

가장 가까운 샘플 5개가 스케일 전후로 달라짐

특성을 표준점수로 바꾸었기 때문에 K-NN 알고리즘이 올바르게 거리를 측정하였다.

그로 인해 가장 가까운 이웃에 변화가 생김

(전) 마름모(🔷)가 0쪽에 3개, 1쪽에 2개 있어서 예측결과가 0으로 나왔다.

(후) 마름모(🔷)가 0쪽에 2개, 1쪽에 3개 있어서 예측결과가 1로 나왔다.

 

또 신기한 점은, 가장 가까운 거리에 있는 샘플 5개의 위치가 달라졌다는 것이다. 

여기서 데이터 전처리에 대한 중요성을 깨달았다.

(대부분의 머신러닝 알고리즘은 특성의 스케일이 다르면 잘 작동하지 않는다고 한다.

다른 방식으로 한 번 더 시도해보고 싶은 마음이 있다.)


  • 맷플롭릿의 전체 마커 리스트

https://matplotlib.org/stable/api/markers_api.html

 

matplotlib.markers — Matplotlib 3.5.1 documentation

matplotlib.markers Functions to handle markers; used by the marker functionality of plot, scatter, and errorbar. All possible markers are defined here: marker symbol description "." point "," pixel "o" circle "v" triangle_down "^" triangle_up "<" triangle_

matplotlib.org