본문 바로가기
인공지능 개발하기/Machine Learning

[Tensorflow] 9. Scikit-Learn "train_test_split" 사용해서 데이터 쪼개기

by 선의공 2024. 1. 4.

 
 

안녕하세요. 
오늘은 Scikit Learn 의
train_test_split 함수를 이용해서
데이터를 쪼개보겠습니다.
 

 

일단 사이킷런(Scikit Learn)이 무엇인지 알아야겠죠?
 
 


 

1. Scikit Learn

 
사이킷 런이란
머신러닝을 위한 데이터 전처리 코드가 들어가 있는
python 머신러닝 패키지라고 보시면 됩니다.
 
 
아래 이미지를 보고 좀 더 알아보자면 

이미지 출처: https://casa-de-feel.tistory.com/3
 
머신러닝에 필요한
예제데이터,
피처처리,
데이터 분리, 검증, 파라미터 튜닝,
평가,
머신러닝 알고리즘,
여러 학습 예측에 대한 유틸리티 기능을
지원한다고 합니다.
 
 
저같은 텐린이에게는
정말 유용하고 신기한 패키지입니다..!
 
 
 


 
 
 

2. train_test_split

 
 
위 이미지에서 
scikit learn의 데이터 분리에 대한 모듈이 있었죠?
 
 
이 sklearn.model_selection 안에 있는
train_test_split 이라는 클래스를
import 해서 사용해서 학습데이터와 평가데이터로
분리를 해주겠습니다.
 
 
 
데이터를 학습데이터와 평가데이터로 나누는 이유는
저번 포스팅에서 설명했죠?
https://aigaeddo.tistory.com/10

 

7. 데이터) 데이터 쪼개기 (훈련 데이터, 평가 데이터)

전에 코드들에서는 10개면 10개 전부 모델에 훈련시켰는데요,,, https://aigaeddo.tistory.com/9 6. 데이터) 입출력 데이터 개수 변경 안녕하세요. 학원에서 저는 텐서플로우 기초를 배우고 있습니다. 학습

aigaeddo.tistory.com

