[머신러닝] 지도 학습과 샘플링 편향

지도 학습과 샘플링 편향


지도 학습이란?

지도 학습은 입력 데이터와 타깃 데이터를 전달하여 모델을 훈련한 후 새로운 데이터를 예측하는데 활용하는 학습이다.
타깃 데이터는 입력 데이터에 대한 정답이다. 예를 들어 입력 데이터가 포도라면 타깃 데이터는 grapes, 바나나라면 banana 라고 데이터에 대한 명시적인 정답을 정해 주는 거다. 모델을 훈련 시키고 새로운 데이터가 나타나 어떤 데이터인지 예측 할 때 타깃 데이터를 기준으로 분류한다.




위에 그림으로 예시 들어보자.
1. Input과 Annotations가 각각 입력 데이터와 타깃 데이터다.
즉 포도 그림들은 입력 데이터이며 정답으로 사용될 타깃 데이터는 These are grapes라는 문장이다. 입력 데이터와 타깃 데이터로 Model(모델)을 훈련 시킨다.

2. Model을 훈련 시킨 후 새로운 데이터를 predition(예측)하면 포도 그림 = grapes 이므로 새로운 데이터는 it's Grapes 라고 예측 할 수 있다.

지도 학습은 훈련한 모델 기반으로 새로운 데이터가 나타났을 때 어떤 데이터로 분류 되는지 예측 하는데 사용된다.
대표적인 지도 학습 알고리즘으로는 K-최근접 이웃이 있다.


지도 학습, 비지도 학습, 강화 학습의 차이점을 보려면 아래 링크에서 보면 된다.




샘플링 편향이란?

머신러닝을 만들때 주의해야 할 점이 몇가지 있다. 그중 하나가 샘플링 편향이다.
샘플링 편향은 데이터 수집 과정에서 무작위로 샘플을 추출하지 않아서 발생하는 문제를 말한다.
예를 들어 남자 10명, 여자 10명의 설문 조사 의견 중 10개만 반영한다고 치자.
만약 10개 모두 남자의 의견만 반영한다면 여자의 의견은 하나도 반영되지 않는다. 이 처럼 불균형한 데이터 셋이 20명의 집단을 대표 할 수 없는 것을 샘플링 편향이라고 부른다.
샘플링 편향을 방지 하기 위해서 20명의 샘플을 무작위로 셔플하여 10개의 의견을 뽑는다. 그렇게 되면 최대한 균형 있는 데이터 수집이 가능하게 된다.
아래 예제에서 샘플링 편향방지 하는 방법에 대해 알아보자.



데이터 준비하기

우선 지도 학습 중 하나인 K-최근접 이웃 알고리즘을 사용하여 머신러닝을 만들어야 하므로 k-최근접 이웃 알고리즘을 알고 있어야한다. K-최근접 이웃 알고리즘을 처음 본다면 아래 링크에서 공부하고 이 게시물을 보면 된다.


우선 데이터를 준비하자.
어린이 10명 어른 5명의  height와 weight의 특성이 있는 총 15개의 샘플을 만들었다.

#데이터 준비하가ㅣ -----------------------------------------
child_height = [120,122,124,128,130,132,134,136,138,140] #어린이 리스트
child_weight = [45,47,48,40,50,45,47,48,40,50]

adult_height = [170,175,180,185,190] #어른 리스트
adult_weight = [300,350,300,400,450]

height = child_height + adult_height #리스트 합치기
weight = child_weight + adult_weight #리스트 합치기

#, 몸무게 정보 데이터 만들기(2차원 리스트 만들기)
person_data = [[h,w] for h, w in zip(height, weight)]

#정답 데이터 만들기/ 어린이는 0 어른은 1
person_target = [0] * 10 + [1] * 5



샘플 무작위로 섞기

15개의 샘플 중 10개는 훈련 세트, 5개는 테스트 세트로 사용 할거다.
만약 순서대로 어린이 10명을 훈련세트, 어른 5명을 테스트 세트로 사용하면 사이킷 런의 scroe 메서드를 사용해 모델을 평가하면 당연히 0.0의 정확도가 나올거다.
그러므로 15개 샘플을 훈련 세트, 테스트 세트로 나누기 전에 한번 무작위로 섞을 거다.



1. 샘플을 섞으려면 파이썬에서 제공하는 numpy 패키지를 사용해야 한다. import 해주자.
import numpy as np


2. person_data, person_target 두 개의 리스트를 numpy 배열로 넘겨주자.
input_arr = np.array(person_data)
target_arr = np.array(person_target)



3. 리스트에서 넘긴 배열을 한번 출력 해보자. 데이터가 제대로 넘어갔다.
print(input_arr)
print(target_arr)
결과 : 
[[120  45]    #input_arr
 [122  47]
 [124  48]
 [128  40]
 [130  50]
 [132  45]
 [134  47]
 [136  48]
 [138  40]
 [140  50]
 [170 300]
 [175 350]
 [180 300]
 [185 400]
 [190 450]]
