AI 기술 및 트렌드

맨 처음 돌려보는 AI 모델, 간편한 python xgboost (GBM개선모델) 는 어떠신가요?

작동미학 2021. 1. 7. 01:34
반응형

 머신러닝 모델 이야기를 풀어나가는 것은 어렵다. 왜냐하면 너무나 종류가 많고, 그 이론적인 배경을 모르면 실수하기 쉽고 데이터의 유형에 따라 추천이 거짓말이 되는 경우도 잦다. 이러한 어려움은 학습 시에 적용되는 다양한 random효과와 결합되어 무언가 알 수 없게 되는 상황도 많다고 생각한다.

 

 딥러닝은 최근 수년간 엄청난 성공을 거둔 방법이다. 그러면 딥러닝을 써보면 어떻겠는가? 하지만 딥러닝이 잘 작동하는 분야도 어찌 보면 특정 분야나 상황으로 제약되어 있다. 이미지, 자연어 처리 분야에서 대량의 데이터로 학습한다는 공통점이 있고, 해당 데이터에 따라 벌써 세부적인 모델들이 잘 정의되어 있지 않은가. 이미지 인식의 CNN(Convolutional Neural Network)의 여러 유형들이 그렇다. 의외로 여러가지 문제를 풀기도 하지만 여하튼 이미지 인식에 특화되어 있다. 그래서 어느 문제이든 딥러닝을 사용하기 위해 무턱대고 deep한 신경망을 구성하는 것도 답이 아니다. 

 

 그러나 우리가 다룰 기업의 데이터는 이렇게 잘 알려진 데이터 유형에 잘 들어맞지 않는 경우가 흔하다(여기서는 feature vector와 label로 결합된 csv를 상상해보자). 딥러닝이 기존에 풀기 어려운 몇몇 문제를 해결하고 있기는 하지만 데이터가 충분할 때만 그렇고, 역시 그 위상에 맞게 오래걸리기가 쉽다.

 

 그런 상황에서 발견하게 된 녀석이 바로 이 xgboost이다. Gradient Boosting Model(GBM)의 계량형 라이브러리라고 생각하면 된다(XGBoost:eXtreme Gradient Boosting). 다만, 여기서는 따로 이 모델에 대해서는 설명하지 않는다(대략 decision tree기법을 여러가지 합성해 boosting해서 만든 모델이라는 정도로 넘어가 보자. 그런데 이 라이브러리 실행의 간결함과 단순함, 속도에 비해서는 전반적으로 괜찮은 결과를 알려준다. 즉, 초기에 아무 부담없이 구동해볼 모델로 써볼 수 있다는 큰 장점이 있다. 쉬운 설치와 짧은 코드는 축복이다. 거기다가 feature vector의 각 컬럼별로 중요도(importance)라는 것을 구해 어느것이 더 중요한 인자인지 알아낼 수 있다.

 

xgboost + scikit learn 으로 해보는 quick 머신러닝 모델

 이 모델은 초기 데이터 탐색시에 고성능 머신러닝 모델을 시험하는데 불필요하게 오랜 시간을 소모하는 경우를 방지하는 목적이 가장 크다. 나를 믿으라. 여러가지 시간을 절약하기 위해서 데이터를 가공해 feature data를 얻어지면 곧바로 무난한 모델을 우선 돌려볼 필요가 있는데, 그때 써볼 첫 모델로 이 xgboost만 한 것이 없었다. 더군다나 유명한 Kaggle에서 상위 랭커들도 곧잘 쓰는 모델로 알려져있다. 가성비는 단연 최고라고 생각한다.

 

1) 샘플 데이터를 train/test로 나누고 학습시켜 간단히 test set 정확도를 얻어보자.

 

레퍼런스는 아래와 같다. 코드도 짧다. xgboost와 scikit learn 패키지 정도는 설치되어 있어야 하는데,

 

$ sudo - root

$ pip3 install xgboost  (python 3.5~3.6 버전에서 시험되었다)

 

위 명령으로 설치가 안된다면, 아래 레퍼런스 전반부를 참조한다.

machinelearningmastery.com/develop-first-xgboost-model-python-scikit-learn/

 

How to Develop Your First XGBoost Model in Python with scikit-learn

XGBoost is an implementation of gradient boosted decision trees designed for speed and performance that is dominative competitive machine learning. In this post you will discover how you can install and create your first XGBoost model in Python. After rea

machinelearningmastery.com

