그럼 QUIZ. k-최근접 이웃 알고리즘은?
바로 지도 학습!
훈련 세트 : 훈련에 이용한 데이터
테스트 세트 : 테스트에 이용한 데이터
샘플 : 하나의 생선 데이터
훈련 세트로만 훈련과 테스트를 하게 된다면 정확도 100%인 문제가 발생한다.
따라서 훈련 세트와 테스트 세트를 별개로 구분짓는게 좋다.
그런데 구분짓는 행위를 뭐라고 할까? 바로 샘플링이다.
샘플링 : 샘플을 뽑는 행위 -> 훈련 세트와 테스트 세트에 적절히 분배하기 위함
샘플링 편향 : 적절히 분배가 안된 상태
샘플링 편향이 나지 않게 뽑으려면 어떻게 하지?
파이썬의 배열 라이브러리
샘플링 편향이 나지 않게 넘파이 라이브러리를 사용해보자.
index = np.arange(49) # 0에서 48까지 1씩 증가하는 인덱스 만들기
np.random.shuffle(index) # 인덱스 섞기
input_arr[1,3] # 예시. 두번째 네번째 샘플 선택
train_input = 똑같은
train_target = 방식
test_input = input_arr[index[35:]] # 여기서 index[35:]는 넘파이 배열
test_target = target_arr[index[35:]]
이렇게 하면 정확도 100프로 모델이 된다.
이제 넘파이를 배웠으니 샘플을 만들 때 아래와 같이 만들지 않는다.
[[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해주면 완성이다.
완성!