일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- position
- 표준화 z
- CSS
- 스크롤뷰
- 선택자 조건
- 머신러닝
- hover
- 지도학습
- 버튼 상속
- 넘파이
- 스낵바
- predict메소드
- 데이터 전처릴
- K최근접이웃 회귀
- relative
- HTML
- 메모리 객체화
- 레이아웃
- 픽셀 깨짐
- apapter
- kneighbors()
- 웹사이트 공개
- 훈련세트
- fit메소드
- Absolute
- 테스트세트
- JavaScript
- score메소드
- LENGTH_INDEFINITE
- 외부css
- Today
- Total
베짱이와 노는 개미
ML#5 - 데이터 전처리 본문
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
from sklearn.model_selection import train_test_split
fish_length = [25.4, 26.3, 26.5, 29.0, 29.0, 29.7, 29.7, 30.0, 30.0, 30.7, 31.0, 31.0,
31.5, 32.0, 32.0, 32.0, 33.0, 33.0, 33.5, 33.5, 34.0, 34.0, 34.5, 35.0,
35.0, 35.0, 35.0, 36.0, 36.0, 37.0, 38.5, 38.5, 39.5, 41.0, 41.0, 9.8,
10.5, 10.6, 11.0, 11.2, 11.3, 11.8, 11.8, 12.0, 12.2, 12.4, 13.0, 14.3, 15.0]
fish_weight = [242.0, 290.0, 340.0, 363.0, 430.0, 450.0, 500.0, 390.0, 450.0, 500.0, 475.0, 500.0,
500.0, 340.0, 600.0, 600.0, 700.0, 700.0, 610.0, 650.0, 575.0, 685.0, 620.0, 680.0,
700.0, 725.0, 720.0, 714.0, 850.0, 1000.0, 920.0, 955.0, 925.0, 975.0, 950.0, 6.7,
7.5, 7.0, 9.7, 9.8, 8.7, 10.0, 9.9, 9.8, 12.2, 13.4, 12.2, 19.7, 19.9]
fish_data = np.column_stack((fish_length, fish_weight))
fish_target = np.concatenate((np.ones(35),np.zeros(14)))
train_input, test_input, train_target, test_target = train_test_split(fish_data, fish_target, random_state=42)
kn = KNeighborsClassifier();
kn.fit(train_input, train_target)
kn.score(test_input, test_target)
print(kn.predict([[25,150]]))
이 코드에 대해서 설명을 해보자면
fish_length , fish_weight 데이터를 받고
target데이터를 만들어준후에 기계에 fit()메소드로 학습을 시켰다.
잘 학습됐는지 알아보기위해 score메소드를 이용해본 결과 1.0이 나왔다.
학습은 잘됐는데
[25,150]은 크기가 크고 무게가 많이 나가므로 bream 즉, 1로 예측을 해야하는데
실제 출력값은 0이 나온다
즉 학습은 잘됐는데 특정 데이터에 대해서 잘못된 결과를 출력하는 현상이 발생했다.
이 부분에 대해서 오늘 포스팅해보겠다.
일단 (25,150)이라는 좌표값이 어디에 찍히는지 봐야 k최근접이웃 알고리즘에서 문제가 있는건지 확인가능하기떄문에
산점도를 먼저 그려보면
plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(25,150, marker='^')
plt.xlabel=('length')
plt.ylabel=('weight')
plt.show()
잘보면 bream개체들과 위치가 비슷한것으로 나오는데 왜 결과값은 1(bream)이 아닌 0(smelt)가 나오는 걸까
k최근접 이웃은 주변의 샘플중에서 다수를 확인하고 이를 통해 예측한다.
(25,150)주변의 샘플에 대한 정보들을 확인해볼 필요가 있다.
kneighbors()라는 메소드를 통해서 이웃까지의 거리와 이웃샘플의 인덱스를 반환 받아보자
distances , index = kn.kneighbors([[25,150]]) #기본값인 5개의 샘플이 반환된다.
plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(25,150, marker='^')
plt.scatter(train_input[index,0], train_input[index,1], marker='D')
plt.xlabel=('length')
plt.ylabel=('weight')
plt.show()
print(train_input[index])
print(train_target[index])
잘보면 삼각형점 주변의 이웃 샘플들은 bream무리(2개)보다 smelt무리(3개)가 더 많이 나온다.
근데 왜 산점도 상에서는 bream무리에 더 가깝게 찍히는 걸까? 아직 이해가 안된다.
정리를 해보면 (25,150)이라는 샘플은 bream이라고 판단되어야한다.
실제로 산점도는 bream무리에 더 가깝게 찍힌다.
그런데 predict([[25,150]])이나 다이아몬드 점들을 볼때는 smelt로 판단되는게 이상해 보이지는 않는다
이번엔 거리를 한번 봐보자
print(distances)
이렇게 나온다
잘보면 bream쪽에 찍힌 다이아몬드 2개중 제일 가까운 샘플과의 거리는 92정도이고
smelt쪽에 찍힌 다이아몬드 3개중 제일 가까운 샘플과의 거리는 138정도이다 근데
92와 138이라는 두 거리의 비율이 맞지 않는게 보인다.
x축과 y축의 척도가 맞지 않아서이다. 범위가 다르다 스케일이 다르다라고도 표현한다.
이제 뭔가 감이 온다.
다시말해서 기계가 거리를 제대로 인식하지 못한것이다.
x축의 거리를 y축과 같게 해주기 위해서 xlim()함수를 이용해보겠다.
plt.xlim(0,1000)
이렇게 바뀐다 그럼 x축인 길이보다는 y축값인 무게가 생선을 비교하는데 영향을 주는 변수라고 할수있겠다.
이렇게 기준을 맞춰주는 작업을 데이터 전처리 라고 한다.
특히 거리를 기반으로 하는 알고리즘에서는 매우 중요한 작업이다.
k최근접이웃 알고리즘 역시 샘플들 간의 거리에 영향을 받기떄문에 이 작업이 필요하다.
고등학교 수학에서 표준편차가 다른 정규분포를 따르는 두 확률변수에 대해서 표준화 작업을 거치는데
이것또한 데이터 전처리라고 이해 하면 될것같다.
실제로 전처리 방법 중 제일 많이 사용되는 방법이 표준점수 이다.(Z값)
Z = (샘플값-평균)/표준편차 이 공식을 이용하는것이다.
평균과 표준편차를 구하기 위해서는 numpy에서 제공되는 함수 mean,std를 사용해야한다.
mean = np.mean(train_input, axis=0) #train_input list를 세로 방향으로 평균값 구하기
std = np.std(train_input, axis=0) #train_input list를 세로 방향으로 표준편차 구하기
train_scaled=(train_input-mean)/std #z값으로 변경해준 훈련용 데이터
new=([25,150]-mean)/std #(25,150)이라는 값도 z값으로 변경해줘야 한다
plt.scatter(train_scaled[:,0], train_scaled[:,1])
plt.scatter(new[0],new[1],marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
kn.fit(train_scaled, train_target) #z값으로 변경된 훈련용 데이터와 훈련용 타켓데이터를 가지고 학습시켜준다.
test_scaled=(test_input-mean)/std #테스트용 데이터 역시 z값으로 변경해줘야함
kn.score(test_scaled, test_target)
print(kn.predict([new]))
그럼 이제 드디어 [25,150]이라는 특성의 물고기를 bream으로 판단한다
전처리 데이터로 모델 훈련을 완료한것이다!!
'AI(머신러닝+딥러닝) 프로젝트' 카테고리의 다른 글
ML#6 - K최근접 이웃 회귀 (0) | 2021.08.07 |
---|---|
ML#4 - 파이썬 함수 정리(수시 업데이트) (0) | 2021.08.06 |
ML#3-테스트세트,훈련세트 (0) | 2021.08.04 |
AI#2-지도학습 (0) | 2021.07.31 |
AI#1 - 머신러닝과 딥러닝은 무엇인가? (0) | 2021.07.30 |