Programming/Python

[ML] 기본 데이터 정리 및 split (iris 예제)

HTleaf 2023. 9. 6. 12:10

 

검증데이터(validation data)로 모델 적합성 따짐. 훈련 검증을 나누고 테스트를 진행하는게 안정적이다.

머신러닝 모델을 학습하고 그 결과를 검증하기 위해서는 원래의 데이터를 Training, Validation, Testing의 용도로 나누어 다뤄야 한다. 그렇지 않고 Training에 사용한 데이터를 검증용으로 사용하면 시험문제를 알고 있는 상태에서 공부를 하고 그 지식을 바탕으로 시험을 치루는 꼴이므로 제대로 된 검증이 이루어지지 않기 때문이다.

딥러닝을 제외하고도 다양한 기계학습과 데이터 분석 툴을 제공하는 scikit-learn 패키지 중 model_selection에는 데이터 분할을 위한 train_test_split 함수가 들어있다.

 

 

 

import seaborn as sd
import pandas as pd

iris = sd.load_dataset('iris')   # 샘플 데이터 부르기
X = iris.drop('species', axis=1)
y = iris['species']       # 머신러닝위해 x와 y벡터 설정

iris['species'].value_counts()   # 데이터 종 개수 세기

setosa        50
versicolor    50
virginica     50
Name: species, dtype: int64

 

 

 

from sklearn.preprocessing import LabelEncoder

LabelEncoder: label(text)값을 code(숫자)로 변환하는 것. species 칼럼의 각종 이름을 숫자로 변환하기 위함이다!

 

encoder = LabelEncoder()   # 함수 객체화
y = encoder.fit_transform(y)  # 학습 (fit)
y

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 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, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])

 

각 이름이 labelencoder()를 통해 숫자로 변환되었다.

 

 

 

from sklearn.model_selection import train_test_split #split module 도입
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state=25)
# split module 적용(단순 쪼개기함수)           test_size = 0.2 의미는 8:2로 나누라는 의미
# random_state = 25번의 규칙에 따라 해라. 숫자는 의미없지만 지정을 해야 일관성을 타인과 공유 可

print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)

(120, 4) (30, 4) (120,) (30,)

 

데이터들이 8:2비율로 나눠졌다

split함수에 data 입력 순서는 data -> target 순이다. (코드 참조)

test_size = 0.2: 전체 데이터 셋의 20%를 test (validation) set으로 지정 의미. default 값은 0.25.

 

 

pd.Series(y_train).value_counts()

2    42
0    41
1    37
dtype: int64

 

그런데 이 방법보다는 stratify 사용을 권장한다. (개수가 제각각으로 random하게 split됨)

 

 

 

 

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, shuffle=True, 
                                                    stratify=y, random_state=25)
# shuffle: 데이터를 섞는 방식. default나 생략시 true로 인지. 보통 default로 둠

즉 split할때 원본 데이터 비율을 유지해서 나누도록 stratify가 역할한다.

pd.Series(y_train).value_counts()

1    40
0    40
2    40
dtype: int64

 

보다시피 1, 0, 2가 stratify를 통해 균등하게 split한다. (개수가 딱 안맞으면 알아서 임의 지정됨)

원본 데이터 비율을 맞춰서 나누는 것도 해당된다.

 

 

 

 

y_train

array([1, 0, 1, 2, 0, 0, 0, 0, 1, 0, 0, 1, 2, 1, 0, 1, 2, 2, 0, 0, 0, 0,
       1, 2, 1, 1, 1, 1, 1, 0, 1, 0, 2, 0, 1, 0, 2, 1, 0, 1, 1, 1, 1, 2,
       2, 1, 0, 0, 0, 2, 2, 0, 2, 1, 2, 0, 0, 1, 1, 2, 0, 2, 2, 1, 0, 0,
       2, 2, 0, 2, 1, 1, 1, 1, 2, 1, 2, 0, 2, 2, 2, 0, 2, 0, 2, 2, 1, 2,
       0, 2, 1, 1, 2, 1, 1, 0, 1, 0, 1, 2, 2, 2, 0, 1, 0, 0, 0, 0, 2, 2,
       2, 1, 2, 1, 2, 1, 2, 2, 0, 0])

 

 

 

 

왜 split해야하는가? (블로그펌)

 

 

머신러닝 모델에 train 데이터를 100% 학습시킨 후 test 데이터에 모델을 적용했을 때 성능이 생각보다 않 나오는 경우가 많습니다 (거의 99.999% 는요)

이러한 현상을 보통 Overfitting(과적합) 되었다라고 합니다.

즉, 모델이 내가 가진 학습 데이터에 너무 과적합되도록 학습한 나머지, 이를 조금이라도 벗어난 케이스에 대해서는 예측율이 현저히 떨어지기 때문이라고 이해하시면 됩니다. 그렇기 때문에 Overfitting을 방지하는 것은 전체적인 모델 성능을 따져보았을 때 매우 중요한 프로세스 중 하나입니다.

Validation Set으로 검증 단계를 추가하여 Overfitting 방지

위의 그림과 같이 기존 train / test로 구분 되어 있었던 데이터 셋을 train에서 train / validation으로 일정 비율 쪼갠 다음에 학습 시에는 train 셋으로 학습 후 중간중간 validation 셋으로 내가 학습한 모델 평가를 해주는 것입니다.

만약, 모델이 과적합되었다면, validation 셋으로 검증시 예측율이나 오차율이 떨어지는 현상을 확인할 수 있으며, 이런 현상이 나타나면 학습을 종료합니다.

 

 

 

결론: split 함수로 train set과 validation set로 나눔

 

 

 

 

 

 

 

 

 

 

 

 

728x90
반응형