[TIL] 22.11.17

문종현·2022년 11월 17일
0

TIL

목록 보기
41/119
post-custom-banner

👉 오늘 한 일

  • 위클리 키워드 정리

CatBoost란?

💡 "CatBoost is a high-performance open source library for gradient boosting on decision trees."
  • CatBoost는 2017년 Yandex 에서 개발한 범주형 데이터 처리에 특화된 오픈 소스 소프트웨어 라이브러리
  • CatBoost는 GBM의 가장 치명적인 한계점이었던 과적합 문제를 해결함과 동시에 기존 GBM 계열 알고리즘인 XGBoost, LightGBM 의 학습 속도 저하 문제를 개선했다는 장점을 앞세워 현재까지도 현업에서 자주 쓰이는 알고리즘이다.
  • 기존 GBM모델의 Hyper-parameter에 따라 성능이 달라지는 민감한 문제도 함께 개선하였다.
  • jetbrians 사에서는 코드 완성을 위해 사용, cream 사에서 목적지 예측을 위해 사용되고 있으며 cloudflare에서 봇 탐지를 위해서 사용되고 있는 알고리즘이다.

참고자료
CatBoost: unbiased boosting with categorical features
https://arxiv.org/pdf/1706.09516.pdf

Review
[ML] Unbiased boosting : CatBoost

CatBoost의 장점

기존 GBM 알고리즘들의 한계점 극복

  • GBM은 최초의 데이터를 하나 학습할 때만 예측값을 기반으로 하고 그 이후의 데이터를 학습할 때는 예측값을 활용해서 계산한 잔차에만 포커스를 맞추어서 학습시킨다.

  • 잔차에만 포커스를 맞추어 학습하기 때문에, 모델이 본적 없는 데이터에는 예측을 잘 하지 못하는 과적합(Overfitting) 문제를 유발할 가능성이 매우 높다는 치명적인 단점이 존재한다.

  • 이런 기존 GBM알고리즘들의 과적합 문제를 해결함과 동시에 학습 속도 저하 문제까지 개선하여 현업에서 활발하게 사용되고 있는 알고리즘이다.

  • XGBoost보다 예측 속도가 8배 빠르다.

    • 속도가 매우 빨라 실제 상용화된 서비스에 예측 기능 삽입할 때 효과적이다.
    • Overfitting 방지를 위한 내부적인 방법 (random permutation, overfitting detector) 구비하고 있어 속도 뿐 아니라 예측력도 굉장히 높다.
  • 시계열 데이터를 효율적으로 처리한다.

  • 비대칭 데이터도 파라미터 조정(class_weight)을 통해 예측력을 높일 수 있다.

    • 하이퍼 파라미터 튜닝을 알고리즘 내부에서 처리하기 때문에 사용자가 지정해주지 않아도 모델이 잘 돌아간다.
      • 건드려도 상관은 없지만 드라마틱한 결과가 도출되지는 않는다.

Symmetric Tree 구조

Level-wise Tree

  • 직관적으로 말하면 너비 탐색 알고리즘처럼 트리를 옆으로 뻗어내는 형태

  • XGBoost와 같은 Catboost 는 Level-wise 트리 분할 방식을 사용한다.
    • 트리가 나누어지는 Feature들이 대칭인지 여부에 따라 차이점이 드러난다.
      • CatBoost는 Feature를 모두 동일하게 대칭적인 트리 구조를 형성하여 예측 시간을 감소시킬 수 있다.

level - wise 와 leaf - wise의 차이

  • XGBoost 와 catboost는 level-wise tree 인 반면 Light GBM 은 Leaf-wise tree다.

  • Level-wise 와 Leaf-wise 의 차이는, 그냥 직관적으로 말하면 Level-wise 는 BFS 같이 트리를 만들어나가는 형태고, Leaf-wise 는 DFS 같이 트리를 만들어나가는 형태다.

  • 물론 max_depth = -1 이면 둘은 같은 형태지만, 대부분의 부스팅 모델에서의 트리는 max_depth != -1 이기 때문에 이 둘을 구분하는 것이다.

CatBoost 의 기본 알고리즘

Ordered Boosting

  • Catboost 는 기존의 부스팅 과정과 전체적인 양상은 비슷하지만 다르다.
  • 기존의 부스팅 모델이 일괄적으로 모든 훈련 데이터를 대상으로 잔차 계산을 했다면, Catboost 는 일부 데이터 만 가지고 잔차계산을 한 뒤, 이걸로 모델을 만들고, 그 뒤 데이터의 잔차는 이 모델로 예측한 값을 사용한다.
    • 예시 https://k.kakaocdn.net/dn/bT3SYM/btqzeZnOlJa/ZxpuNY6Wc7MK9B8X7N2cJk/img.png
      • 기존의 부스팅 기법은 모든 데이터(x1 ~ x10) 까지의 잔차를 일괄 계산한다.
      • 반면, Catboost 의 과정은 다음과 같다.
        1. 먼저 x1 의 잔차만 계산하고, 이를 기반으로 모델을 만든다.
          → model x1이라 가정
        2. x2 의 잔차를 이 모델로 예측한다.
        3. x1, x2 의 잔차를 가지고 모델을 만든다.
        4. 3을 기반으로 x3, x4 의 잔차를 모델로 예측한다.
        5. x1, x2, x3, x4 를 가지고 모델을 만든다.
        6. 5를 기반으로 x5, x6, z7, x8 의 잔차를 모델로 예측한다.
        7. 1~6번 반복

