Ch02. 데이터 다루기

Hyemin Seo·2024년 10월 4일
1

혼공머신

목록 보기
2/5
post-thumbnail

02-1 데이터 다루기

지도학습과 비지도 학습

  • 지도학습 supervised learning
    정답을 준다
  • 비지도학습 unsupervised learning
    정답을 안준다
  • 강화학습
    보상을 이용한다

그럼 QUIZ. k-최근접 이웃 알고리즘은?
바로 지도 학습!

훈련 세트와 테스트 세트

훈련 세트 : 훈련에 이용한 데이터
테스트 세트 : 테스트에 이용한 데이터
샘플 : 하나의 생선 데이터

훈련 세트로만 훈련과 테스트를 하게 된다면 정확도 100%인 문제가 발생한다.
따라서 훈련 세트와 테스트 세트를 별개로 구분짓는게 좋다.

샘플링 편향 sampling bias

그런데 구분짓는 행위를 뭐라고 할까? 바로 샘플링이다.
샘플링 : 샘플을 뽑는 행위 -> 훈련 세트와 테스트 세트에 적절히 분배하기 위함
샘플링 편향 : 적절히 분배가 안된 상태
샘플링 편향이 나지 않게 뽑으려면 어떻게 하지?

넘파이

파이썬의 배열 라이브러리
샘플링 편향이 나지 않게 넘파이 라이브러리를 사용해보자.

  1. 인덱스 순서를 1,2,3,.. 이 아니라 2, 49, 12, ... 가 되게 섞는다.
index = np.arange(49) # 0에서 48까지 1씩 증가하는 인덱스 만들기
np.random.shuffle(index) # 인덱스 섞기
  1. 넘파이의 배열 인덱싱 사용한다.
    배열 인덱싱 : 1개의 인덱스가 아닌 여러 개의 인덱스로 한 번에 여러 개의 원소 선택 가능
input_arr[1,3] # 예시. 두번째 네번째 샘플 선택
  1. 배열 인덱싱의 인덱스를 넘파이 배열로 준다.
train_input = 똑같은
train_target = 방식
test_input = input_arr[index[35:]] # 여기서 index[35:]는 넘파이 배열
test_target = target_arr[index[35:]]

이렇게 하면 정확도 100프로 모델이 된다.

02-2 데이터 전처리

넘파이로 데이터 준비하기

이제 넘파이를 배웠으니 샘플을 만들 때 아래와 같이 만들지 않는다.

[[l,r] for l,r in zip(fish_length, fish_weight)

바로 np.column_stack( 안에는 튜플 )로 만든다.
튜플이란? 수정할 수 없는 리스트

fish_data = np.column_stack((fish,length, fish_weight))

또한, 넘파이를 배운 여러분은 타깃 데이터도 더 쉽게 만들 수 있다.

fish_target = np.concatenate((np.ones(35),np.zeros(14)) # 사슬로 잇다

사이킷런으로 훈련 세트와 테스트 세트 나누기

그리고 마지막으로, 넘파이를 배웠기 때문에! 여러분은 훈련 세트와 테스트 세트를 나눌 때 인덱스 셔플 할 필요가 없다.

from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split( fish_data, fish_target )

이 함수는 기본적으로 25퍼센트를 테스트 세트로 떼어 낸다.
그런데 무작위로 데이터를 나눴을 때 샘플링 편향이 일어날 수 있다. 다시 말해 훈련 세트에서의 도미와 빙어 비율보다 테스트 세트에서의 도미와 빙어 비율이 더 높거나 낮을 수 있다는 뜻이다. 이것은 특히 훈련 데이터가 적거나, 특정 클래스의 샘플 개수가 적을 때 특히 그렇다.
해결법 : stratify = fish_target 매개변수 추가! 그렇게 하면 비율 똑같이 들어간다.

train_input, test_input, train_target, test_target = train_test_split( fish_data, fish_target, stratify=fish_target )

수상한 도미 한 마리

이렇게 하고 도미인 데이터 하나 predict 해보자. 어라? 도미가 아니라 빙어라고 주장하네.
이웃들을 다른 점으로 표현해 봅시다.

distances, indexes = kn.kneighbors([[25,150]])
plt.scatter(train_input[indexes, 0], train_input[indexes,1], marker='D') ????

이상하네. 표현해보면 빙어가 이웃 중에 4개입니다. 근데 점 자체는 도미랑 더 가까워 보여요.
무슨 일일까요?

기준을 맞춰라

x,y의 거리 비율이 안 맞아요. == 두 특성의 스케일이 다르다.
해결법-1.

plt.xlim((0,1000)) # x 범위를 y 범위와 동일하게 조정해준다.

로 해볼까요? 그럼 너무 일직선 처럼 보여요 ㅠㅠ.

해결법-2. 표준점수
표준점수는 값에서 평균을 빼고 표준편차를 나누어 주면 된다.

mean = np.mean(train_input, axis=0)
std = np.std(train_input, axis=0)
train_scaled = (train_input -mean)/std

브로드캐스팅 : 모든 행에 있는 데이터를 표준점수 계산해주는 기능

test_scaled = (test_input -mean)/std

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

맞추고 싶은 데이터도 표준점수로 만들고, 훈련 세트, 테스트 세트도 표준점수로 만들어서 fit해주면 완성이다.

완성!

profile
친해져요

0개의 댓글