사용하는 샘플 데이터는 간단해서, 8 차원으로 된 숫자 벡터와 0과 1로 분류되는 한자리의 label로 된 데이터이다.

raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv

 

대략 이렇게 생겼다. feature의 맨 마지막 숫자가 label 컬럼이다.

 

$ more pima-indians-diabetes.csv

6,148,72,35,0,33.6,0.627,50,1
1,85,66,29,0,26.6,0.351,31,0
8,183,64,0,0,23.3,0.672,32,1

...

 

상기 레퍼런스에서 제시된 분석 코드는 아래와 같다(python3.5 이상 기반하에 xgboost 패키지 등을 설치해둔다)

 

xgboost_example.py
0.00MB

$ more xgboost_example.py

# First XGBoost model for Pima Indians dataset
# from https://machinelearningmastery.com/develop-first-xgboost-model-python-scikit-learn/
# csv file : https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv
 
from numpy import loadtxt
from xgboost import XGBClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
# load data
dataset = loadtxt('pima-indians-diabetes.csv', delimiter=",")
# split data into X and y
X = dataset[:,0:8]
Y = dataset[:,8]
# split data into train and test sets
seed = 7
test_size = 0.33
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)
# fit model no training data
model = XGBClassifier()
model.fit(X_train, y_train)
# make predictions for test data
y_pred = model.predict(X_test)
predictions = [round(value) for value in y_pred]
# evaluate predictions
accuracy = accuracy_score(y_test, predictions)
print("Accuracy: %.2f%%" % (accuracy * 100.0))

 

상기 파일을 저장 후 실행해보면 Accuracy를 얻을 수 있다.

 

$ python3 xgboost_example.py

Accuracy: 74.02%

 

2) 조금더 실제 상황에 맞게 validation file을 넣어서도 할 수 있도록 해보자.

다만 실제 과제에서의 데이터 구분은 잘 알려져있다시피, 학습/테스트용 데이터 한 셋과, 나중에 최종 검증(validation)용 별도의 데이터 한 셋을 상정하기 때문에 조금 더 일반화하여 재작성한 파일은 아래와 같다.

xgboost_general.py
0.00MB

$ more xgboost_general.py

# csv file : https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv
 
import numpy as np
import pandas as pd
from xgboost import XGBClassifier
 
import sys
from sklearn.preprocessing import OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
 
seed = 7
 
df_t = pd.read_csv('./pima-indians-diabetes.csv', header=None)
df = df_t.astype(np.float32)
del df_t
 
df_X = df.iloc[:,0:8].values
df_Y = df.iloc[:,8:9].values
del df
 
train_dataset, test_dataset, train_labels, test_labels = train_test_split(df_X, df_Y, shuffle = True, test_size = 0.3, random_state=seed)
 
nTrain = train_dataset.shape[0]
nTest = test_dataset.shape[0]
 
print ("Shape of (X_train, Y_train, X_test, Y_test)")
print (train_dataset.shape, train_labels.shape, test_dataset.shape, test_labels.shape)
 
# input data
df_t = pd.read_csv('./pima-indians-diabetes-valid.csv', header=None)
df = df_t.astype(np.float32)
del df_t
 
valid_dataset = df.iloc[:,0:8].values
valid_labels = df.iloc[:,8:9].values
del df
 
model = XGBClassifier(learning_rate=0.005)
print (model)
 
model.fit(train_dataset, train_labels.ravel())
 
# make prediction for test data
y_pred = model.predict(test_dataset)
predictions = [round(value) for value in y_pred]
 
# evaluate predictions
accuracy = accuracy_score(test_labels.ravel(), predictions)
print("Test Accuracy :%.5f%%" % (accuracy * 100.0))
 
# make prediction for validation data
y_pred = model.predict(valid_dataset)
predictions = [round(value) for value in y_pred]
 
# evaluate predictions
accuracy = accuracy_score(valid_labels.ravel(), predictions)
print("Valid Accuracy :%.5f%%" % (accuracy * 100.0))

 

해당 script에서는 pima-indians-diabetes-valid.csv라는 validation file을 요구하는데, 지금은 없으면 단순히 똑같은 파일을 복사해서 테스트하자.

 

$ cp pima-indians-diabetes.csv pima-indians-diabetes-valid.csv

$ python3 xgboost_general.py

