본문 바로가기
머신러닝

X, y 용어 정리 및 머신러닝 지도학습 의 큰 흐름

by 미생22 2023. 1. 12.
728x90

코린이인 저는 보통 분류를 위한 머신러닝 시 코드 흐름은 정해져있기 때문에 그 흐름대로 코드를 짜게 되는데, 그러다보면 함수의 의미와 변수를 나누는 의미에 대해 쉽게 잊어버리게 되는 경향이 있습니다. 따라서 이번에 데이터사이언스 강의를 들으면서 이 변수 X, y가 어떤 의미인지, 왜 나누는지에 대해 제대로 다뤄보겠습니다.

 

1. 머신러닝 용어정리

분류를 위한 머신러닝 코드에서는 대체로 갖고있는 데이터에서 train_test_split 함수를 사용해 X_train, y_train, X_test, y_test으로 나누어 학습 데이터와 테스트 데이터로 나눕니다. 왜 이렇게 X, y로 나누고 train과 test로 나누는 걸까요?

머신러닝을 하다보면 target(label, class 라고도 합니다.)과 feature가 있습니다. target은 예측하려는 목표, 즉 정답입니다. 예를 들어 수많은 iris의 데이터가 있고 iris의 품종에 따라 분류하는 머신러닝을 진행하는 경우, iris의 품종에 해당합니다. 그렇다면 feature는 뭘까요? 데이터에서 target을 제외한 나머지 컬럼에 해당합니다. 즉 데이터의 특징, 속성을 나타내죠. 예를들어 iris 데이터에서 꽃받침 길이와 너비, 꽃잎 길이와 너비에 해당합니다. 그래서 보통 X라고 하면 정답을 제외한 나머지 특성이고 y라고하면 정답컬럼을 말합니다.

  • Target(y) - 예측하려는 목표(class, label)
  • Feature(X) – 정답을 제외한 나머지 칼럼(data in model)

만약 데이터가 선형회귀를 따른다면 아래 식이 성립됩니다.
y = WX+b

2. 머신러닝 지도학습의 분류

먼저 머신러닝의 지도학습은 아래와 같이 크게 분류 알고리즘과 회귀 알고리즘으로 나뉩니다. 분류 알고리즘은 target이 0, 1, 2인 것 처럼 불연속적이면 분류이고, 연속적인 정답이면 회귀로 나뉩니다.

분류에서는 이진분류와 멀티라벨 분류로 나뉘는데, 이진분류는 참/거짓 중 하나를 택하는 것이고, 멀티라벨분류는 이진분류 이외의 즉, 라벨이 여러개 일 때를 나타냅니다.

회귀에서는 로지스틱회귀와 선형회귀로 나뉩니다. 회귀알고리즘은 정답이 연속적이다보니 선을 그어 그래프를 그리게되는데 이 때 곡선이면 로지스틱회귀, 직선이면 선형회귀입니다.

3. 머신러닝의 큰 흐름

위에서 말씀드렸다시피 머신러닝을 위한 코딩에는 흐름이 있습니다. 보통 데이터를 학습용(train)과 검증용(test)으로 분리하고 다음으로 모델을 학습합니다. 학습된 모델을 통해 정답을 잘 맞추는지 예측하는 코드를 한번 더 짜고 정답이 얼마나 맞는지 정확도를 확인하는게 전체적인 프로세스입니다.

 

1. 데이터 세트 분리

2. 모델 학습 (fit)

3. 테스트 데이터 예측 (predict)

4. 정확도 평가

 

3.1 데이터 세트 분리 

데이터를 분리할 때는 train_test_split 함수를 사용해 X_train, y_train, X_test, y_test으로 나눕니다. 즉, 학습데이터(train data)의 feature과 target, 검증데이터(test data)의 feature과 target으로 분리하는 것을 말합니다.

 

아래 꽃받침 길이와 너비, 꽃잎 길이와 너비 그리고 붓꽃(iris)의 품종이 나와있는 예시가 있습니다.

