02 - 1. 훈련 세트와 테스트 세트
지도 학습과 비지도 학습
- 머신러닝 알고리즘은 지도 학습과 비지도 학습이 있음
- 지도 학습 알고리즘은 훈련하기 위한 데이터와 정답이 필요함
- 지도 학습에서 데이터와 정답을 입력 + 타깃 = 훈련 데이터라고 부름
- 입력으로 사용된 길이와 무게를 특성이라고 함
- 지도 학습은 정답(타깃)이 있기 때문에 알고리즘이 정답을 맞추는 것을 학습함
- 비지도 학습 알고리즘은 타깃 없이 입력 데이터만 사용
- 테스트 세트는 평가에 사용하는 데이터
- 훈련 세트는 훈련에 사용되는 데이터
코드1 - 도미 데이터와 빙어 데이터를 합쳐 하나의 파이썬 리스트 준비
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]
코드2 - 두 파이썬 리스트를 순회하며 각 생선의 길이와 무게를 하나의 리스트로 담은 2차원 리스트
fish_data = [[l, w] for l, w in zip(fish_length, fish_weight)]
fish_target = [1]*35 + [0]*14
- 이때 하나의 생선 데이터를 샘플이라고 함
- 도미 35마리, 빙어 14마리 = 전체 데이터 49마리
- 사용하는 특성은 길이와 무게 2개
- 이 데이터의 처음 35개를 훈련 세트, 나머지 14개를 테스트 세트로 사용
코드3 - 사이킷런의 KNeighborsClassifier 클래스를 임포트하고 모델 객체를 만듬
from sklearn.neighbors import KNeighborsClassifier
kn = KNeighborsClassifier()
- 전체 데이터에서 처음 35개를 선택해야 함
- 일반적으로 리스트처럼 배열의 소요를 선택 -> 배열의 위치 인덱스를 사용해야 함
코드4 - fish_data의 다섯번째 샘플을 출력
print(fish_data[4]) -> [29.0, 430.0]
- 파이썬 리스트는 인덱스 외에도 슬라이싱이라는 특별한 연산자 제공
- 슬라이싱은 콜론(:)을 가운데 두고 인덱스 범위를 지정해 여러 개의 원소 선택 가능
코드5 - 첫 번째 부터 다섯 번째까지의 샘플을 선택
print(fish_data[0:5]) ->
# [[25.4, 242.0], [26.3, 290.0], [26.5, 340.0], [29.0, 363.0], [29.0, 430.0]]
- 리스트의 리스트로 5개의 샘플이 선택됨
- 슬라이싱을 사용할 때는 마지막 인덱스의 원소는 포함되지 않는다!!
- 0.5와 같이 지정했다면 0~4개 까지의 5개 원소만 선택되고 인덱스 5인 여섯번째 선택은 x
- 만약 0:5와 같이 처음부터 슬라이싱 되는 경우는 0을 생략가능
코드6 - 슬라이싱을 이용해 출력(1)
print(fish_data[:5]) ->
# [[25.4, 242.0], [26.3, 290.0], [26.5, 340.0], [29.0, 363.0], [29.0, 430.0]]
- 이와 비슷하게 마지막 원소까지 포함하면 두 번째 인덱스 생략가능
- 예를 들어 마지막에서 5개의 샘플을 출력할 때 44:49와 같이 쓰지 않고 44: 만 써도 됨
코드7 - 슬라이싱을 이용해 출력(2)
print(fish_data[44:]) ->
# [[12.2, 12.2], [12.4, 13.4], [13.0, 12.2], [14.3, 19.7], [15.0, 19.9]]
- 이를 이용해 생선 데이터 처음 35개와 나머지 14개를 선택 가능o
코드8 - 훈련 세트 출력
# 훈련 세트로 입력 중 0부터 34번째 인덱스까지 사용
train_input = fish_data[:35]
# 훈런 세트로 타깃값 중 0부터 34번쨰 인덱스까지 사용
train_target = fish_target[:35]
# 테스트 세트로 입력값 중 35번째부터 마지막 인덱스까지 사용
test_input = fish_data[35:]
# 테스트 세트로 타깃값 중 35번째부터 마지막 인덱스까지 사용
test_target = fish_target[35:]
- 슬라이싱 연산으로 인덱스 0~34까지 처음 35개 샘플을 훈련 세트로 선택함
- 인덱스 35~48까지 나머지 14개 샘플을 테스트 세트로 선택
코드9 - 훈련 세트로 fit() 메서드를 호출해 모델을 훈련하고 테스트 세트로 score() 메소드 출력
kn = kn.fit(train_input, train_target)
kn.score(test_input, test_target)
-> # 0.0
- 이렇게 나오면 머신러닝 모델이 최악의 성능을 내고 있음
샘플링 편향
- 샘플링 편향은 훈련 세트와 테스트 세트에 샘플이 골고루 섞여 있지 않아 샘플링이 한쪽으로 치우치는 현상
- 훈련하는 데이터와 테스트하는 데이터에는 도미와 빙어가 골고루 섞여 있어야 함
- 해결하는 방법은 훈련 세트와 테스트 세트를 나누기 전에 데이터를 섞거나 골고루 샘플을 뽑아서 만들어야 함
넘파이
- 파이썬의 대표적인 배열 라이브러리
- 파이썬의 리스트로 2차원 리스트를 표현할 수 있지만 고차원 리스트를 표현하려면 번거로움
- 넘파이는 고차원의 배열을 손쉽게 만들고 조작할 수 있는 간편한 도구를 많이 제공함
- 보통의 xy 좌표계와는 달리 시작점이 왼쪽 아래가 아니고 왼쪽 위에서 시작함
- 배열의 시작점을 이렇게 놓으면 편리한 점이 많음
코드 10 - 넘파이 라이브러리 임포트(1)
import numpy as np
- 파이썬 리스트를 넘파이 배열로 바꾸기는 정말 쉬움
- 넘파이 array() 함수에 파이썬 리스트를 전달하면 끝임
코드 11 - 넘파이 라이브러리 임포트(2)
input_arr = np.array(fish_data)
target_arr = np.array(fish_target)
print(input_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]]
- 넘파이는 친절하게 배열의 차원을 구분하기 쉽도록 행과 열을 가지런히 출력함
- 출력 결과에서 49개의 행과 2개의 열을 쉽게 확인 가능함
코드12 - 배열의 크기를 알려주는 shape속성 사용
print(input_arr.shape) -> # 이 명령을 사용하면 (샘플 수, 특성 수)를 출력
# (49, 2)
- 이 배열에서 랜덤하게 샘플을 선택해 훈련 세트와 테스트 세트로 만들 차례
- 여기서는 배열을 섞어 나누는 방식 대신에 무작위로 샘플을 고르는 방법을 택함
- 한가지 주의해야 할 점은 input_arr와 target_arr에서 같은 위치는 함께 선택되어야 함
- 타깃이 샘플과 함께 이동하지 않으면 올바르게 훈련 x
코드12 - 넘파이 arange() 함수를 이용하여 0부터 48까지 증가하는 인덱스(1)
np.random.seed(42)
index = np.arange(49)
np.random.shuffle(index)
- 넘파이 arange() 함수에 정수 N을 전달하면 0에서 부터 N-1까지 1씩 증가하는 배열을 만듬
- 넘파이 random 패키지 아래에 있는 shuffle 함수는 주어진 배열을 무작위로 섞음
코드13 - 넘파이 arange() 함수를 이용하여 0부터 48까지 증가하는 인덱스(2)
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]
- 넘파이는 슬라이싱 외에 배열 인덱싱이란 기능을 제공함
- 배열 인덱싱은 1개의 인덱스가 아닌 여러 개의 인덱스로 한 번에 여러 개의 원소 선택가능
코드14 - input_arr 에서 두번쨰와 네 번째 샘플을 선택하여 출력
print(input_arr[[1, 3]]) -> # [[ 26.3 290. ] [ 29. 363. ]]
코드15 - input_arr와 target_arr에 랜덤하게 훈련 세트 적용(1)
train_input = input_arr[index[:35]]
train_target = target_arr[index[:35]]
- 만들어진 index의 첫 번째 값은 13
- 따라서 train_input의 첫 번째 원소는 input_arr의 열 네번째 원소가 들어 있음
코드16 - input_arr와 target_arr에 랜덤하게 훈련 세트 적용(2)
print(input_arr[13], train_input[0]) -> # [ 32. 340.] [ 32. 340.]
코드17 - 나머지 14개를 테스트 세트로 만듬
test_input = input_arr[index[35:]]
test_target = target_arr[index[35:]]
코드18 - 산점도를 이용한 훈련 세트와 테스트 세트 출력
import matplotlib.pyplot as plt
plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(test_input[:,0], test_input[:,1])
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
두 번째 머신러닝 프로그램
- 훈련 세트와 테스트 세트를 이용해 k- 최근점 이웃 모델을 훈련 시킴
- fit() 메서드를 실행 할 때마다 KNeighborsClassifier 클래스의 객체는 이전에 학습한 모든 것을 잃어버림
- 만약 이 모델을 그대로 두고 싶다면 KNeighborsClassifier 클래스 객체를 새로 만들어야 함
코드19 - kn 객체를 이용한 fit() 메서드 출력(1)
kn = kn.fit(train_input, train_target)
- 인덱스를 섞어 만근 train_input과 train_target으로 모델 훈련 시킴
코드20 - kn 객체를 이용한 fit() 메서드 출력(2)
kn.score(test_input, test_target) -> # 1.0
- 100%의 정확도로 테스트 세트에 있는 모든 생선을 맞춤
코드21 - predict() 메서드를 이용한 예측결과와 실제 타깃 확인
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])
- 테스트 결과에 대한 예측 결과가 일치함
- predict() 메서드의 출력 결과가 test_target의 출력과 동일하게 array()로 감싸 있음
- 이 값은 넘파이 배열을 의미함
코드22 - 최종 코드
"""# 훈련 세트와 테스트 세트"""
"""## 훈련 세트와 테스트 세트"""
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[4])
print(fish_data[0:5])
print(fish_data[:5])
print(fish_data[44:])
# 훈련 세트로 입력 중 0부터 34번째 인덱스까지 사용
train_input = fish_data[:35]
# 훈런 세트로 타깃값 중 0부터 34번쨰 인덱스까지 사용
train_target = fish_target[:35]
# 테스트 세트로 입력값 중 35번째부터 마지막 인덱스까지 사용
test_input = fish_data[35:]
# 테스트 세트로 타깃값 중 35번째부터 마지막 인덱스까지 사용
test_target = fish_target[35:]
kn = kn.fit(train_input, train_target)
kn.score(test_input, test_target)
""" ## 넘파이"""
import numpy as np
input_arr = np.array(fish_data)
target_arr = np.array(fish_target)
print(input_arr)
print(input_arr.shape)
np.random.seed(42)
index = np.arange(49)
np.random.shuffle(index)
print(index)
print(input_arr[[1, 3]])
train_input = input_arr[index[:35]]
train_target = target_arr[index[:35]]
print(input_arr[13], train_input[0])
test_input = input_arr[index[35:]]
test_target = target_arr[index[35:]]
import matplotlib.pyplot as plt
plt.scatter(train_input[:,0], train_input[:,1])
plt.scatter(test_input[:,0], test_input[:,1])
plt.xlabel('length')
plt.ylabel('weight')
plt.show()
"""## 두 번째 머신러닝 프로그램"""
kn = kn.fit(train_input, train_target)
kn.score(test_input, test_target)
kn.predict(test_input)
test_target
'공부 기록일지' 카테고리의 다른 글
유성이의 공부일지(18-1) - 혼자공부하는 머신러닝 + 딥러닝 3장 (0) | 2024.10.11 |
---|---|
유성이의 공부일지(17-2) - 혼자공부하는 머신러닝 + 딥러닝 2장 (0) | 2024.09.21 |
유성이의 공부일지(16) - 혼자공부하는 머신러닝 + 딥러닝 1장 (3) | 2024.08.27 |
유성이의 공부일지(15) - 혼자공부하는 컴퓨터 구조 + 운영체제 15장 (0) | 2024.07.16 |
유성이의 공부일지(14) - 혼자공부하는 컴퓨터 구조 + 운영체제 14장 (0) | 2024.07.15 |