한빛미디어 도서 <혼자 공부하는 머신러닝+딥러닝>의 전개를 따른 내용이다.
이번에 다룰 내용은 "데이터 전처리"이다.
이전까지는 그냥 날것의 데이터로 훈련시키고 그랬는데, 이 날것의 데이터에는 요상한 데이터가 숨어있을 수도 있다. 위험!
그래서 이번에는 전처리한 데이터를 사용해보자.
챕터2, 데이터 다루기 | 데이터 전처리
* 머신러닝 알고리즘에 주입할 데이터를 준비하는 방법을 배운다.
* 데이터 형태가 알고리즘에 미치는 영향을 이해한다.
데이터를 전처리하기 전에,
이전과는 다른 새로운 방법으로 데이터를 준비할 것이다.
- 전체 데이터 준비하기 : numpy의 column_stack() 이용
- train/test set 준비하기 : sklearn의 train_test_split() 이용
다시말해서, 이글의 핵심인
전처리 하는 내용은 여기부터(클릭) 나온다.
전처리 내용을 미리 요약정리한다면,
특성값들을 좌표계에 나타낼 때 단위가 달라서 거리기반 알고리즘을 그냥 적용하면 안 된다는 내용이다.
표준화하여 데이터를 전처리하고 나서 거리기반 알고리즘을 적용해야 한다는 내용이다.
# 데이터 준비하기
전달한 두개의 리스트를 각각의 열로 설정하고 싶다면?
다시 말해, length리스트랑 weight리스트를 각 column으로 붙여서 새로운 리스트를 만들겠다는 것.
numpy의 column_stack()이 그러한 기능을 수행한다.
이때 전달한 length, weight라는 파이썬 리스트는 튜플로 전달한다. 튜플은 리스트와 비슷하지만, 수정할 수 없다.
이번에는 0, 1로 이루어진 target data를 준비할 것이다.
이전에는 fish_target = [1] * 35 + [0] * 14 이렇게 손수 만들었지만,
이번에는 np.ones(), np.zeros() 함수를 사용해보자.
자 이렇게 data와 그것에 대한 target data를 준비해두었으니,
이제는 train set과 test set을 준비해보자.
# train set, test set 준비하기 "이번에는 사이킷런으로!"
이전에는 index를 random.shuffle을 통해 랜덤으로 섞어 활용했었다.
이번에는, 머신러닝 라이브러리인 사이킷런이 제공하는 도구인 train_test_split() 함수를 사용할 것이다.
train/test set을 만들어준다.
알아서 섞어주고 알아서 분할해준다.
사이킷런의 도움(train_set_split())을 받아서 train/test set으로 분할하긴 했는데,
혹시 데이터가 편향되진 않았을까?
전체 생선 set에서는 도미25마리:빙어14마리 => 2.5 : 1 비율이었다.
test_target도 이제는 2.25 : 1로 좀 비슷해졌다.
이정도면 괜찮다고 판단하겠다.
자 이렇게, 사이킷런의 train_test_split()의 도움을 받아 훈련데이터와 테스트데이터를 적절히 나눴으며,
이때 stratify 속성을 통해 샘플링 편향을 피할 수 있었다.
# 데이터 전처리
우리가 하고 있는 실습으로 예를 들어보자.
k-최근접이웃 알고리즘은 주변 샘플 중 다수인 클래스를 예측결과로 내놓는다.
"다수결"이 핵심이자, 예측미스를 내놓을 수 있는 부분이다.
예를 들어보자.
빙어는 가볍고 작다.
도미는 비교적 무겁고 크다.
데이터상으로 25cm, 150 weight의 물고기는 도미로 분류되어야 한다.
그런데 25cm, 150 weight는..
k-최근접이웃 알고리즘에 의하면 빙어로 분류해버린다.
위 산점도를 보면, 최근접이웃 5개 데이터 중 1개가 도미고, 4개가 빙어 클래스이게 된다.
(시각적으로는 왜 빙어가 '최근접'이웃이냐! 이상할 수 있다. 그 이유는 x축, y축의 스케일 때문이다. y축 기준으로 가까워보여도, 스케일이 상당히 축소되어있기에 사실은 먼 거리이다. y축을 보면 200단위 눈금인데 x축은 5단위 눈금임을 유의하기!)
그래서 분명 도미인데도 빙어로 예측결과를 내놓는 것이다.
왜 예측결과가 빙어일까?
잠시 이러한 이웃 데이터를 시각적으로 확인해보자.
우리가 k-최근접이웃 알고리즘을 사용할 때 계속 사용한
KNeighborsClassifier클래스는 kneighbors() 메서드를 통해서 '이웃에 대한 것'을 반환해준다.
이웃까지의 거리, 그리고 이웃 인덱스를 반환해준다.
참고 : 최근접이웃을 시각적으로 확인할 때, x축과 y축의 스케일이 다르기 때문에 최근접이웃처럼 보이지 않을 수 있다. 그럴 때는 x축과 y축의 스케일을 동일하게 설정하여 시각적으로 확인해볼 수 있다.
xlim(), ylim()으로 스케일을 설정한다.
이제 최근접이웃이 더 납득가능하게 보일 것이다.
아하 25length, 150weight의 최근접 이웃은 빙어가 맞구나...
웅? 아무리 봐도 수치적으로 도미인데.. 왜 최근접 이웃이 빙어라고 하지?
# 바로 여기서 거리판단시 주의점이 보인다
거리 기반의 알고리즘일 때, 샘플 간의 거리는 x축과 y축의 설정에 따라 영향을 받는다.
지금 이 데이터에서 length와 weight가 동등한 단위라는 것을 보장할 수 없다!!!*****
그래서 "나는 거리를 동등한 기준으로 판단하겠어!"랍시고,
저렇게 x축 y축을 length, weight인 상태로 "동일한 눈금 간격"으로 맞춰 본다고 해도,
두 단위는 다른 단위기에, 여기서 한 점과 다른 데이터들간의 거리를 따지는 건 잘못된 것이다.
그래서 특성값을 일정한 기준으로 맞춰주는 전처리가 필요하다.*****
이때, 일정한 기준으로는 '표준점수'를 많이 사용한다.
표준점수(z점수) : 각 특성값이 평균(or 원점)에서 표준편차의 몇 배만큼 떨어져 있는지를 나타낸다.
데이터들이 평균에서 표준편차의 몇 배만큼 떨어져 있는지를 보려면,
'평균'과 '표준편차'를 알면 된다.
그럼 표준점수를 구해보자.
이걸 산점도로 그려보고 축의 값을 보자.
표준화된 데이터들임을 알 수 있다.
그럼 이제 여기에다가, 점찍어보고 싶은 생선 샘플 25length, 150weight를 표시해보자.
유의할 점은 이 샘플 [25, 150]은 "표준화되지 않은 샘플"이라는 것이다!
우리는 모든 데이터를 표준화하여 산점도를 그렸는데, [25, 150] 샘플은 단위가 맞지 않아서 그냥 그대로 점을 찍으면 아래와 같이 동떨어질 수밖에 없다.
그래서 이를 반드시 신경써야 한다.
샘플도 표준화하여 점찍어보면, 아래와 같이 제대로 된 산점도를 얻을 수 있다.
# 이렇게 전처리한 데이터를 통해 모델을 훈련하자
우리가 사용하는 알고리즘은 k-최근접이웃 알고리즘인데, 이는 거리 기반 알고리즘이라고 했다.
표준화를 통해 전처리하여 이제서야 거리를 객관적으로 바라볼 수 있게 되었으니,
이렇게 전처리된 데이터들로 거리기반 알고리즘을 적용하면 성공적이겠다.
계속 그래왔듯이 fit()으로 학습시키고 score()로 테스트해보자.
이때 짚고 넘어가야 할 것!
test set을 표준화할 때에, train set에서의 mean과 std로 표준화해야 한다.
훈련 자체를 train data의 mean, std로 표준화한 데이터를 통해 했기 때문에, test data에도 마찬가지로 그렇게 적용해야 한다.
우리의 도미/빙어 판단 머신러닝 모델의 정확도는 1이라고 한다. 굿!!!
그럼 아까 그 문제의 데이터 [25, 150]을 predict 해보자.
이제 드디어 완성이 되었다!
마지막으로 저 new생선의 최근접이웃을 표시한 산점도를 확인해보자
아까 모든 데이터들을 표준화하기 전에는 x축과 y축의 거리개념이 동등하지 않아서, 결과적으로 new생선과 데이터들간 거리는 잘못된 값이었다. 그래서 내 이웃은 분명 도미인데 빙어라는 '요상한 이웃'이 도출되었다.
나는 도미라구 ㅠㅅ ㅠ~~~
그런데 이제 표준화하여 전처리했으니 나는 도미다!! 라고 자랑스럽게 보여줄 수 있다.
# 이번 내용 정리, 데이터 전처리하기 (표준화하기)
1. 거리기반 알고리즘을 사용하기 위해서는 좌표계를 동등한 조건으로 맞출 필요가 있었다.
2. 그래서 특성 값들을 표준점수로 변환하였다. (특성의 스케일을 조정)
3. 이렇게 train/test set을 표준화해서 거리기반 알고리즘을 적용한 머신러닝 모델에 fit()하고 score() 하였더니, 이번에는 거리를 객관적으로 바라볼 수 있었기에 제대로 된 결과를 도출하였다.
* 유의! test data를 표준점수로 변환할 때, 당연히 train data의 mean과 std를 사용해야 한다.
4. 산점도 또한 표준화된 데이터들로 그려보니, 시각적으로도 객관적인 거리를 확인가능했다.
이전 포스팅:
2022.01.12 - [데이터분석과 머신러닝] - 머신러닝 입문 | 지도학습, train set과 test set
'데이터분석과 머신러닝' 카테고리의 다른 글
머신러닝 | 회귀 모델 (+ knr) | 과소적합, 과대적합 (0) | 2022.01.21 |
---|---|
혼공단7기 1주차 미션인증 (0) | 2022.01.13 |
머신러닝 입문 | 지도학습, train set과 test set (0) | 2022.01.12 |
머신러닝 입문 | 이진분류해보기 (k-Nearest Neighbors algorithm 사용) (0) | 2022.01.10 |
혼자 공부하는 머신러닝+딥러닝 | 도서 추천도 하고 내 얘기도 겸사겸사.. (0) | 2022.01.10 |