이 문제는 품종을 예측하는게 목표니까 품종 컬럼이 target(class, label)입니다.

iris는 다양한 품종이 있지만, 오늘 다룰 데이터에서는 'setosa' 'versicolor' 'virginica' 세 가지 품종에 대해서 다룬다. 데이터는 다루기 쉽게 int형식의 0, 1, 2로 순서대로 나타냈습니다. 이해를 돕기위해 도표로 10개 데이터만 갖고오겠습니다. 실제로 다룬 데이터는 150개가 됩니다.

iris

우선 위 데이터를 X, y로 나눠줍니다. 다시말해 feature과 label으로 나눕니다. 이해를 돕기 위해 feature과 label로 나타내겠습니다.

feature = iris.drop(['품종'], axis=1)
label = iris['품종']

print 해서 잘 나눠졌는지 확인해주고,

이제 그 유명한 scikit-learn의 train_test_split 함수를 쓰겠습니다.

여기서 참고로 scikit-learn에 대해 간략히 소개하자면, 아래와 같은 특징을 갖고있습니다.

- 머신러닝에서 가장 유명한 라이브러리
- Decision Tree를 가장 간단하게 활용할 수 있는 라이브러리
- 2007년 구글 썸머코드에서 처음 구현되어 2016년쯤부터 대중화됨
 
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

여기서 test_size는 test 데이터로 쓸 데이터의 양입니다. 전체 데이터 중 random하게 30%의 데이터를 test 데이터로 설정합니다. 우선 아래와 같이 30%를 나누고,

Train data

결과적으로 train_test_split 함수를 통해 X_train, X_test, y_train, y_test로 나뉘어졌습니다.

데이터 세트 분리가 끝났습니다.

추가로 잘 나눠졌는지 확인도 해줍니다.

X_train.shape, X_test.shape

(, 4), (3, 4)가 나옵니다. 7:3으로 30%의 test data를 뽑은 것을 확인했습니다.

 

마지막 확인작업으로 test data의 target 비율이 치우쳐져있지 않은지 즉 class별 분포를 확인해줍니다. X_test, y_test 둘 중 하나를 잡고 확인합니다. numpy 모듈의 unique 함수를 써줍니다.

import numpy as np

np.unique(y_test, return_counts=True)

(array([0, 1, 2]), array([ 1, 2, 0], dtype=int64))

라는 결과가 나온다. 이는 품종 0이 1개, 품종 1이 2개, 품종 2가 0개 있다는 뜻입니다.

3.2 모델 학습

이제 위 변수들로 학습을 시켜줍니다. X_train의 정답이 y_train이라고 모델에 학습을 시킵니다. 즉 이런 특징을 가진 것들은 이런 품종이더라 하고 데이터와 정답을 직접 알려줍니다. 이 과정을 모의고사에 비유하곤 합니다.

 

다음으로 train data만으로 Decision Tree 모델을 만들어줍니다. 여기서 Decision Tree는 알고리즘의 하나로 아래와 같은 특징을 갖고있습니다.

- 조건문에 따라 구별하므로 직관적으로 알기 쉬운 알고리즘
- 간결한 코드로 이해하기 쉬움
 
Decision Tree는 max_depth를 요소로 갖고있는데 모델을 단순화 시키기 위해 즉 과적합을 막기 위해 max_depth=2로 설정해보겠습니다. max_depth는 작을수록 정확도가 떨어지는 특성을 갖고있습니다. 주로 최적화되지 않도록 모델의 성능을 제한하는 방법 중 하나로 depth를 조정합니다. 
 
from sklearn.tree import DecisionTreeClassifier

iris_tree = DecisionTreeClassifier(max_depth=2)
iris_tree.fit(X_train, y_train)

 

 

다음으로 decision tree를 확인하면서 특성을 확인해줍니다. figure로 나타내기 때문에 pyplot을 불러옵니다.

import matplotlib.pyplot as plt
from sklearn.tree import plot_tree

plt.figure(figsize=(12, 8))
plot_tree(iris_tree);

