Post

머신러닝 4: 혼공머신 5장

5장: 트리 알고리즘

결정 트리

  • 예 / 아니오에 대한 질문을 이어나가면서 정답을 찾아 학습하는 알고리즘이다

    photo 1

결정 트리로지스틱 회귀
이유를 설명하기 쉽다결과를 설명하기 어렵다
  • 사이킷런의 DecisionTreeClassifier 클래스를 사용하여 결정 트리 모델을 수립할 수 있다.
1
2
3
4
5
6
7
from sklearn.tree import DecisionTreeClassifier

dt = DecisionTreeClassifier(random_state=42)
dt.fit(train_scaled, train_target)

print(dt.score(train_scaled, train_target))
print(dt.score(test_scaled, test_target))
  • plot_tree() 함수를 이용하여 결정 트리를 이해하기 쉬운 트리 그림으로 볼 수 있다.

    1
    2
    3
    4
    5
    6
    
      import matplotlib.pyplot as plt
      from sklearn.tree import plot_tree
    	
      plt.figure(figsize=(10,7))
      plot_tree(dt)
      plt.show()
    

    photo 2

    • 위 그림에서 맨 위의 노드를 루트 노드라고 부르고 맨 아래 끝에 달린 노드를 리프 노드라고 부른다.
      • 노드란: 훈련 데이터의 특성에 대한 테스트를 표현한다.
      • 가지(branch)는 테스트의 결과(True/False)를 나타내며 일반적으로 하나의 노드는 2개의 가지를 가진다.
    • 매개변수:
      • max_depth: 루트 노드를 제외하고 몇 개의 노드를 더 확장하여 그린다
      • filled: 클래스에 맞게 노드의 색을 칠할 수 있다
      • feature_names: 특성의 이름을 전달한다

        1
        2
        3
        
          plt.figure(figsize=(10,7))
          plot_tree(dt, max_depth=1, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
          plt.show()
        
    • 결정 트리 그림을 읽는 방법:

      photo 3

      • 결정 트리 모델은 어떤 샘플이 테스트 조건을 만족시키는지 판단하여 분류한다.

        불순도 (Impurity)

  • criterion 매개변수: 노드에서 데이터를 분할할 기준을 정하는 것
  • 지니 불순도
    • 기본적으로 criterion 매개변수가 ‘gini’로 지정한다 \(\text{지니 불순도} = 1 - (\text{음서 클래스 비율}^2 + \text{양성 클래스 비율}^2)\)
  • 정보 이득(information gain)이란: 결정 트리 모델은 부모 노드 (parent node)와 자식 노드(child node)의 불순도 차이가 가능한 크도록 트리를 성장시킨다. \(\text{부모의 불손도} - \frac{\text{왼쪽 노드 샘플 수}}{\text{부모의 샘플 수}} \times \text{왼쪽 노드 불순도} - \frac{\text{오른쪽 노드 샘플 수}}{\text{부모의 샘플 수}} \times \text{오른쪽 노드 불순도}\)
  • 엔트로피 불순도
    • criteron = 'entropy'로 지정한다
    • 지니 불순도와 달라 제곱을 사용하는 대신에 밑이 2인 로그를 사용하여 곱한다. \(-\text{음성 클래스 비율} \times \log_2{(\text{음성 클래스 비율})} - \text{양성 클래스 비율} \times \log_2{(\text{양성 클래스 비율})}\)

가지치기

  • 과대적합을 피하기 위한 과정
  • DecisionTreeClassifier 클래스에 있는 max_depth 매개변수를 이용하여 최대 깊이를 지정할 수 있다.
1
dt = DecisionTreeClassifier(max_depth=3, random_state=42)

특성 중요도

  • 결정 트리에 사용된 특성이 불순도를 감소하는데 기여한 정도를 나타내는 값이다
  • feature_imporances_ 속성을 이용하여 특성 중요도를 볼 수 있다.
1
dt.feature_importances_

교차 검증과 그리드 서치

검증 세트

  • 테스트 세트를 사용하지 않고 모델이 과대적합인지 과소적합인지 측정하기를 위하여 훈련 세트를 또 나눈다.

    photo 4

  • 훈련 세트에서 모델을 훈련하고 검증 세트로 모델을 평가한다
    • 이런 식으로 테스트하고 싶은 매개변수를 바꿔가며 가장 좋은 모델을 고른다
      • 이 매개변수를 이용하여 훈련세트 와 검증 세트를 합쳐 전체 훈련 데이터에서 모델을 다시 훈련하고 마지막에 테스트 세트에서 최종 점수를 평가한다
  • 이전처럼 train_test_split() 함수를 이용하여 전체 데이터를 훈련 세트와 테스트 세트로 나누고 그 함수를 이용하여 훈련 세트를 또 훈련 세트와 검증 세트로 나눈다.
1
2
3
train_input, test_input, train_target, test_target = train_test_split(data, target, test_size=0.2, random_state=42)

sub_input, val_input, sub_target, val_target = train_test_split(train_input, train_target, test_size=0.2, random_state=42)

교차 검증

  • 검증 세트를 만드느라 후련 세트가 줄었는 탓에 어누 조금 떼어 놓으면 불안정할 수도 있으므로 교차 검증(cross validation을 이용하여 안정적인 검증 점수를 얻을 수 있도 훈련에 더 많은 데이터를 사용할 수 있다.

    photo 5

  • 훈련 세트를 k 부분으로 나눠서 교차 검증을 수행하는 것을 k-폴드 교차 검증(k-fold cross validation)이라고 한다
    • 보통 5-폴드 교차 검증이나 10-폴드 교차 검증을 많이 사용한다.
  • 사이킷런에 있는 cross_validate() 함수를 이용하여 교차 검증을 수행할 수 있다
1
2
from sklearn.model_selection import cross_validate
scores = cross_validate(dt, train_input, train_target)
  • 이 함수는 fit_time, score_time, test_score 키를 가진 딕셔너리를 반환한다
    • fit_time: 모델을 훈련하는 시간
    • score_time: 검증하는 시간
    • test_score: 교차 검증의 최종 점수
  • 기본적으로 5-폴드 검증을 수행하는데 cv 매개변수를 이용하 폴드 수를 바꿀 수도 있다
  • cross_validate()는 훈련 세트를 섞어 폴드를 나누지 않은데 먼저 train_test_split() 함수로 전체 데이터를 섞어 훈련 세트를 준비했으니 따로 섞을 필요가 없다
    • 교차 검증을 수행할 때 훈련 세트를 섞으려면 분할기(splitter)를 지정해야 된다
    • 기본적으로 회귀 모델일 경우 KFold 분할기를 사용하고 분류 모델일 경우 타깃 클래스를 골고루 나누기 위하여 StratifiedKFold를 사용한다
    1
    2
    
    from sklearn.model_selection import StratifiedKFold
    scores = cross_validate(dt, train_input, train_target, cv=StratifiedKFold())
    
    • 만약 훈련 세트를 섞은 후 10-폴드 교차 수행하려면 (KFold도 동일한 방식으로 사용한다):
1
2
splitter = StratifiedKFold(n_splits=10, shuffle=True, random_state=42) # n_splits 매개변수는 k 값을 지정
scores = cross_validate(dt, train_input, train_target, cv=splitter)

하이퍼파라미터 튜닝

  • 검증 세트의 점수나 교차 검증을 통해서 매개변수를 조금씩 바꾼다
  • 그리드 서치를 이용하여 어떤 모델에 대한 매개변수들의 최적값을 찾을 수 있다
  • 사이킷런에 GridSearchCV 클래스를 이용할 수 있다
1
2
3
4
from sklearn.model_selection import GridSearchCV
params = {'min_impurity_decrease': [0.0001, 0.0002, 0.0003, 0.0004, 0.0005]} # 0.0001qnxj 0.0005 0.0001씩 증가하는 5대의 값을 시도

gs = GridSearchCV(DecisionTreeClassier(random_state=42), params, n_jobs=-1)
  • best_params_ 속성을 이용하여 최적의 매개변수를 알아볼 수 있다

    랜덤 서치

  • 또 너무 많은 매개변수 조건이 있으면 그리드 서티 수행 시간이 오래 걸릴 수 있으므로 이 경우에는 랜덤 서치를 사용하면 좋다
  • 매개변수 값의 목록을 전달하는 것이 아니라 매개변수를 샘플링할 수 있는 확률 분포 객체를 전달한다
1
2
3
4
5
6
7
from scipy.stats import uniform, randint # uniform은 실숫값을 뽑고 randint는 정숫값을 뽑는다

# 0에서 10 사이의 범위를 갖는 randint 객체를 만들고 10개의숫자를 샘플링한다
rgen = randint(0, 10) 
rgen.rvs(10)

# uniform 생성 방법 똑같다

트리 앙상블

정형 데이터와 비정형 데이터

  • 정형 데이터(structured data)이란: 어떤 구조로 되어 있다
    • CSV, 데이터베이스, 엑셀
  • 비정형 데이터(unstructured data): 데이터베이스나 엑셀로 표현하기 어렵다
    • 책의 글, 텍스트 데이터, 기지털카메라로 찍은 사진, 등
    • 신경망 알고리즘을 이용하여 학습
  • 앙상블 학습: 정형 데이터를 다루는 데 가장 뛰어난 성과를 내는 알고리즘

랜덤 포레스트

  • 결정 트리를 랜덤하게 만들어 결정 트리의 숲을 만든다
  • 부트스트랩 샘플: n 개 샘플에서 k 개씩 샘플을 뽑는다

    photo 6

  • 사이킷런에 있는 RandomForestClassifier 클래스를 이용하여 랜덤 포레스트를 수행할 수 있다
1
2
from sklearn.ensemle import RandomForestClassifier
rf = RandomForestClassifier(n_jobs=-1, random_state=42)
  • oob_score 매개변수를 이용하여 자체적으로 모델을 평가하는 점수를 얻을 수 있다
1
2
3
rf = RandomForestClassifier(oob_score=True, n_jobs=-1, random_state=42)
rf.fit(train_input, train_target)
print(rf.oob_score_)

엑스트라 트리

  • 랜덤 포레스트와 매우 비숫하게 동작하는데 랜덤포레스트와 달라 부트스트랩 샘플을 사용하지 않는다
1
2
from sklearn.ensemble import ExtraTreesClassifier
et = ExtraTreesClassifier(n_jobs=-1, random_state=42)

그레이디언트 부스팅

  • 깊이가 얕은 결정 트리를 사용하여 이전 트리의 오차를 보완하는 방식으로 앙상블 하는 방법이다
    • 과대적합에 강하고 일반적으로 높은 일반화 성능을 기대할 수 있다
1
2
from sklearn.ensemble import GradientBoostingClassifier
gb = GradientBoostingClassifier(random_state=42)
  • 학습률을 증가시키고 트리의 개수를 늘리면 조금 더 성능이 향상될 수 있다
1
gb = GradientBoostingClassifier(n_estimators=500, learning_rate=0.2, random_state=42)

히스토그램 기반 그레이디언트 부스팅

  • 그레이디언트 부스팅의 속도를 개선한 것이며 안정적인 결과와 높은 성능으로 매우 인기가 높다
1
2
3
from sklearn.experimental import enable_hist_gradient_boosing
from sklearn.ensemble import HistGradientBoostingClassifier
hbg = HistGradientBoostingClassifier(random_state=42)
  • 사이킷런 말고 히스토그램 기반 그레이디언트 부스팅 알고리즘을 구현한 대표적인 라이브러리는 XGBoost이다.
1
2
from xgboost import XGBClassifier
xgb = XGBClassifier(tree_method='hist', random_state=42)
This post is licensed under CC BY 4.0 by the author.

Trending Tags