본문 바로가기
AI/AI 부트캠프

[AI 부트캠프] DAY 59 - 머신러닝 프로젝트 3

by HOHHOH 2023. 10. 14.

[오늘의 일지]

머신러닝 프로젝트 - CatBoost, HistGradientBoosting, Random Forest

[상세 내용]

머신러닝 프로젝트

CatBoost

- 어제 LGBM을 사용하면서 계속해서 하이퍼파라미터를 여러 가지로 수정해 가면서 좋은 평가지표를 얻으려는 시도를 많이 했지만 아쉽게도 어느 순간부터는 정체되는 느낌을 받았고 optuna를 통해서 최적의 파라미터 값을 찾기 위해서 수치를 더 깊은 학습을 하도록 조정했지만 시간만 오래 걸렸고 실패했습니다. 그러던 중에 여러 가지 알고리즘을 사용하면서 최적의 모델을 찾을 수 있다는 이야기를 듣고 CatBoost를 사용해 보았습니다. CatBoost는 사실 카테고리컬 피처가 많이 존재할 때 자동으로 처리해 줄 수 있으므로 유용하다고 합니다. 그래서 이번 데이터에도 카테고리컬 피처가 6개는 존재했기 때문에 한번 사용해 보았습니다. CatBoost를 사용해 보고 결과물을 제출까지 해본 결과 특징을 몇 가지 설명해 보자면 처음에 그냥 모든 피처를 사용해서 결과를 얻었을 때는 평가지수가 잘 나왔습니다. 그러다가 피처수를 줄여가면서 측정해 보니 점점 잘 안 나오는 것을 확인했습니다. 이 말은 불필요한 피처를 그냥 사용하면 오버피팅이 일어난다는 것입니다. CatBoost 또한 LGBM과 걸리는 시간이 비슷했고 결과도 어느 정도 비슷하게 정체되는 것 같았습니다.

# CatBoost 사용 예시

import catboost
from catboost import CatBoostClassifier
from catboost import CatBoostRegressor, Pool
from sklearn.model_selection import KFold


params = {'iterations': 2000, 'max_depth': 12, 'learning_rate': 0.015325,
          'rsm' : 0.8 }

# 'ARI_CO' 열을 범주형으로 처리하도록 추가
cat_features = ['ARI_CO', 'ARI_PO', 'SHIP_TYPE_CATEGORY']

catboost_model = CatBoostRegressor(**params, cat_features=cat_features, random_state=42)

# 5-Fold 설정
kf = KFold(n_splits=5, shuffle=True, random_state=42)

# 각 fold의 모델로부터의 예측을 저장할 리스트와 MAE 점수 리스트
ensemble_predictions = []
scores = []

for train_idx, val_idx in tqdm(kf.split(X_train_reduced), total=5, desc="Processing folds"):
    X_t, X_val = X_train_reduced.iloc[train_idx], X_train_reduced.iloc[val_idx]
    y_t, y_val = y_train.iloc[train_idx], y_train.iloc[val_idx]

    # CatBoost 모델로 학습
    catboost_model.fit(X_t, y_t)

    # 각 모델로부터 Validation set에 대한 예측을 평균내어 앙상블 예측 생성
    val_pred = catboost_model.predict(X_val)

    # Validation set에 대한 대회 평가 산식 계산 후 저장
    scores.append(mean_absolute_error(y_val, val_pred))

    # test 데이터셋에 대한 예측 수행 후 저장
    catboost_pred = catboost_model.predict(X_test_reduced)
    catboost_pred = np.where(catboost_pred < 0, 0, catboost_pred)

    ensemble_predictions.append(catboost_pred)

# K-fold 모든 예측의 평균을 계산하여 fold별 모델들의 앙상블 예측 생성
final_predictions = np.mean(ensemble_predictions, axis=0)

# 각 fold에서의 Validation Metric Score와 전체 평균 Validation Metric Score 출력
print("Validation : MAE scores for each fold:", scores)
print("Validation : MAE:", np.mean(scores))

 

HistGradientBoosting

- 다양한 방법을 시도하기 위해서 찾던 중에 검색을 통해  HistGradientBoosting을 알게 되어 사용하게 되었습니다. 이 알고리즘은 히스토그램 기반의 알고리즘입니다. 이는 데이터를 히스토그램으로 요약하여 학습에 사용하는데, 이를 통해 데이터를 효율적으로 압축하고 처리할 수 있습니다. 특히, 이 히스토그램 기반 접근 방식은 데이터 집약적인 문제와 대규모 데이터셋에 매우 유용합니다. 그리고 속도가 빠르다는 장점이 있었는데 제가 느끼기에는 LGBM이나 CatBoost와 많은 차이는 느끼지 못했던 거 같습니다. 모델링을 하던 중에 좋은 결과가 나와서 결과물을 제출해 보았지만 오버피팅된 결과였고 이렇다 할 결과를 얻지 못했습니다.