train data 120개 중에서 40, 40, 40개로 나뉘어지는지 확인해보겠습니다. setosa는 전부 다 나온 것 같습니다. versicolor는 5개가 빠졌고 다른게 1개 들어왔네요. verginia는 1개가 빠졌고 versicolor 5개가 들어와있네요.

 

3.3 예측

예측으로는 본 시험은 X_train을 학습한 모델에 X_test를 인자로 줘서 정답을 예측하게 합니다.

즉 y_test를 가리고 예측해보라고 시킵니다.

그 다음 예측한 정답과 실제 정답을 비교해 정확도를 측정합니다.

from sklearn.metrics import accuracy_score

y_pred_test = iris_tree.predict(X_test)
accuracy_score(y_test, y_pred_test)

train data의 accuracy도 모델이 잘 만들어졌는지 확인하기 위해 사용해봐도 좋습니다.

X_train, X_test, y_train, y_test = train_test_split(X, y,)

iris_tree = DecisionTreeClassifier(max_depth=2)
iris_tree.fit(X_train, y_train)

y_pred_tr = iris_tree.predict(X_train)
y_pred_test = iris_tree.predict(X_test)

print('Train Acc : ', accuracy_score(y_train, y_pred_tr))
print('Test Acc : ', accuracy_score(y_test, y_pred_test))
아마 train data의 accuracy가 더 높게 나올겁니다. 원래 train 데이터보다 test 데이터의 accuracy가 더 높은 경우는 거의 없으나, iris data의 경우 좀 다르다고 합니다. train data의 accuracy가 높습니다.

 

 

max_depth=2로 설정한 이 코드의 경우, accuracy가 0.95333이 나오면서 과적합이 해소되었지만, decision tree가 작아졌습니다. 궁금한 마음에 max_depth를 설정하지 않아보니, accuracy가 0.99333이 나왔습니다. 이 높은 수치가 과적합인지 정말 높은 정확도를 나타내는지 확인해보겠습니다.

 

 

아래는 max_depth를 설정하지 않았을 때의 decision tree입니다. 이 코드는 train과 test를 합쳐서 본 경우라 150개의 데이터로 확인했습니다.

 

decision tree가 복잡하게 나타나져있습니다. 분류 기준을 한눈에 보기 쉽게 mlxtend 모듈의 plot_decision_region 함수를 사용해보겠습니다.

from mlxtend.plotting import plot_decision_regions

plt.figure(figsize=(14, 8))
plot_decision_regions(X=X_train, y=y_train, clf=iris_tree, legend=2)
#clf는 classification의 약자, legend는 범례 위치
plt.show();
#plot_decision_regions는 지역으로 분류하는 그림을 나타내는 함수, feature가 2개 뿐이라 쉽게 볼 수 있음

이제 분류 기준을 확인해보자면 저 튀어나온 경계면이 눈에 띕니다. 저 부분은 올바른 건가? 과적합이 아닌가? 하는 의문이 생깁니다. 오히려 오류가 날 수 있는 환경으로 보입니다. 복잡한 경계면은 모델의 성능을 결국 나쁘게 만듭니다.
 
그렇다면 먼저 진행한 max_depth=2에서의 훈련데이터에 의한 결정경계를 확인해보겠습니다.
전보다 깔끔해진  decision_region을 발견할 수 있습니다. 물론 더 틀렸지만 복잡하지 않은 것이 (max_depth가 작은 것) train data 기준으로 과적합을 막기위해 좋습니다

 

 

설명은 아래 블로그를 참고했습니다.

 

출처 : https://perconsi.tistory.com/76

 

[머신러닝] fit(X,y)에서 변수 X,y의 의미와 지도학습의 흐름 및 머신러닝 용어정리 (data feature,data cl

안녕하십니까! 너무 오랜만에 글을 써서 조금 반성이 되네요. 이번 시간에는 머신러닝, 딥러닝을 코딩할 때 자꾸 나오는 이 변수 x와 Y가 어떤 의미인지 전달해 드리려고 합니다. 이는 제가 현재

perconsi.tistory.com

 

728x90