Shape of (X_train, Y_train, X_test, Y_test)
(537, 8) (537, 1) (231, 8) (231, 1)
XGBClassifier(base_score=None, booster=None, colsample_bylevel=None,
              colsample_bynode=None, colsample_bytree=None, gamma=None,
              gpu_id=None, importance_type='gain', interaction_constraints=None,
              learning_rate=0.005, max_delta_step=None, max_depth=None,
              min_child_weight=None, missing=nan, monotone_constraints=None,
              n_estimators=100, n_jobs=None, num_parallel_tree=None,
              objective='binary:logistic', random_state=None, reg_alpha=None,
              reg_lambda=None, scale_pos_weight=None, subsample=None,
              tree_method=None, validate_parameters=None, verbosity=None)
Test Accuracy :73.16017%
Valid Accuracy :84.24479%

 

실제 풀 과제에서는 데이터를 분할하여 validation file을 따로 만들어두면 된다. 그리고 상기에서 살펴보면 learning_rate등 몇 가지 파라메터가 존재하는 것을 알 수 있다. 다만 여기서는 기본 셋팅으로도 대부분 무리 없게 결과를 받을 수 있었다. xgboost에 대해서는 예시가 많기 때문에 필요하다면 소폭 파라메터를 조율하여 실험해볼 수 있다.

 

경험상은 위 xgboost의 성능은 어떤가? feature data를 대개 standardization으로 scale한 후(전체 데이터의 평균을 빼고 표준편차로 나누는 간단한 feature scale 기법이다) 돌리면 일주일 내내 몇 가지 복합 신경망으로 얻은 결과의 상위권 성능과 유사한 정확도를 얻을 수 있었다. 이렇게 손쉽게 기초 결과를 얻어 볼 수 있다니, 개인적으로는 여전히 그 빠른 속도와 높은 정확도가 인상 깊다. 꽤 큰 규모의 데이터도 결과가 수십초 안에 나온다. 몇가지 다층 신경망으로 하루 종일 돌려서 나온 결과와 별로 다르지 않았거나 더 나았다.

 

3) 하나 더, 개별 feature의 중요도를 알 수 있다!

xgboost의 장점중의 하나는 feature importance라는, 어떤 feature column이 좋은지 힌트를 얻을 수 점이다. decision tree 방법에서 유래한 만큼 어떤 컬럼이 해당 decision에 가장 큰 효과를 지니는지 얻을 수 있는 정도로 이해할 수 있겠다.

 

레퍼런스는 아래와 같다.

machinelearningmastery.com/feature-importance-and-feature-selection-with-xgboost-in-python/

 

Feature Importance and Feature Selection With XGBoost in Python

A benefit of using ensembles of decision tree methods like gradient boosting is that they can automatically provide estimates of feature importance from a trained predictive model. In this post you will discover how you can estimate the importance of featu

machinelearningmastery.com

역시 몇가지 편의성을 위해 소폭 변형한 python 소스 코드 아래와 같다.

xgboost_feature_importance.py
0.00MB

$ more xgboost_feature_importance.py

 

# csv file : https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv
 
import pandas as pd
import numpy
# plot feature importance manually
from numpy import loadtxt
from xgboost import XGBClassifier
from sklearn.preprocessing import LabelEncoder
 
numpy.seterr(divide='ignore', invalid='ignore')
 
# load data
df = pd.read_csv('./pima-indians-diabetes.csv')
 
# split data into X and y
X = df.iloc[:,0:8].values
y = df.iloc[:,8].values
 
label_encoder = LabelEncoder()
label_encoder = label_encoder.fit(y)
label_encoded_y = label_encoder.transform(y)
 
# fit model no training data
model = XGBClassifier()
model.fit(X, label_encoded_y)
 
# feature importance
print(model.feature_importances_)

 

$ python3 xgboost_feature_importance.py

[0.09912988 0.2538216  0.08532038 0.08422164 0.10490113 0.1399659
 0.0945934  0.13804607]

 

상기 수치가 바로 feature의 각 컬럼별 feature 중요도이다. 높은 수치를 지닌 컬럼이 기여도가 크다.

 

여러가지 오랜 시간과 튜닝을 필요로 하는 복잡한 모델에 비해서 인스턴트 라면과 같이 빨리 별도의 튜닝 없이도 괜찮은 성능을 주는 모델 하나를 알고 있으면 의외로 여러 가지 검토 시 편하다는 것을 알 수 있다. 상기 예시를 잘 활용해보도록 하자.

 

반응형