02-1훈련데이터의 일부를 테스트세트로 사용
데이터 출처 : https://bit.ly/bream_smelt
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 = [[l,w] for l,w in zip(fish_length,fish_weight)]
fish_target = [1]*35 + [0]*14
from sklearn.neighbors import KNeighborsClassifier
kn = KNeighborsClassifier()
print(fish_data)
[[25.4, 242.0], [26.3, 290.0], [26.5, 340.0], [29.0, 363.0], [29.0, 430.0], [29.7, 450.0], [29.7, 500.0], [30.0, 390.0], [30.0, 450.0], [30.7, 500.0], [31.0, 475.0], [31.0, 500.0], [31.5, 500.0], [32.0, 340.0], [32.0, 600.0], [32.0, 600.0], [33.0, 700.0], [33.0, 700.0], [33.5, 610.0], [33.5, 650.0], [34.0, 575.0], [34.0, 685.0], [34.5, 620.0], [35.0, 680.0], [35.0, 700.0], [35.0, 725.0], [35.0, 720.0], [36.0, 714.0], [36.0, 850.0], [37.0, 1000.0], [38.5, 920.0], [38.5, 955.0], [39.5, 925.0], [41.0, 975.0], [41.0, 950.0], [9.8, 6.7], [10.5, 7.5], [10.6, 7.0], [11.0, 9.7], [11.2, 9.8], [11.3, 8.7], [11.8, 10.0], [11.8, 9.9], [12.0, 9.8], [12.2, 12.2], [12.4, 13.4], [13.0, 12.2], [14.3, 19.7], [15.0, 19.9]]
# 배열의 요소를 선택할 때 : 인덱스를 지정
print(fish_data[4])
[29.0, 430.0]
# 배열의 요소 범위를 지정 : 슬라이싱
# 요소 첫 번째부터 다섯 번째까지 선택
print(fish_data[0:5])
print(fish_data[:5]) # 0 은 생략 가능
print(fish_data[44:]) # 마지막 원소까지 출력할 경우 마지막 원소는 생략
[[25.4, 242.0], [26.3, 290.0], [26.5, 340.0], [29.0, 363.0], [29.0, 430.0]]
[[25.4, 242.0], [26.3, 290.0], [26.5, 340.0], [29.0, 363.0], [29.0, 430.0]]
[[12.2, 12.2], [12.4, 13.4], [13.0, 12.2], [14.3, 19.7], [15.0, 19.9]]
훈련데이터와 테스트데이터 나누기
# 훈련 세트로 "입력값" 중 0~35까지
train_input = fish_data[:35]
# 훈련 세트로 "타겟값" 중 0~35까지
train_target = fish_target[:35]
# 테스트 세트로 "입력값" 중 0~35까지
test_input = fish_data[35:]
# 테스트 세트로 "타겟값" 중 0~35까지
test_target = fish_target[35:]
평가
kn = kn.fit(train_input, train_target)
kn.score(test_input, test_target)
0.0
정확도가 0.0이 나온 이유에 대하여
훈련세트와 테스트세트를 구분하는 과정에서 샘플링의 편향으로 인해 제대로된 결과도출이 안됨
넘파이 사용하기
import numpy as np
input_arr = np.array(fish_data)
target_arr = np.array(fish_target)
print(input_arr)
print(target_arr)
[[ 25.4 242. ]
[ 26.3 290. ]
[ 26.5 340. ]
[ 29. 363. ]
[ 29. 430. ]
[ 29.7 450. ]
[ 29.7 500. ]
[ 30. 390. ]
[ 30. 450. ]
[ 30.7 500. ]
[ 31. 475. ]
[ 31. 500. ]
[ 31.5 500. ]
[ 32. 340. ]
[ 32. 600. ]
[ 32. 600. ]
[ 33. 700. ]
[ 33. 700. ]
[ 33.5 610. ]
[ 33.5 650. ]
[ 34. 575. ]
[ 34. 685. ]
[ 34.5 620. ]
[ 35. 680. ]
[ 35. 700. ]
[ 35. 725. ]
[ 35. 720. ]
[ 36. 714. ]
[ 36. 850. ]
[ 37. 1000. ]
[ 38.5 920. ]
[ 38.5 955. ]
[ 39.5 925. ]
[ 41. 975. ]
[ 41. 950. ]
[ 9.8 6.7]
[ 10.5 7.5]
[ 10.6 7. ]
[ 11. 9.7]
[ 11.2 9.8]
[ 11.3 8.7]
[ 11.8 10. ]
[ 11.8 9.9]
[ 12. 9.8]
[ 12.2 12.2]
[ 12.4 13.4]
[ 13. 12.2]
[ 14.3 19.7]
[ 15. 19.9]]
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0]
#(샘플 수, 특성 수)
print(input_arr.shape)
(49, 2)
#0~48까지 인덱스를 생성하여 랜덤하게 섞기
np.random.seed(42) # 랜덤시드 지정 - 책과 동일한 랜덤생성을 위함
index = np.arange(49) # 0-48까지 1씩 증가하는 인덱스 생성
np.random.shuffle(index) # 섞기
print(index)
[13 45 47 44 17 27 26 25 31 19 12 4 34 8 3 6 40 41 46 15 9 16 24 33
30 0 43 32 5 29 11 36 1 21 2 37 35 23 39 10 22 18 48 20 7 42 14 28
38]
# 배열 슬라이싱 : 배열 요소를 선택
print(input_arr)
print(input_arr[[1,3]]) # input_arr[1] input_arr[3]
print(input_arr[1:3]) # input_arr[1]~input_arr[2]
[[ 25.4 242. ]
[ 26.3 290. ]
[ 26.5 340. ]
[ 29. 363. ]
[ 29. 430. ]
[ 29.7 450. ]
[ 29.7 500. ]
[ 30. 390. ]
[ 30. 450. ]
[ 30.7 500. ]
[ 31. 475. ]
[ 31. 500. ]
[ 31.5 500. ]
[ 32. 340. ]
[ 32. 600. ]
[ 32. 600. ]
[ 33. 700. ]
[ 33. 700. ]
[ 33.5 610. ]
[ 33.5 650. ]
[ 34. 575. ]
[ 34. 685. ]
[ 34.5 620. ]
[ 35. 680. ]
[ 35. 700. ]
[ 35. 725. ]
[ 35. 720. ]
[ 36. 714. ]
[ 36. 850. ]
[ 37. 1000. ]
[ 38.5 920. ]
[ 38.5 955. ]
[ 39.5 925. ]
[ 41. 975. ]
[ 41. 950. ]
[ 9.8 6.7]
[ 10.5 7.5]
[ 10.6 7. ]
[ 11. 9.7]
[ 11.2 9.8]
[ 11.3 8.7]
[ 11.8 10. ]
[ 11.8 9.9]
[ 12. 9.8]
[ 12.2 12.2]
[ 12.4 13.4]
[ 13. 12.2]
[ 14.3 19.7]
[ 15. 19.9]]
[[ 26.3 290. ]
[ 29. 363. ]]
[[ 26.3 290. ]
[ 26.5 340. ]]
print(index[:35]) # index배열의 인덱스0~34 요소
print(index[35:]) # index배열의 인덱스35~끝 요소
train_input = input_arr[index[:35]]
train_target = target_arr[index[:35]]
test_input = input_arr[index[35:]]
test_target = target_arr[index[35:]]
[13 45 47 44 17 27 26 25 31 19 12 4 34 8 3 6 40 41 46 15 9 16 24 33
30 0 43 32 5 29 11 36 1 21 2]
[37 35 23 39 10 22 18 48 20 7 42 14 28 38]
# 섞기 전 배열의 13번 인덱스 요소가 섞인 후 train_input배열의 0번째 요소
print(input_arr[13], train_input[0])
[ 32. 340.] [ 32. 340.]
# 산점도 그리기
import matplotlib.pyplot as plt
print("train_input 배열의 [행전체,첫번째열] \n",train_input[:,0])
print("train_input 배열의 [행전체,두번째열] \n",train_input[:,1])
print("train_input \n",train_input)
plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(test_input[:,0], test_input[:,1])
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
train_input 배열의 [행전체,첫번째열]
[32. 12.4 14.3 12.2 33. 36. 35. 35. 38.5 33.5 31.5 29. 41. 30.
29. 29.7 11.3 11.8 13. 32. 30.7 33. 35. 41. 38.5 25.4 12. 39.5
29.7 37. 31. 10.5 26.3 34. 26.5]
train_input 배열의 [행전체,두번째열]
[ 340. 13.4 19.7 12.2 700. 714. 720. 725. 955. 650.
500. 430. 950. 450. 363. 500. 8.7 10. 12.2 600.
500. 700. 700. 975. 920. 242. 9.8 925. 450. 1000.
500. 7.5 290. 685. 340. ]
train_input
[[ 32. 340. ]
[ 12.4 13.4]
[ 14.3 19.7]
[ 12.2 12.2]
[ 33. 700. ]
[ 36. 714. ]
[ 35. 720. ]
[ 35. 725. ]
[ 38.5 955. ]
[ 33.5 650. ]
[ 31.5 500. ]
[ 29. 430. ]
[ 41. 950. ]
[ 30. 450. ]
[ 29. 363. ]
[ 29.7 500. ]
[ 11.3 8.7]
[ 11.8 10. ]
[ 13. 12.2]
[ 32. 600. ]
[ 30.7 500. ]
[ 33. 700. ]
[ 35. 700. ]
[ 41. 975. ]
[ 38.5 920. ]
[ 25.4 242. ]
[ 12. 9.8]
[ 39.5 925. ]
[ 29.7 450. ]
[ 37. 1000. ]
[ 31. 500. ]
[ 10.5 7.5]
[ 26.3 290. ]
[ 34. 685. ]
[ 26.5 340. ]]
두 번쨰 머신러닝 프로그램
kn = kn.fit(train_input, train_target)
kn.score(test_input, test_target)
1.0
02-2 데이터 전처리
넘파이로 데이터 쉽게 만들기
# 행방향으로 데이터 넣기 : column_stack, 열방향 - row_stack
np.column_stack(([1,2,3],[4,5,6]))
print(np.column_stack(([1,2,3],[4,5,6])))
fish_data = np.column_stack((fish_length,fish_weight))
print(fish_data)
[[1 4]
[2 5]
[3 6]]
[[ 25.4 242. ]
[ 26.3 290. ]
[ 26.5 340. ]
[ 29. 363. ]
[ 29. 430. ]
[ 29.7 450. ]
[ 29.7 500. ]
[ 30. 390. ]
[ 30. 450. ]
[ 30.7 500. ]
[ 31. 475. ]
[ 31. 500. ]
[ 31.5 500. ]
[ 32. 340. ]
[ 32. 600. ]
[ 32. 600. ]
[ 33. 700. ]
[ 33. 700. ]
[ 33.5 610. ]
[ 33.5 650. ]
[ 34. 575. ]
[ 34. 685. ]
[ 34.5 620. ]
[ 35. 680. ]
[ 35. 700. ]
[ 35. 725. ]
[ 35. 720. ]
[ 36. 714. ]
[ 36. 850. ]
[ 37. 1000. ]
[ 38.5 920. ]
[ 38.5 955. ]
[ 39.5 925. ]
[ 41. 975. ]
[ 41. 950. ]
[ 9.8 6.7]
[ 10.5 7.5]
[ 10.6 7. ]
[ 11. 9.7]
[ 11.2 9.8]
[ 11.3 8.7]
[ 11.8 10. ]
[ 11.8 9.9]
[ 12. 9.8]
[ 12.2 12.2]
[ 12.4 13.4]
[ 13. 12.2]
[ 14.3 19.7]
[ 15. 19.9]]
# 넘파이로 0 과 1 체우기
print('np.ones(5) : ',np.ones(5))
print('np.zeros(5) : ',np.zeros(5))
# 배열 2개를 생성하고 연결하기
print('np.concatenate((np.ones(5),np.zeros(5))) : ',np.concatenate((np.ones(5),np.zeros(5))))
fish_target = np.concatenate((np.ones(35),np.zeros(14)))
print('fish_target : \n',fish_target)
np.ones(5) : [1. 1. 1. 1. 1.]
np.zeros(5) : [0. 0. 0. 0. 0.]
np.concatenate((np.ones(5),np.zeros(5))) : [1. 1. 1. 1. 1. 0. 0. 0. 0. 0.]
fish_target :
[1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.
1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0.]
사이킷런으로 데이터 나누기
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(fish_data, fish_target, stratify = fish_target, random_state = 42)
print(train_input.shape, test_input.shape)
print(train_target.shape, test_target.shape)
print(test_target)
(36, 2) (13, 2)
(36,) (13,)
[0. 0. 1. 0. 1. 0. 1. 1. 1. 1. 1. 1. 1.]
k-최근접 이웃 훈련
from sklearn.neighbors import KNeighborsClassifier
kn = KNeighborsClassifier()
kn.fit(train_input, train_target)
kn.score(test_input, test_target)
1.0
# 길이 25, 무게 150g 도미로 테스트 하기 : 1-도미, 0-빙어
print(kn.predict([[25,150]]))
[0.]
산점도 그리기
import matplotlib.pyplot as plt
plt.scatter(train_input[:,0],train_input[:,1])
plt.scatter(25,150, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
길이 25, 무게 150g 도미가 빙어로 뜨는 이유에 대한 고찰
distances, indexes = kn.kneighbors([[25,150]])
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.xlabel('length')
plt.ylabel('weight')
plt.show()
print(train_input[indexes])
print(train_target[indexes])
print(distances)
[[[ 25.4 242. ]
[ 15. 19.9]
[ 14.3 19.7]
[ 13. 12.2]
[ 12.2 12.2]]]
[[1. 0. 0. 0. 0.]]
[[ 92.00086956 130.48375378 130.73859415 138.32150953 138.39320793]]
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))
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
표준점수로 바꾸기
mean = np.mean(train_input, axis = 0)
std = np.std(train_input, axis = 0)
print(mean, std)
train_scaled = (train_input - mean)/std
[ 27.29722222 454.09722222] [ 9.98244253 323.29893931]
전처리 데이터로 모델 훈련하기
plt.scatter(train_scaled[:,0], train_scaled[:,1])
plt.scatter(25,150, marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
new = ([25,150] - mean)/std
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)
test_scaled = (test_input - mean)/std
kn.score(test_scaled, test_target)
1.0
# 스케일링 이후 이상한 도미 데이터 예측하기
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()