CatBoost는 일반적인 시계열이 포함되지 않은 데이터라도 CatBoost가 임의적으로 시계열을 형성해 위와 같은 과정으로 Boosting을 진행할 수 있다. 

  • 이렇게 시계열을 형성하고 순서에 따라 모델을 만들어 예측하는 방식**Ordered Boosting** 이라 부른다.

그러나 데이터 포인트마다 학습을 한다고 가정했을 때, 만약 10만개의 데이터가 존재할 경우 10만개의 모델을 학습시켜야만 한다.

이 부분은 연산 비용에 있어서 심각한 문제이기 때문에 보통 이를 해결하기 위해 log개수만큼의 모델을 학습하게 된다.

Random Permutations

  • CatBoost는 주어진 전체 데이터를 임의적으로 N개의 Fold로 나눠 각 Fold에 속한 데이터 셋에 Ordered Boosting을 적용한다. (K-fold Cross Validation 과정과 유사)
    • 예를 들어, 100개의 데이터가 존재할 때, CatBoost는 4개의 Fold로 나누기로 했으면 주어진 데이터셋을 25개씩 나누고 각 25개의 데이터셋 마다 Ordered Boosting을 적용하게 된다.
  • 트리를 다각적으로 만들어 부스팅 계열 알고리즘의 단점이었던 과적합 문제를 해결하는 데 도움이 되었다.

범주형 변수 처리

Ordered Target Encoding

Target Encoding 방법

Target Encoding, Mean Encoding, Response Encoding 이라고 불리우는 기법 (3개 다 같은 말이다.)을 사용한다.

범주형 변수를 수로 인코딩 시키는 방법 중, 비교적 가장 최근에 나온 기법으로, 간단히 말하자면 과거 데이터 포인트만 고려하여 평균값을 계산하는 방법이다.

예시는 아래와 같다.

https://k.kakaocdn.net/dn/cqpaqa/btqzf6zMggo/CttRUX0mk387TZQAGYZ2LK/img.png

위 데이터에서 time, feature1 으로 class_label 을 예측해야한다고 해보자.

feature1 의 cloudy 는 다음과 같이 인코딩 할 수 있다.

cloudy = (15 +14 +20 + 25)/4 = 18.5

즉, cloudy 를 cloudy 를 가진 데이터들의 class_label 의 값의 평균으로 인코딩 하는 것이다.

이 때문에 Mean encoding 이라 불리기도 한다.

Data Leakage 방지

그런데 위는 우리가 예측해야하는 값이 훈련 셋 피처에 들어가버리는 문제, 즉 Data Leakage 문제를 일으킨다.

이는 오버피팅을 일으키는 주 원인이자, Mean encoding 방법 자체의 문제이기도 하다.

그래서, Catboost 는 이에대한 해결책으로, 현재 데이터의 인코딩하기 위해 이전 데이터들의 인코딩된 값을 사용한다.

예를 들면 다음과 같다.

- Friday 에는, cloudy = (15+14)/2 = 15.5 로 인코딩 된다.
- Saturday 에는, cloudy = (15+14+20)/3 = 16.3 로 인코딩 된다.

즉, 현재 데이터의 타겟 값을 사용하지 않고, 이전 데이터들의 타겟 값만을 사용하니, Data Leakage 가 일어나지 않는 것이다.

범주형 변수를 수로 인코딩하는 할 때, 오버피팅도 막고 수치값의 다양성도 만들어 주는 이점이 있다고 볼 수 있다.

Categorical Feauture Combinations

  • CatBoost는 여러 범주 기능을 결합한다.
  • 대부분의 경우 두 가지 범주 기능을 결합하는 것이 좋으며, 결과적으로 가능한 최상의 기능 조합을 찾아 단일 기능으로 간주한다.
  • CatBoost는 이 작업을 자동으로 수행한다.

아래의 예시를 살펴보자.

  • country만 봐도 hair_color feature가 결정되기 때문에, class_label 을 예측하는데 있어 두 Feature 중 하나의 feature 만 있으면 된다.
  • Catboost 는 이렇게 information gain 이 동일한 두 feature 를 하나의 feature 로 묶어버린다. 결과적으로, 데이터 전처리에 있어 feature selection 부담이 조금 줄어든다고 할 수 있다.

