본문 바로가기
데이터 분석/혼자 공부하는 머신러닝 + 딥러닝

1주차_나의 첫 머신러닝 및 데이터 다루기

by yEvery 2025. 7. 5.

기본숙제(필수): 코랩 실습 화면 캡처하기

 

1-3

도미데이터를 입력하고, 산점도로 그려보았다.

빙어데이터도 입력한 뒤, 빙어데이터와 도미데이터를 산점도로 나타내었다. 도미가 파란색, 빙어가 주황색이다.

도미의 길이와 빙어의 길이 리스트를 length에 합쳐서 저장, 무게도 마찬가지로.

zip()을 사용하여 fish_data에 length와 weight가 열로 각각에 해당하는 데이터가 행으로 저장된다.

fish_target 데이터로 맞춰야 하는 도미를 1로, 빙어를 0으로 저장한다.

 사이킷런의 k최근접 이웃 알고리즘을 임포트한다. kn에 모델을 생성하고 fit()을 통해 학습시킨다.

score()를 통해 정확도를 알 수 있다. 1은 모든 것을 맞췄다는 것을 의미한다.

길이가 30이고 무게가 600인 데이터는 세모로 표시하도록 산점도를 그려보았다.

predict()로 맞출 데이터를 입력한다. 1이 나왔으므로 도미로 판단한 것을 알 수 있다.

kn._fit_X는 훈련 데이터를, kn._y는 타켓 데이터를 나타낸다. 

몇 개의 이웃을 참고할 지 n_neighbors 매개변수를 통해 직접 지정할 수도 있다.

49로 지정했을 때 49개 중에 35개를 맞추는 것을 알 수 있다. 


2-1

슬라이싱을 통해 49개 중에 35개를 훈련 데이터로, 나머지 14개를 테스트 데이터로 분리해서 진행하였다.

훈련데이터로 학습시키고, 테스트 데이터로 평가를 해봤는데 0으로 하나도 맞추지 못한 것을 알 수 있었다.

이번에는 파이썬 리스트가 아닌 넘파이로 진행해보았다. 지금은 그렇게 데이터의 양이 많지 않지만, 많은 양의 데이터를 다룰 때는 넘파이가 훨씬 효과적이다. 넘파이를 임포트해서 np로 사용한다. shape을 통해 몇 행 몇 열인지 알 수 있다.

np.random.seed를 통해 랜덤하게 사용하지만 seed를 통해 항상 같은 결과가 나오도록 할 수 있다.

arange를 사용하면 0부터 전달한 숫자 - 1 까지 1씩 증가하는 배열을 만들 수 있다. 이것을 인덱스로 전달하고 shuffle을 통해 순서를 무작위로 섞는다. 아까 진행한 학습에서 처음부터 35개까지의 데이터를 훈련 데이터로 전달하였었는데, 이러면 도미의 데이터만이 전달되어 빙어만이 있는 테스트 데이터로 평가를 했을 때, 0이 나올 수 밖에 없다. (클래스 불균형 문제) 훈련을 비슷한 비율의 데이터들로 섞어줘야 테스트 할 때 맞출 수 있기 때문에 이와 같은 과정을 진행한다. 산점도를 보면 훈련데이터와 테스트 데이터에 빙어와 도미가 적절히 섞여 있는 것을 확인할 수 있다.

이렇게 무작위로 섞고, 학습을 진행한 뒤 테스트 데이터로 평가해보면 정확히 다 맞춘 것을 확인할 수 있다!


2-2

넘파이의 column_stack()을 사용하면 전달하는 값들을 열로 쌓아준다.

넘파의 ones()는 전달하는 크기만큼 1로 채워진 배열을 만들어준다. zeros()는 0으로 채워진 배열을 만든다.

concatenate는 column_stack과 달리 그대로 전달하는 값들을 이어준다.

