상세 컨텐츠

본문 제목

[머신러닝 커닝 페이퍼] train_test_split : random_state는 대체뭐야? 왜 X는 대문자고 y는 소문자야?

프로그래밍/Data&ML

by 척척석사 민준 2022. 11. 29. 01:24

본문

728x90
#학습데이터와 테스트데이터를 분리합니다
#학습데이터 80% 테스트데이터 20%로 설정합니다
#알고리즘별 학습결과를 비교하기 위해 random state를 0으로 설정합니다
from sklearn.model_selection import train_test_split

#분류문제의 경우
X_train, X_test, y_train, y_test = train_test_split(data, data_label, test_size = 0.2, random_state=0)

#회귀문제의 경우
X_train, X_test = train_test_split(data, test_size = 0.2, random_state=0)

코드설명

왜 필요한가?

머신러닝은 컴퓨터한테 기출문제 잔뜩 주고 모의고사를 풀게하는것과 같다.
데이터를 모두 때려박아서 학습을 시키면 컴퓨터 입장에선 이미 풀어본 문제만 시험에 나오는 격이니까 정확도가 100%가 나오게된다. (우린 이걸 과적합이라고 한다)
하지만 머신러닝을 사용하는 이유는 학습정확도 100%에 있는게 아니라 다른 데이터를 넣어도 높은 정확도로 예측해주는 모델을 얻는 것이다. 과적합되지 않은 일반적인 모델이어야 실제 적용했을때 의미있는 결과를 얻을 것이기 때문이다.

데이터셋의 크기가 작거나 편파적으로 답이 분포되어 있으면 (예를 들어 정답이 대부분 4번이면.. 학습데이터랑 테스트데이터를 나눠도 머신러닝 입장에선 그냥 4로 찍어도 정답률이 90%이상 나오게 된다.)
학습데이터와 테스트데이터를 나누는 것으로도 부족해서 K-fold 교차검증이라는 걸 하게 되는데 다른 포스팅에서 설명하겠다.

구체적인 사용방법

맨 위 컨닝페이퍼를 그대로 가져다 쓰면 되지만 설명을 덧붙여보면
일단 분류문제를 위한 학습데이터므로 데이터는 data에 답이 있는 레이블은 data_label 위치에 넣는다.
(데이터는 list도 되고 array도 되고 DataFrame도 된다. 설마 튜플을 넣지는 않겠지..)
train_test_split(data, data_label)
기출문제문제 중에 80% 만 떼서 공부시키고 20%로는 모의고사를 보게하는 것이다.
test_size = 0.2 를 주면 전체데이터 중 20%는 시험을 보겠다는 의미므로 자동으로 전체 데이터의 80%는 학습데이터가 될 것이다.
train_test_split(data, data_label, test_size = 0.2)
train_size = 0.8로 줘도 똑같은 결과가 나온다.
내가 공부하면서 제일 헷갈렸던 random_state!!!
결론만 말하면 random_state에 들어가는 숫자는 아무 의미가 없다. 그냥 모델 학습시킬때 random_state에 들어가는 숫자만 통일시켜주면 된다.
train_test_split(data, data_label, test_size = 0.2, random_state = 0)
dt_clf = DescisionTreeClassifier(random_state = 0)
random_state는 그냥 데이터를 어떤 순서로 섞을까요? 이런 의미이다. 0으로 하면 그냥 원래 데이터 순서대로 가는거고 100으로 하면 100번째 데이터부터 시작해서 섞이는 식이다.
머신러닝 모델을 하나만 사용하는게 아니라 다양한 모델을 사용해서 결과를 비교할 텐데, 이때 학습순서에 따라 성능이 다르게 나올 수 있기 때문에 모델끼리 성능을 비교하기 위해 random_state를 통일 시켜주는 것이다.

scikit learn 홈페이지에서 설명하는 random_state

더보기

Controls the shuffling applied to the data before applying the split. Pass an int for reproducible output across multiple function calls

분할을 적용하기 전에 데이터에 적용되는 셔플링을 제어합니다. 여러 함수에서 사용될 때 동일한 출력을 위해 사용된다.

회귀문제를 위한 학습데이터는 레이블 없이 그냥 데이터만 넣으면 된다.
train_test_split(data, test_size = 0.2, random_state = 0)
왜 그럴까? 분류문제는 데이터를 학습해서 정답 레이블을 맞추는게 목적이었다. (객관식이라고 생각하면 된다)
회귀문제는 어떤 데이터의 값을 예측하는 게 목적이다. 정답이 아니라 추세를 분석한 다음 어떤 값을 얘측하고자 하는 것이다. (쉽게 서술형이라고 생각하자)

출력결과

분류의 경우
X_train, y_train : 학습을 위한 데이터 어레이 (X_train : 학습 데이터, y_train : 학습 데이터의 정답 레이블)
X_test, y_test : 테스트를 위한 데이터 어레이 (X_test: 테스트 데이터, y_test: 테스트 데이터의 정답 레이블)

모델을 학습시킬때는 X_train, y_train을 사용하면 된다.
dt_clf.fit(X_train, y_train)
학습한 모델을 이용해 얘측을 할 때는 X_test를 사용한다.
prediction = dt_clf.predict(X_test)
예측결과와 실제 정답레이블을 비교해 채점을 할때 머신러닝이 내놓은 답인 prediction과 y_test를 사용한다
accuracy = accuracy_score(y_test, prediction)

회귀의 경우
X_train : 학습을 위한 데이터 어레이
X_test : 데스트를 위한 데이터 어레이

항상 궁금했던게 왜 사이킷런에서 X는 대문자를 쓰고 y는 소문자를 쓸까?

<파이썬 라이브러리를 활용한 머신러닝 : 안드레아스 뮐러 지음>에 그 답이 나와있다.

scikit-learn에서 데이터는 대문자 X로 표기하고 레이블은 소문자 y로 표기합니다. 이는 수학에서 함수의 입력을 x, 출력을 y로 나타내는 공식 f(x) = y에서 유래된 것 입니다. 수학의 표기방식을 따르되 데이터는 2차원 배열의 행렬이므로 대문자 X를 타깃은 1차원 배열의 벡터이므로 소문자 y를 사용합니다.

 

728x90

관련글 더보기