One-hot Encoding

  • 기본적으로 CatBoost는 One-hot 인코딩을 사용하여 모든 두 범주 기능을 나타낸다.
  • Catboost 는 낮은 Cardinality 를 가지는 범주형 변수에 한해서, 기본적으로 One-hot encoding 을 시행한다.
    • Cardinality 기준은 one_hot_max_size 파라미터로 설정할 수 있다.
      • 예를 들어 one_hot_max_size = 3 으로 준 경우, Cardinality 가 3이하인 범주형 변수들은 Target Encoding 이 아니라 One-hot 으로 인코딩 된다.
    • Low Cardinality 를 가지는 범주형 변수의 경우 Target Encoding 보다 One-hot 이 더 효율적일 것으로 볼 수 있다.

수치형 변수 처리

Information Gain 기반 트리 분할

  • CatBoost는 다른 트리 알고리즘과 동일한 방식으로 수치 기능을 처리한다.
    • Information Gain을 기반으로 최상의 분할 기준을 선택한다.
    • 분기가 발생하면 정보 획득량을 의미하는 Gain이 높게 나오는 방향대로 나뉘게 된다.

파라미터 튜닝

Optimized Parameter tuning

  • Catboost 는 기본 파라미터가 기본적으로 최적화가 잘 되어있어서, 파라미터 튜닝에 크게 신경쓰지 않아도 된다고 한다.
    • 반면 xgboost 나 light gbm 은 파라미터 튜닝에 매우 민감하다.
  • 사실 대부분 부스팅 모델들이 파라미터를 튜닝하는 이유는, 트리의 다형성과 오버피팅 문제를 해결하기 위함인데, Catboost 는 이를 내부적인 알고리즘으로 해결하고 있으니, 굳이 파라미터 튜닝할 필요가 없는 것이다.
  • 굳이 한다면 learning_rate, random_strength, L2_regulariser 과 같은 파라미터 튜닝인데, 결과는 큰 차이가 없다고 한다.

CatBoosts 모델 구현

CatBoostClassifier

import numpy as np

# CatBoostClassifier, Regressor 패키지도 사용가능하다. 
from catboost import CatBoostClassifier, Pool

# initialize data
X_train = np.random.randint(0, 100, size=(100, 10))

y_train = np.random.randint(0, 2, size=(100))

X_test = catboost_pool = Pool(train_data, train_labels)

model = CatBoostClassifier(iterations=2,
                           depth=2,
                           learning_rate=1,
                           loss_function='Logloss',
                           verbose=True)

# train the model
model.fit(X_train, y_train)

# make the prediction using the resulting model
preds_class = model.predict(X_test)
preds_proba = model.predict_proba(X_test)
print("class = ", preds_class)
# print("proba = ", preds_proba)

  • Catboost모델은 시계열 데이터로 진행할 경우 has_time = True로 파라미터를 셋팅해주어야한다. 그래야 ordered boosting시에 임의로 정한 시간대로 random permutation을 하지 않는다.

.predict()

Classifier, Regressor구분 없이 아래와 같이 .predict()함수를 통해서도 구분이 가능하다.

import numpy as np
from catboost import CatBoost, Pool

# read the dataset
X_train = np.random.randint(0, 100, size=(100, 10))
y_train = np.random.randint(0, 2, size=(100))
X_test = np.random.randint(0, 100, size=(50, 10))
                                
train_pool = Pool(X_train, y_train)
test_pool = Pool(X_test) 

# specify training parameters via map
param = {'iterations':5}
model = CatBoost(param)

#train the model
model.fit(train_pool) 

# make the prediction using the resulting model
preds_class = model.predict(test_pool, prediction_type='Class')
preds_proba = model.predict(test_pool, prediction_type='Probability')
preds_raw_vals = model.predict(test_pool, prediction_type='RawFormulaVal')
print("Class", preds_class)
#print("Proba", preds_proba)
#print("Raw", preds_raw_vals)

CatBoost의 한계

Sparse Matrix의 처리

  • 즉, 결측치가 매우 많은 데이터셋에는 부적합한 모델이다.
  • 예를 들어, 추천시스템에 자주 사용되는 `사용자-아이템 행렬` 데이터를 살펴보면 보통 Sparse한 형태로 이루어져 있다.
  • 만약 이러한 데이터를 활용하려면 Sparse한 특성이 없도록 Embedding을 적용한다던지 등 데이터를 변형한 후 CatBoost에 활용하는 것이 적합할 것이다.

수치형 변수의 처리 속도

  • 수치형 변수가 매우 많은 데이터일 경우 LightGBM 보다 학습 속도가 오래 걸린다는 단점이 있다.
  • 그래서 이름을 정할 때 Cat(egorical) Boost 라는 의미를 담지 않았을까 하는 느낌
profile
자라나라 새싹새싹🌱
post-custom-banner

0개의 댓글