[머신러닝] 데이터 전처리 - 표준점수
데이터 전처리 - 표준점수
데이터 전처리란?
데이터 전처리(data preprocessing)란 머신러닝 모델에 훈련 데이터를 주입 하기 전에 가공하는 단계를 말한다. 데이터 전처리 작업을 거치지 않으면 모델의 학습 및 예측이 정확하게 이뤄지지 않을 수가 있다.
아래 그림을 보면 머신러닝 모델을 만드는 순서다.
크게 보면 데이터 준비 -> 데이터 전처리 -> 모델 훈련 -> 모델 평가 순서로 볼 수 있다.
표준점수란?
표준 점수(standard score)는 데이터 전처리 방법 중 하나다. 표준 점수는 각 특성 값이 평균에서 표준편차의 몇 배 만큼 떨어져 있는지 나타낸다.
표준점수는 이번 게시물에서 다룰 내용이다.
훈련 세트, 테스트 세트 만들기
우선 데이터 전처리 중 표준점수가 어디에 쓰는지 알기 위해서 모델부터 만들자.
K-최근접 이웃 알고리즘으로 모델을 만들기 위해서 훈련 세트와 테스트 세트를 만들자.
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 #리스트 합치기
#넘파이 column_stack()함수로 2차원 리스트 만들기
person_data = np.column_stack((height, weight))
# 정답 데이터 만들기/ 어린이는 0 어른은 1
#넘파이 concatenate() 함수는 두개의 배열을 이어준다.
#np.zero 는 0 을 10개 만들어 준다., np.ones는 1을 5개 만들어준다.
person_target = np.concatenate((np.zeros(10), np.ones(5)))
#훈련 세트, 테스트 세트 나누기----------------------------------------------------------
# 사이킷런 train_test_split함수는 리스트나 배열을 무작위로 섞고 알아서 나눠준다.
from sklearn.model_selection import train_test_split
#train_test_splite은 25%를 테스트 세트로 떼어내어 샘플링 편향이 나타 날 수있다.
#이 때 stratify 변수에 타깃데이터를 전달하면 클래스 비율에 맞게 데이터를 나눈다.
train_input, test_input, train_target, test_target = (
train_test_split(person_data, person_target, stratify = person_target, random_state=42))
모델 평가하기
사이킷런으로 모델을 평가해보자.
정확도 100%가 나온다. 여기 까지는 문제가 없어 보인다.
#모델 평가하기 ------------------------------------------------------------------------
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
예측할 데이터를 포함한 산점도 그리기
이제 한번 예측 할 데이터 175, 200에 주황색 별을 찍어보자.
파랑 색 원은 현재 훈련 세트 입력 데이터다.
왼쪽에 모여있는 원 7개가 child 특성이며 오른쪽 상단에 원 4개는 adult특성이다.
그에 따라 사이킷런으로 perdict을 한다면 adult에 가까운 주황색 별은 adult가 나와야 한다.
현재 adult target은 1이다.
#그래프 그리기 -----------------------------------------
import matplotlib.pyplot as plt #그래프 그리는 패키지 import
plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(175, 200, marker ='*')
plt.xlabel('height')
plt.ylabel('weight')
plt.show()
새로운 데이터 예측하기
위에 산점도를 봤을 때 새로운 데이터(주황색 별)은 adult로 예상 가능 했다.
이제 predict 함수로 예측을 해보고 결과를 보자.
어라? 0(child)가 나왔다. 분명 새로운 데이터는 adult 와 가까운데 말이다.
#모델 예측하기 ------------------------------------------------------------------------
b = kn.predict([[175,200]])
print(b)
결과 : [0.]
child가 나오는 것은 스케일이 다르기 때문
산점도를 보면 X축은 35, Y축은 100이 차이난다.
따라서 Y축은 크게 영향을 미치지 못하고 X축만 고려되어 child(0)이 나오게 된다.
child와 adult 처럼 두 개의 특성의 값이 놓인 범위가 다른 것을 스케일이 다르다고 표현한다. 정확한 데이터를 보기 위해서는 특성 값을 일정한 기준으로 맞춰야 하며 이 과정을 데이터 전처리라고 부른다.
표준점수 만들기
위에 문제들을 해결하기 위해서는 데이터 전처리 방법 중하나인 표준점수를 만들어야 한다.
우선 표준편차란 분산의 제곱근으로 데이터가 분산 된 정도를 나타낸다.
표준점수는 각 데이터가 원점에서 표준편차의 몇 배만큼 떨어져 있는지 나타낸다.
계산은 다음과 같다. 평균을 빼고 표준편차를 나눠주면 된다.
이때 넘파이는 평균 구하는 함수, 표준편차 계산함수 이 두 함수를 제공한다.
이렇게 알아서 계산해주는 넘파이 기능을 브로드캐스팅 이라고 부른다.
#표준점수 구하기------------------------------------------------------------------------
mean = np.mean(train_input, axis = 0) #평균 계산
std = np.std(train_input, axis = 0) #표준편차 계산
train_scaled = (train_input - mean)/std #표준점수 구하기
산점도 그려보기
표는 바뀌지 않았지만 x, y축이 -1.0 ~ 1.5 사이로 바꼈다.
#표준 점수 구한 후 그래프 그리기 -----------------------------------------
new = ([175, 200] - mean) / std
plt.scatter(train_scaled[:,0], train_scaled[:,1])
plt.scatter(new[0], new[1], marker ='*')
plt.xlabel('height')
plt.ylabel('weight')
plt.show()
모델 평가하고 예측하기
평가는 당연히 100%가 나오고
예측 데이터도 예상 한 결과 adult(1)로 나오게 된다.
#표준 점수 구한 후 모델 평가하기 ------------------------------------------------------------------------
from sklearn.neighbors import KNeighborsClassifier #사이킷런 Kneighclass import
kn = KNeighborsClassifier()
kn.fit(train_scaled, train_target) #훈련 시키기
a = kn.score(train_scaled, train_target) #모델 평가하기
print(a)
#준 점수 구한 후 새로운 데이터 예측하기 ------------------------------------------------------------------------
b = kn.predict([[175,200]])
print(b)
결과 :
1.0
[1.]
전체 소스 코드
이 게시물에서 사용한 소스 코드다.
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 #리스트 합치기
#넘파이 column_stack()함수로 2차원 리스트 만들기
person_data = np.column_stack((height, weight))
# 정답 데이터 만들기/ 어린이는 0 어른은 1
#넘파이 concatenate() 함수는 두개의 배열을 이어준다.
#np.zero 는 0 을 10개 만들어 준다., np.ones는 1을 5개 만들어준다.
person_target = np.concatenate((np.zeros(10), np.ones(5)))
#훈련 세트, 테스트 세트 나누기----------------------------------------------------------
# 사이킷런 train_test_split함수는 리스트나 배열을 무작위로 섞고 알아서 나눠준다.
from sklearn.model_selection import train_test_split
#train_test_splite은 25%를 테스트 세트로 떼어내어 샘플링 편향이 나타 날 수있다.
#이 때 stratify 변수에 타깃데이터를 전달하면 클래스 비율에 맞게 데이터를 나눈다.
train_input, test_input, train_target, test_target = (
train_test_split(person_data, person_target, stratify = person_target, random_state=42))
#모델 평가하기 ------------------------------------------------------------------------
from sklearn.neighbors import KNeighborsClassifier #사이킷런 Kneighclass import
kn = KNeighborsClassifier()
kn.fit(train_input, train_target) #훈련 시키기
a = kn.score(train_input, train_target) #모델 평가하기
print(a)
# #그래프 그리기 -----------------------------------------
import matplotlib.pyplot as plt #그래프 그리는 패키지 import
#
# plt.scatter(train_input[:,0], train_input[:,1])
# plt.scatter(175, 200, marker ='*')
#
# plt.xlabel('height')
# plt.ylabel('weight')
# plt.show()
#새로운 데이터 예측하기 ------------------------------------------------------------------------
b = kn.predict([[175,200]])
print(b)
#표준점수 구하기------------------------------------------------------------------------
mean = np.mean(train_input, axis = 0) #평균 계산
std = np.std(train_input, axis = 0) #표준편차 계산
train_scaled = (train_input - mean)/std #표준점수 구하기
#표준 점수 구한 후 그래프 그리기 -----------------------------------------
new = ([175, 200] - mean) / std
plt.scatter(train_scaled[:,0], train_scaled[:,1])
plt.scatter(new[0], new[1], marker ='*')
plt.xlabel('height')
plt.ylabel('weight')
plt.show()
#표준 점수 구한 후 모델 평가하기 ------------------------------------------------------------------------
from sklearn.neighbors import KNeighborsClassifier #사이킷런 Kneighclass import
kn = KNeighborsClassifier()
kn.fit(train_scaled, train_target) #훈련 시키기
a = kn.score(train_scaled, train_target) #모델 평가하기
print(a)
#준 점수 구한 후 새로운 데이터 예측하기 ------------------------------------------------------------------------
b = kn.predict([[175,200]])
print(b)
참조
혼자 공부하는 머신러닝 + 딥러닝(박해선, 한빛 미디어) : https://hongong.hanbit.co.kr/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-%EB%94%A5%EB%9F%AC%EB%8B%9D/
혼자 공부하는 머신러닝 + 딥러닝(깃 허브) : https://github.com/rickiepark/hg-mldl
댓글
댓글 쓰기