사이킷런의 train_test_split 라이브러리를 통해 훈련 데이터와 테스트 데이터를 편리하게 나눌 수 있다. 

여기서 random_state가 앞서 진행했던 seed와 비슷한 역할을 한다.

staratify 매개변수를 통해 클래스 불균형이 생기지 않게 타겟 데이터를 참고하여 적절히 섞어줄 수 있다.

훈련 데이터와 테스트 데이터를 출력해보면 적절히 섞인 것을 확인할 수 있다. 

여기서는 워낙 빙어의 데이터가 도미 보다 적기 때문에 이 정도면 적절하게 섞인 것으로 볼 수 있다.

학습 후 평가해보면 모두 맞춘 것을 알 수 있다.

하지만, 길이가 25이고 무게가 150인 것은 도미로 판단해야 하는데 빙어로 예측한 것을 확인할 수 있다.

산점도를 그려 확인해봐도 도미에 해당해야 하는 것으로 보인다. (주황색 세모가 해당 데이터)

kneighbors를 통해 전달한 데이터의 참고하는 이웃들의 알 수 있다. 거리와 인덱스를 전달받고, 이를 산점도로 그려보면 위와 같이 빙어쪽에서 4개, 도미쪽에서 1개를 참고하는 것을 확인할 수 있다. (초록색 마름모)

원래 이 k최근접 이웃 알고리즘은 5개를 기본값으로 참고한다.

거리를 따로 확인해보면 뭔가 이상한 것을 알 수 있다.

거리가 92인 것은 도미쪽 데이터이고 나머지는 빙어쪽 데이터인데, 거리가  그래프에서 보는 것과 다른 것을 알 수 있다.

길이의 단위와 무게의 단위가 달라 둘의 눈금, 스케일이 달라 이러한 현상이 발생한 것을 알 수 있다.

 

 길이인 x축을 y축과 맞춰서 산점도를 그려보면 위와 같다.

이러면 거의 일렬로 나타나기 때문에 적절한 반영이 어렵다.

이럴 때 표준점수를 활용한다. 이러한 것을 데이터 전처리라고 할 수 있다.

넘파이의 mean()과 std()를 통해 평균과 표준편차를 구해주고, 이를 훈련 데이터에 적용하여 표준화 해준다.

왼쪽은 새로운 데이터에 표준화를 하지 않은 산점도이고 오른쪽은 새로운 데이터도 표준화를 적용한 산점도이다.

동일하게 표준화를 적용하니 이전과 모습이 다르지 않게 산점도가 그려지는 것을 확인할 수 있다.

이제 전처리까지 한 데이터를 학습시켰다. 테스트 데이터 또한, 훈련 데이터에 적용한 전처리를 동일하게 해주고 평가를 해야 한다.

score() 결과 이전에는 빙어로 예측하던 모델이 이제는 도미로 맞게 예측하는 것을 확인할 수 있었다. 어떤 이웃들을 참고했는지 앞서 진행한 것과 동일하게 알아보면, 오른쪽 산점도 그래프에서 확인할 수 있듯이 도미 쪽 데이터를 올바르게 참고한 것을 알 수 있다.


추가 숙제(선택): Ch.02(02-1) 확인문제(p.90) 풀고, 설명하기

답: 1번

정답을 알고 있을 때는 지도 학습을 할 수 있다. 정답을 알고 있지 않을 때는 비지도 학습을 할 수 있다.

 답: 4번

훈련 세트나 테스트 세트가 잘못 만들어져 전체 데이터를 대표하지 못하는 현상은 샘플링 편향이다.

답: 2번

행은 각각의 샘플들로, 특성은 열로 구성되어 있다고 기대한다.

답: 3번

두 번째 원소부터 다섯 번째 원소까지는 인덱스가 1부터 4이다. 슬라이싱 할 때 마지막 숫자에 해당하는 원소는 포함이 안되기 때문에 1부터 4+1인 5를  사용해야 한다.