참고자료
CatBoost: unbiased boosting with categorical features
https://arxiv.org/pdf/1706.09516.pdf
기존 GBM 알고리즘들의 한계점 극복
GBM은 최초의 데이터를 하나 학습할 때만 예측값을 기반으로 하고 그 이후의 데이터를 학습할 때는 예측값을 활용해서 계산한 잔차
에만 포커스를 맞추어서 학습시킨다.
잔차에만 포커스를 맞추어 학습하기 때문에, 모델이 본적 없는 데이터
에는 예측을 잘 하지 못하는 과적합(Overfitting) 문제를 유발할 가능성이 매우 높다는 치명적인 단점이 존재한다.
이런 기존 GBM알고리즘들의 과적합 문제를 해결함과 동시에 학습 속도 저하 문제까지 개선하여 현업에서 활발하게 사용되고 있는 알고리즘이다.
XGBoost보다 예측 속도가 8배 빠르다.
시계열 데이터를 효율적으로 처리한다.
비대칭 데이터도 파라미터 조정(class_weight)을 통해 예측력을 높일 수 있다.
대칭
인지 여부에 따라 차이점이 드러난다.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
이기 때문에 이 둘을 구분하는 것이다.
일부 데이터
만 가지고 잔차계산을 한 뒤, 이걸로 모델을 만들고, 그 뒤 데이터의 잔차는 이 모델로 예측한 값을 사용한다.
- 먼저 x1 의 잔차만 계산하고, 이를 기반으로 모델을 만든다.
→ model x1이라 가정- x2 의 잔차를 이 모델로 예측한다.
- x1, x2 의 잔차를 가지고 모델을 만든다.
- 3을 기반으로 x3, x4 의 잔차를 모델로 예측한다.
- x1, x2, x3, x4 를 가지고 모델을 만든다.
- 5를 기반으로 x5, x6, z7, x8 의 잔차를 모델로 예측한다.
- 1~6번 반복
CatBoost는 일반적인 시계열이 포함되지 않은 데이터라도 CatBoost가 임의적으로 시계열을 형성해 위와 같은 과정으로 Boosting을 진행할 수 있다.
**Ordered Boosting**
이라 부른다.그러나 데이터 포인트마다 학습을 한다고 가정했을 때, 만약 10만개의 데이터가 존재할 경우 10만개의 모델을 학습시켜야만 한다.
이 부분은 연산 비용에 있어서 심각한 문제이기 때문에 보통 이를 해결하기 위해 log개수만큼의 모델을 학습하게 된다.
Target Encoding 방법
Target Encoding,
Mean Encoding,
Response Encoding
이라고 불리우는 기법 (3개 다 같은 말이다.)을 사용한다.
범주형 변수를 수로 인코딩 시키는 방법 중, 비교적 가장 최근에 나온 기법으로, 간단히 말하자면 과거 데이터 포인트만 고려하여 평균값을 계산하는 방법이다.
예시는 아래와 같다.
위 데이터에서 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 가 일어나지 않는 것이다.
범주형 변수를 수로 인코딩하는 할 때, 오버피팅도 막고 수치값의 다양성도 만들어 주는 이점이 있다고 볼 수 있다.
아래의 예시를 살펴보자.
one_hot_max_size
파라미터로 설정할 수 있다.Gain
이 높게 나오는 방향대로 나뉘게 된다.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)
.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)