근데 이 방식은 오류가 있습니다.
전체데이터 중
앞의 7개를 학습데이터로 (x_train = [1,2,3,4,5,6,7] // y_train = [1,2,3,4,5,6,7]) ,
뒤의 3개를 평가데이터(x_test = [8,9,10]  // y_test = [8,9,10])로 
나눠주어서
학습데이터로는 모델학습,
평가데이터로는 모델의 평가를 해주었는데요
 
여기서 잘못된 점이 있습니다..
바로 학습되지 않은 범위의 데이터로
평가해줬다는거에요.
 
학습 데이터는 1~7까지이고, 평가는 8~10을 해주게 되면서
학습 데이터의 범위 밖의 값을 평가해주는 오류가 생겼습니다.
 
더군다나 1~10까지 넓은 범위를 학습시키면
모델의 신뢰도가 증가하는데
7까지밖에 학습하지 못했어요.
 
그렇다면 해결책은 무엇일까요?
[1,2,3,4,5,6,7,8,9,10] 에서 3개의 평가데이터를 뽑아낼때
1~10 사이의 랜덤값을 뽑아내면 
적합하다고 합니다.
[3,5,8] 을 뽑아서 평가데이터로서 사용하는거죠.
 
그래서 이 함수를 사용해서 쪼개주는겁니다!
 
 
 
함수에 대한 정보는 가장 잘 설명되어 있을 것 같은
Scikit Learn Document를 참고했습니다.
https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html

 

sklearn.model_selection.train_test_split

Examples using sklearn.model_selection.train_test_split: Release Highlights for scikit-learn 0.24 Release Highlights for scikit-learn 0.23 Release Highlights for scikit-learn 0.22 Comparison of Cal...

scikit-learn.org

 
 
텐서플로우와 마찬가지로
오픈소스로 되어있습니다
https://github.com/scikit-learn/scikit-learn/blob/3f89022fa/sklearn/model_selection/_split.py#L2532
(그래서 코드도 까볼 수 있습니다)
 
파라미터 6개를 갖고 있는 함수입니다.

def train_test_split(
    *arrays,  
    test_size=None, 
    train_size=None,
    random_state=None,
    shuffle=True,
    stratify=None,
):

 
각 파라미터를 설명하자면
arrays : 필수 값이네요. 쪼갤 데이터를 입력 받는 파라미터입니다.

팩킹을 해서 값을 받습니다.
 
test_size : 이 함수가 훈련,테스트 데이터를 나눠주죠?
test_size를 얼마나 정할건지 0.0~1.0 사이로 정해줄 수있습니다!
default 값은 0.25네요.
train_size, test_size 둘다 정해주지 않으면 디폴트 값이 설정됩니다.
위 오픈소스에서 디폴트 설정하는 코드도 볼 수 있었네요.

 
train_size: test_size랑 반대입니다. test_size가 0.3이라면 
train_size는 자동으로 0.7이 정해지게 됩니다.
(둘이 합쳐서 1.0이 넘어가면 오류납니다! 하나만 쓰시길 권장)
 
random_state: 설정한 번호의 랜덤값이 추출됩니다.
박스에서 해당 번호의 랜덤값을 꺼낸다고 보시면 됩니다.
(저는 이렇게 이해했네요...힘들었습니다 ㅎㅎ,,)
꺼낸 값은 다시 같은 박스에서 꺼내도 똑같습니다.
설정하지 않으면 랜덤한 값이 계속 나오게 됩니다.
하이퍼 파라미터 튜닝에서 중요한 값입니다.
이 값을 알고 있어야 하니 반드시 설정하고 기억합시다!
 
suffle : 추출 값을 섞냐 안섞냐를 정하는 랜덤 설정입니다.
default값은 True입니다.
 
stratify :  설정을 하면
설정한 타겟의 비율을 
최대한 유치한채로 분류를 해주는 것 같습니다. 
(굉장히 중요한 개념이라는데
아직은 써보지 못했습니다..)
 

리턴값은 리스트네요.그래서 

x_train, x_test, y_train, y_test 형태로 받을 수 있습니다.

    return list(
        chain.from_iterable(
            (_safe_indexing(a, train), _safe_indexing(a, test)) for a in arrays
        )
    )

 
 
 
코드에 적용시킨 사용법은 아래와 같습니다.
저는 train_size = 0.7, test_size는 안줘도 됐었지만 줘봤습니다!
suffle을 해서 랜덤을 설정했구요.(안줘도 디폴트기는 합니다.)
random_state 1500을 줬습니다.
그럼 1500번을 가진 박스에 담긴 랜덤값을 가져오게 됩니다.
random_state의 범위를 알고 싶어서 
찾아보니 약 42억 9천만개의 값이 있더라구요..ㅎㅎ 
좋은 모델 결과가 나왔을때 이 값을 까먹으면 안됩니다...
 
아 리턴값 설명을 안했네요.
list로 x train, x test , y train, y test의
값을 리턴해줍니다!

# 1. 데이터
x = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
y = np.array([1, 2, 3, 4, 6, 5, 7, 8, 9, 10])

x_train, x_test, y_train, y_test = train_test_split(
    x,
    y,
    train_size= 0.7,
    test_size=0.3,
    shuffle=True,
    random_state=1500
)

 

쪼개진 값은 랜덤으로
train 에 7 개 test에 3개가 담기겠네요.
train : [1,3,4,6,7,8,10]
test:[2,5,9]
이런식으로요

 

 
전체 코드는 아래와 같습니다!

#데이터 전처리
x_train, x_test, y_train, y_test = train_test_split(
    x,
    y,
    train_size= 0.7,
    test_size=0.3,
    shuffle=True,
    random_state=1500
)

#모델구성
model = Sequential()
model.add(Dense(1, input_dim = 1))
model.add(Dense(5))
model.add(Dense(1))

#컴파일, 훈련
model.compile(loss='mse', optimizer='adam')
model.fit(x_train, y_train, epochs=500 , batch_size=1)

#평가 , 예측
loss = model.evaluate(x_test, y_test)
result = model.predict([11])

print("loss 값: ", loss)
print("예측 값: ", result)