<핵심 키워드>
데이터가 클수록 넘파이 배열을 활용하는것이 좋다(C,C++ 같은 저수준 언어로 개발되었기 때문)
사이킷런에서 train_test_split을 통해서 알아서 섞고 학습,타깃 데이터 나눌수 있음(stratify는 타깃값보고 클래스 비율에 맞게 나눠줌)
길이, 무게는 단위가 다르므로, 표준점수(Zscore)를 활용하여 단위의 기준비율을 맞추어야 된다.(스케일, 데이터 전처리)
표준점수: 각 특성값이 평균에서 표준편차의 몇배만큼 떨어져 있는지를 나타낸다. (데이터Arr-평균)/표준편차
브로드캐스팅: 넘파이 배열에서 알아서 깔끔하게 각 배열요소마다 사칙연산 해주고 수정해주는 기능이다.
표준점수를 적용할때는 Train, Test, Predictdata 모두 스케일을 진행해주어야 한다!!!
<알아두어야 하는 코드>
# 세로로 이어 붙이기
np.column_stack(([1,2,3], [4,5,6]))
''' 세로로 나열한뒤 옆구리에 딱 붙이기
array([[1, 4],
[2, 5],
[3, 6]])
'''
# 행 방향으로 꼬리 이어 붙이기
fish_data = np.column_stack((fish_length, fish_weight))
# ones, zeros 사용한 1,0으로만 이루어진 넘파이 배열 생성하기
fish_target = np.concatenate((np.ones(35), np.zeros(14)))
# 사아킷런을 활용한 자동으로 Train, Test 데이터셋 알아서 섞어서 나누기 실행 (75:25 비율로 나눔, 순서 중요)
# 순서: 학습입력, 테스트입력, 학습타깃(정답), 테스트타깃(정답) 으로 나누어서 반환됨
# 또한 strstratify = 타깃배열 으로 설정해두면 샘플링 편향 없게 비율 잘 섞어서 나눠줌 (기본 25%로 테스트셋 할당)
# random_state를 활용하면 시드 고정 기능도 있다고~~
train_input, test_input, train_target, test_target = train_test_split(fish_data, fish_target, stratify=fish_target, random_state=42)
# 입력된 값을 바탕으로 실제 이웃의 거리, 인덱스번호를 알려주는 기능(추적이 가능함)
distance, indexes = kn.kneighbors([[25,150]])
plt.xlim((0,1000)) # X축의 범위를 직접 정하는 기능
mean = np.mean(train_input, axis=0) # 열 방향으로 평균 계산
mean = np.std(train_input, axis=0) # 열 방향으로 표준편차 계산
전체 코드는 아래와 같다
#%%
# 생선 데이터들
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]
import numpy as np
# 세로로 이어 붙이기
np.column_stack(([1,2,3], [4,5,6]))
''' 세로로 나열한뒤 옆구리에 딱 붙이기
array([[1, 4],
[2, 5],
[3, 6]])
'''
fish_data = np.column_stack((fish_length, fish_weight))
# 가로로 이어 붙이기, 1혹은 0으로만 있는 넘파이 배열생성,
fish_target = np.concatenate((np.ones(35), np.zeros(14)))
print(fish_data.shape) # 물고기 데이터 (49, 2)
print(fish_target.shape) # 물고기 타깃 (49,)
#%% 사이킷런 활용, 잘 섞어서 훈련셋 데이터셋 나누기 실행
from sklearn .model_selection import train_test_split
# 순서 중요# 학습입력, 테스트입력, 학습타깃(정답), 테스트타깃(정답) 으로 나누어서 반환됨
# 또한 strstratify = 타깃배열 으로 설정해두면 샘플링 편향 없게 비율 잘 섞어서 나눠줌 (기본 25%로 테스트셋 할당)
# random_state를 활용하면 시드 고정 기능도 있다고~~
train_input, test_input, train_target, test_target = train_test_split(fish_data, fish_target, stratify=fish_target, random_state=42)
#%% 이제 처음 만나는 샘플을 집어넣어 봅시다.
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
kn = KNeighborsClassifier(n_neighbors=5)
kn.fit(train_input, train_target)
kn.score(test_input, test_target) # 테스트셋 바탕으로는 잘 맞추네(아직 데이터 전처리 전임)
print(kn.predict([[25,150]])) # 1이 나와야 하는데 0이 나와 버림(길이,무게의 스케일 문제가 발생함)
plt.scatter(train_input[:,0],train_input[:,1])
plt.scatter(25,150, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.savefig('데이터전처리 전 산포도.png') # 라벨이 1인 쪽에 더 가까워 보이는걸 알수 있음
plt.clf()
#%% 한번 가장 가깝다고 측정된 이웃을 kneighbor 함수를 활용해 직접 찾아 봅시다.
distance, indexes = kn.kneighbors([[25,150]])
print(distance) # [[ 92.00086956 130.48375378 130.73859415 138.32150953 138.39320793]]
print(indexes) # [[21 33 19 30 1]]
plt.scatter(train_input[:,0],train_input[:,1]) # 트레인 인풋 데이터 그림 그리기
plt.scatter(25,150, marker = '^')
plt.scatter(train_input[indexes,0], train_input[indexes,1], marker='D') # 이웃 5명의 좌표 다이아몬드 표시 하기
plt.xlabel('length')
plt.ylabel('weight')
plt.savefig('스케일이다르면_발생하는문제점.png')
plt.clf()
plt.scatter(train_input[:,0],train_input[:,1]) # 트레인 인풋 데이터 그림 그리기
plt.scatter(25,150, marker = '^')
plt.scatter(train_input[indexes,0], train_input[indexes,1], marker='D') # 이웃 5명의 좌표 다이아몬드 표시 하기
plt.xlim((0,1000)) # X축의 범위를 직접 정하는 기능
plt.xlabel('length')
plt.ylabel('weight')
plt.savefig('실제스케일대로_측정시_이웃의현실.png')
plt.clf()
# %% 정상적인 결과 확인을 위한 표준점수(Zscore)를 활용한 데이터 전처리 실행하기
# Z스코어 계산법 = (data - mean)/std # 데이터는 보통 여러개인데, 넘파이에서 자동으로 브로드캐스팅을 통해 알잘딱깔센하게 각각 계산해줌
# 각 특성값이 평균에서 표준편차의 몇배 만큼 떨어져 있는지를 나타낸다.
mean = np.mean(train_input, axis=0) # colum 방향으로 평균을 구해야 함(잊지말자, 그럼 길이, 무게의 평균이 나온다.)
std = np.std(train_input, axis=0)
train_scaled = (train_input-mean)/std # 표준점수가 담긴 train_scaled 완성
# 데이터전처리 후 다시 그림을 그려보자
plt.scatter(train_scaled[:,0], train_scaled[:,1])
new = ([25, 150] - mean) / std
distance, indexs = kn.kneighbors([new])
plt.scatter(train_scaled[indexes,0], train_scaled[indexes,1], marker='D')
plt.scatter(new[0], new[1], marker = '^')
plt.xlabel('length')
plt.ylabel('weight')
plt.savefig('스케일링_후의_이미지.png')
# %% 스케일 데이터를 바탕으로 모델 학습을 진행 한다.
kn.fit(train_scaled, train_target)
# 잊지말자 test데이터들도 스케일화 해주어야 한다.(mean, std는 학습데이터를 사용하면 됨)
test_scaled = (test_input - mean)/std
print(kn.score(test_scaled, test_target), '테스트셋 점수 계산')
print(kn.predict([new]))
# 다시 이웃을 찾아보자
distance, indexes = kn.kneighbors([new])
plt.scatter(train_scaled[:,0], train_scaled[:,1])
plt.scatter(new[0], new[1], marker='^')
plt.scatter(train_scaled[indexes,0], train_scaled[indexes,1], marker='D')
plt.xlabel('length')
plt.ylabel('weight')
plt.savefig('새 입력에 대한 이웃결과.png')
'머신러닝 & 딥러닝' 카테고리의 다른 글
[혼자 공부하는 머신러닝] 03-03 특성공학과 규제(다중회귀, 변환기, 릿지&라쏘 회귀) (1) | 2024.01.24 |
---|---|
[혼자 공부하는 머신러닝] 03-2 선형회귀 그리고 다항회귀 (0) | 2024.01.21 |
[혼자 공부하는 머신러닝] 02-1 훈련세트와 테스트세트 (0) | 2024.01.15 |
[혼자 공부하는 머신러닝] K 최근접이웃을 활용한 2class분류 (KNeighborsClassifier) (1) | 2024.01.13 |
[머신러닝/딥러닝] PART 2 (0) | 2023.07.17 |