[0 0 0 0 0 0 0 0 0 0 1 1 1 1 1]    #target_arr




4. 이제 샘플을 섞어야 한다. 이때 input_arr와 target_arr가 한번에 섞어야 한다.
우선 무작위 인덱스를 만들자. arrange 메서드는 0 ~ 14 까지 배열을 만든다.
shuffle 메서드는 주어진 배열을 무작위로 섞는다.
한번 출력해 보면 무작위로 숫자가 섞인다.
index = np.arange(15) #샘플 15개 니까
np.random.shuffle(index) #숫자 섞기

print(index)
결과 : [ 4 11  1 13 12 10  0  8  9  2  7  6 14  3  5]


5. 이제 15개 샘플을 훈련 세트와  테스트 세트로 무작위로 나누어 보자.
훈련 세트를 만들어보자. 넘파이 배열 슬라이싱을 사용하여 1 ~ 10 까지 훈련 세트로 만들자.
index의 무작위 숫자로 input_arr와 target_arr의 원소를 train_input, train_target에 담는다.
train_input = input_arr[index[:10]]
train_target = target_arr[index[:10]]


6. 테스트 세트를 만들자. 이러면 K-최근접 이웃 모델을 훈련 시킬 훈련 세트테스트 세트는 완성되었다.
#테스트 세트 만들기
test_input = input_arr[index[10:]]
test_target = target_arr[index[10:]]



7. 산점도를  그려보면 훈련 세트 테스트 세트가 아주 잘 섞인 것을 확인 할 수 있다.
파랑 = 훈련 세트, 주황 = 테스트 세트
import matplotlib.pyplot as plt #그래프 그리는 패키지 import

plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(test_input[:,0], test_input[:,1])

plt.xlabel('height')
plt.ylabel('weight')
plt.show()
결과 : 





K-최근접 이웃 모델 훈련하고 평가하기

모델을 평가해보면 1.0으로 100% 정확도로 모든 데이터를 맞춘다.

내 예제는 샘플이 적어서 0.8 ~ 1.0 오락가락한다.
from sklearn.neighbors import KNeighborsClassifier #사이킷런 Kneighclass import

kn = KNeighborsClassifier()
kn.fit(train_input, train_target) #훈련 시키기
a = kn.score(train_input, train_target) #모델 평가하기
print(a)
결과 : 1.0



데이터 예측하기

test_input을 predict 하고
실제로 test_taget을 출력 해보면 일치하는 것을 알 수 있다.
b = kn.predict(test_input)
print(b)
print(test_target)
결과 : 
[1 0 0 1 0]
[1 0 0 1 0]



전체 소스 코드

이번에 사용한 예제의 전체 소스 코드다.
import numpy as np


#데이터 준비하가ㅣ -----------------------------------------
child_height = [120,122,124,128,130,132,134,136,138,140] #어린이 리스트
child_weight = [45,47,48,40,50,45,47,48,40,50]

adult_height = [170,175,180,185,190] #어른 리스트
adult_weight = [300,350,300,400,450]

height = child_height + adult_height #리스트 합치기
weight = child_weight + adult_weight #리스트 합치기

#, 몸무게 정보 데이터 만들기(2차원 리스트 만들기)
person_data = [[h,w] for h, w in zip(height, weight)]

#정답 데이터 만들기/ 어린이는 0 어른은 1
person_target = [0] * 10 + [1] * 5

input_arr = np.array(person_data)
target_arr = np.array(person_target)

print(input_arr)
print(target_arr)

index = np.arange(15) #샘플 15개 니까
np.random.shuffle(index) #숫자 섞기

print(index)

#훈련 세트 만들기
train_input = input_arr[index[:10]]
train_target = target_arr[index[:10]]

#테스트 세트 만들기
test_input = input_arr[index[10:]]
test_target = target_arr[index[10:]]


#그래프 그리기 -----------------------------------------
# import matplotlib.pyplot as plt #그래프 그리는 패키지 import
#
# plt.scatter(train_input[:,0], train_input[:,1])
# plt.scatter(test_input[:,0], test_input[:,1])
#
# plt.xlabel('height')
# plt.ylabel('weight')
# plt.show()
#
#모델 평가하기 -----------------------------------------
from sklearn.neighbors import KNeighborsClassifier #사이킷런 Kneighclass import

kn = KNeighborsClassifier()
kn.fit(train_input, train_target) #훈련 시키기
a = kn.score(train_input, train_target) #모델 평가하기
print(a)

b = kn.predict(test_input)
print(b)
print(test_target)



참조


혼자 공부하는 머신러닝 + 딥러닝(깃 허브) : https://github.com/rickiepark/hg-mldl




댓글

이 블로그의 인기 게시물

[Arduino] 아두이노 초음파 센서(HC-SR04) 사용하기

[Arduino] 아두이노 조이스틱 사용하기

[자연 환경] 농약의 장단점 농약이 환경과 인간에게 미치는 영향