# HistGradientBoosting 예시 코드

from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingRegressor
from sklearn.model_selection import KFold

# 5-Fold 설정
kf = KFold(n_splits=5, shuffle=True, random_state=42)

# 각 fold의 모델로부터의 예측을 저장할 리스트와 MAE 점수 리스트
ensemble_predictions = []
scores = []

for train_idx, val_idx in tqdm(kf.split(X_train), total=5, desc="Processing folds"):
    X_t, X_val = X_train.iloc[train_idx], X_train.iloc[val_idx]
    y_t, y_val = y_train.iloc[train_idx], y_train.iloc[val_idx]

    # HistGradientBoostingRegressor 모델 초기화
    model = HistGradientBoostingRegressor(max_iter=10000,
                                          max_depth=30,
                                          learning_rate = 0.02,
                                          max_leaf_nodes=31,     # 각 트리의 최대 리프 노드 수
                                          max_bins=255,          # 데이터를 나누는 히스토그램의 최대 bin 수
                                          l2_regularization=0.01, # L2 정규화 강도
                                          random_state=42)

    # 모델 학습
    model.fit(X_t, y_t)

    # Validation set에 대한 예측을 평균내어 앙상블 예측 생성
    val_pred = model.predict(X_val)

    # Validation set에 대한 대회 평가 산식 계산 후 저장
    scores.append(mean_absolute_error(y_val, val_pred))

    # test 데이터셋에 대한 예측 수행 후 저장
    model_pred = model.predict(X_test)
    model_pred = np.where(model_pred < 0, 0, model_pred)

    ensemble_predictions.append(model_pred)

# K-fold 모든 예측의 평균을 계산하여 fold별 모델들의 앙상블 예측 생성
final_predictions = np.mean(ensemble_predictions, axis=0)

# 각 fold에서의 Validation Metric Score와 전체 평균 Validation Metric Score 출력
print("Validation : MAE scores for each fold:", scores)
print("Validation : MAE:", np.mean(scores))

 

Random Forest

- 원래대로는 랜덤 포레스트가 LGBM 보다 느리기 때문에 먼저 시도를 해봤어야 했지만 작업에 진전이 없어서 복습한다는 생각으로 돌려보았습니다. 하이퍼파라미터를 설정하지 않고 그냥 돌렸을 때도 다른 알고리즘들보다 낯은 수치가 나왔습니다. 그리고 하이퍼파라미터를 설정하기 위해 그리드 서치를 시도했는데 10시간 정도를 기다렸는데도 결과가 나오지 않았고 colab의 오류로 결과도 얻지 못해서 안타까웠습니다. 나중에 데이터의 크기가 비교적 작을 때 다시 한번 도전해 봐야 될 거 같습니다.

# 랜덤 포레스트 예시 코드 입니다.

from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_absolute_error


X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.2, random_state=42)

# 랜덤 포레스트 모델 생성
random_forest = RandomForestRegressor()  # 기본값을 사용하거나 조정할 하이퍼파라미터를 설정합니다

# 탐색할 하이퍼파라미터 그리드 정의
param_grid = {
    'n_estimators': [100, 200, 300],  # 결정 트리의 개수
    'max_depth': [None, 10, 20, 30],  # 최대 깊이
    'min_samples_split': [2, 5, 10],  # 내부 노드를 분할하기 위한 최소 샘플 수
    'min_samples_leaf': [1, 2, 4]  # 리프 노드에 필요한 최소 샘플 수
}

# Grid Search 객체 생성
grid_search = GridSearchCV(random_forest, param_grid, cv=5, scoring='neg_mean_absolute_error', verbose=2)  # verbose를 1로 설정

# 모델 훈련 및 최적 하이퍼파라미터 조합 탐색
grid_search.fit(X_train, y_train)

# 최적 하이퍼파라미터 조합 출력
print("Best Hyperparameters:", grid_search.best_params_)

# 최적 모델
best_model = grid_search.best_estimator_

# 검증 데이터에 모델을 적용하고 MAE 계산
y_pred = best_model.predict(X_val)
mae = mean_absolute_error(y_val, y_pred)
print("Validation MAE:", mae)

# 테스트 데이터에 모델 적용
test_predictions = [best_model.predict([sample]) for sample in X_test]

 

[마무리]

 오늘은 어제부터 이어진 모델링 작업을 이어서 했습니다. 어느 순간부터 결과가 정체되어 있다고 생각해서 여러 가지 알고리즘을 활용해 보는 시간을 가져봤습니다. 이 작업 또한 원하는 결과를 얻지는 못했지만 수업시간에 배웠던 내용을 복습할 수 있어서 좋았고 직접 사용해 보니까 각각의 특징들을 더 잘 이해할 수 있어서 좋았습니다. 주말 동안에는 검색을 통해서 더 좋은 결과를 얻을 수 있도록 노력해 봐야 될 거 같습니다. 

반응형

댓글