데이터 분석
[Python] 혼공 머신러닝 + 딥러닝 데이터 표준화의 중요성
BTC_기범
2022. 4. 11. 22:33
출처 : 혼자 공부하는 머신러닝 + 딥러닝
데이터 전처리_2
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]
# 각 파라미터에 할당 받은 리스트에 인덱스에 맞춰 zip 함수와 같은 역할을 한다
np.column_stack(([1,2,3],[4,5,6]))
# 데이터의 원소가 물고기의 길이와 무게 값을 가진 배열이 되도록 처리
fish_data = np.column_stack((fish_length, fish_weight))
# 35개의 1을 원소로 가진 배열 과 14개의 0을 원소로 가진 배열을 concatenate 함수로 하나의 배열로 통합
fish_target = np.concatenate((np.ones(35), np.zeros(14)))
# 사이킷런의 데이터를 train dataset과 test dataset으로 분리하는 함수
from sklearn.model_selection import train_test_split
# 기본 test dataset의 비율은 20%, random_state 파라미터는 분리 결과 값을 일관되게 만듦
train_input, test_input, train_target, test_target = train_test_split(fish_data, fish_target, random_state=42)
print(train_input.shape, test_input.shape) # (36,2) (13, 2)로 나눠짐
print(train_target.shape, test_target.shape) # (36, ) (13, )로 나눠짐
# stratify 파라미너는 입력한 매개변수의 원소비율을 파악하고,
# 분리하는 배열들이 파악한 비율과 동일한 비율을 가지도록 한다
train_input, test_input, train_target, test_target = train_test_split(fish_data, fish_target,
stratify=fish_target, random_state=42)
K-최근접 이웃 모델링_2
# k-최근접 이웃 객체에 train_input과 train_target을 이용하여 학습을 진행하여 모델링
kn = kn.fit(train_input, train_target)
# 위의 학습 진행한 모델의 테스트 점수
kn.score(test_input, test_target) # 1.0
# 모델을 이용하여 test_input을 기반으로 예측값 출력
kn.predict(test_input) # array([0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0])
test_target # array([0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0])
K-최근접 이웃 모델_2를 통한 데이터 분류
# 도미로 분류하는 것이 적절한 데이터를 예측을 진행 했으나 빙어로 분류했다
print(kn.predict([[25,150]])) # [0.]
# 산점도 그래프를 출력, 데이터 확인
plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(25, 150, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
산점도 그래프를 그려 보았을 때도 도미의 데이터들가 가까워 보인다. k-최근점 분류가 가까운 데이터의 분류를 따라가는 알고리즘이란 것을 상기해보면 노란 화살점(25,150)을 빙어로 구분하는 것은 이상하다.
# kn.kneighbors 함수는 입력된 데이터와 입력된 데이터,
# 최근접한 데이터 사이의 거리와 최근접한 것으로 인식된 데이터의 인덱스를 할당
distances, indexes = kn.kneighbors([[25, 150]])
# train data의 데이터를 모두 그래프에 표시
plt.scatter(train_input[:,0], train_input[:,1])
# 무게 : 25,길이 : 150인 데이터 그래프에 표시
plt.scatter(25, 150, marker='^')
# 인덱스에 할당된 데이터를 그래프에 표시, marker 파라미터 'D'를 통해 표시 모양을 다이아몬드로 지정
plt.scatter(train_input[indexes,0], train_input[indexes,1], marker='D')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
# 25, 150과 가장 가까운 데이터 5개 출력
print(train_input[indexes])
'''
[[[ 25.4 242. ]
[ 15. 19.9]
[ 14.3 19.7]
[ 13. 12.2]
[ 12.2 12.2]]]
'''
25, 150 데이터와 가까운 데이터 5개 중 4개가 빙어의 데이터인 것을 확인할 수 있었고 이로 인해 빙어로 분류되었다는 것을 파악하였다.
# # 25, 150 데이터와 가장 가까운 데이터 5개 사이의 거리 출력
print(distances)
# [[ 92.00086956 130.48375378 130.73859415 138.32150953 138.39320793]]
# x, y 축의 한계가 같은 그래프 출력
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')
plt.xlim((0,1000)) # x 축의 한계를 0~1000으로 연장
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
물고기 무게의 축의 한계와 물고기 길이의 축의 한계를 같게 설정하였을 때 무게의 분포에 비해 길이의 분포는 미미한 것을 파악할 수 있다. 고로 분류에 무게 변수의 영향이 더 크다는 것을 알 수 있다.
데이터 표준화
mean= np.mean(train_input, axis=0)
std=np.std(train_input, axis=0)
train_scaled = (train_input - mean) / std # 표준화 진행
new = ([25,150] - mean) / std # (25, 150) 데이터에 표준화 진행
plt.scatter(train_scaled[:,0], train_scaled[:,1])
plt.scatter(new[0], new[1], marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
K-최근접 이웃 모델링_3
# 표준화 데이터로 모델링
kn.fit(train_scaled, train_target)
# test dataset 표준화 진행
test_scaled = (test_input - mean) / std
# 표준화 데이터 모델 테스트
kn.score(test_scaled, test_target) # 1.0
# 표준화한 25,150 데이터 예측, 도미로 분류 됨^^
print(kn.predict([new])) # [1.]
distances, 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.show()
표준화 데이터로 kneighbores 함수를 실행 시킨 후 최근접 데이터를 산점도 그래프에 출력해보았을 때 표준화된 25, 150 데이터와 최근접한 데이터가 모두 도미로 분류되어 있는 것을 확인할 수 있다. 데이터 분석을 위해서는 각 특성의 영향력의 차이를 고려하여 전처리 과정에서 표준화를 진행한 후 분석을 진행하는 것이 중요하다는 점을 알 수 있다.