LightGBM 파라미터 튜닝

LightGBM 파라미터 튜닝 (Parameters Tuning)

LightGBM은 리프 중심(best-first) 트리 성장 알고리즘을 사용하는데, 많은 다른 인기 도구는 깊이 중심(depth-wise)으로 트리를 키워요. 깊이 중심 성장과 비교하면 리프 중심 알고리즘은 훨씬 빠르게 수렴할 수 있어요. 하지만 적절한 파라미터 없이는 과적합될 수 있으니 주의해야 해요.

출처: LightGBM Parameters Tuning

리프 중심 트리 튜닝

  1. num_leaves: 트리 모델의 복잡도를 제어하는 핵심 파라미터예요. 이론적으로 깊이 중심 트리와 같은 리프 수를 얻으려면 num_leaves = 2^(max_depth)로 설정할 수 있어요. 하지만 이 단순한 변환은 실전에서 좋지 않아요. 리프 중심 트리는 같은 리프 수로도 깊이 중심 트리보다 훨씬 깊어지고, 제한 없는 깊이는 과적합을 유발하죠. 그래서 num_leaves를 튜닝할 때는 2^(max_depth)보다 작게 두는 게 좋아요. 예를 들어 max_depth=7일 때 깊이 중심 트리는 좋은 정확도를 얻지만 num_leaves127로 하면 과적합되고, 70이나 80으로 하면 깊이 중심보다 나은 정확도를 얻을 수 있어요.

  2. min_data_in_leaf: 리프 중심 트리에서 과적합을 막는 매우 중요한 파라미터예요. 최적값은 학습 샘플 수와 num_leaves에 의존해요. 크게 두면 너무 깊은 트리를 피할 수 있지만 과소적합(under-fitting)을 유발할 수 있어요. 실전에서는 큰 데이터셋에서 수백~수천으로 설정하는 게 충분해요.

  3. max_depth: 트리 깊이를 명시적으로 제한할 수 있어요. max_depth를 설정하면 num_leaves2^max_depth 이하 값으로 명시적으로 설정해야 해요.

더 빠른 속도를 위해

얕은 트리 성장하기

  • num_leaves 낮추기: LightGBM은 깊이와 무관하게 노드를 추가했을 때의 이득에 따라 트리에 노드를 추가해요. 이런 성장 전략 때문에 max_depth만으로 트리 복잡도를 제한하기는 쉽지 않아요. num_leaves가 트리당 최대 노드 수를 설정하므로, 이 값을 낮추면 학습 시간이 줄어요.
  • min_data_in_leafmin_sum_hessian_in_leaf 높이기: min_data_in_leaf는 트리 노드에 들어가야 할 최소 관측 수, min_sum_hessian_in_leaf는 리프에 있는 관측의 Hessian(각 관측에서 평가된 목적 함수의 2차 도함수) 합의 최소값이에요.

트리 수 줄이기

  • num_iterations 낮추기: 부스팅 라운드 수를 제어해요. 의사결정 트리를 학습자로 쓰므로 "트리 수"라고도 볼 수 있어요. 올바른 num_iterationslearning_rate는 데이터와 목적에 크게 의존해서 하이퍼파라미터 튜닝으로 고르는 경우가 많아요.
  • 조기 종료(early stopping) 사용하기: 연속 라운드 수는 early_stopping_round 파라미터로 제어돼요. 예를 들어 early_stopping_round=1은 "검증셋 정확도가 처음으로 개선되지 않는 순간 학습을 멈춰라"라는 뜻이에요.

분할 수 줄이기

  • feature_pre_filter=True 설정: 사용하지 않을 피처를 매 반복마다 재고하지 않고, Dataset을 만들 때 먼저 걸러줘요.
  • max_bin 낮추기: 노드를 추가할 때 고려하는 분할 수는 O(#feature * #bin)이라 피처당 빈 수를 줄이면 평가할 분할 수가 줄어요. max_bin으로 피처가 묶일 최대 빈 수를 제어하고, max_bin_by_feature로 피처별로도 설정할 수 있어요.
  • feature_fraction 낮추기: 기본값으로 모든 피처를 고려하는데, feature_fraction> 0이고 <= 1.0으로 설정해 각 트리 구성 초기에 피처의 일부만 무작위 선택할 수 있어요. 예를 들어 0.5는 50% 피처만 선택해요.
  • max_cat_threshold 낮추기: 범주형 피처를 두 그룹으로 나누는 "k-vs-rest" 분할을 탐색하는데, 값이 클수록 더 많은 분할점과 더 큰 그룹 크기를 탐색해요.

데이터 줄이기

  • 배깅(bagging) 사용하기: bagging_freq를 0보다 큰 정수로 설정해 새 샘플을 뽑는 빈도를, bagging_fraction> 0.0이고 < 1.0으로 설정해 샘플 크기를 제어해요. 예를 들어 {"bagging_freq": 5, "bagging_fraction": 0.75}는 "5번 반복마다 비복원 재샘플링하고 학습 데이터의 75%를 뽑아라"라는 뜻이에요.

과적합 다루기

  • 작은 max_bin 사용
  • 작은 num_leaves 사용
  • min_data_in_leafmin_sum_hessian_in_leaf 사용
  • bagging_fraction·bagging_freq 설정으로 배깅 사용
  • feature_fraction 설정으로 피처 서브샘플링 사용
  • 더 큰 학습 데이터 사용
  • 정규화를 위해 lambda_l1, lambda_l2, min_gain_to_split 시도
  • 깊은 트리를 피하려 max_depth 시도
  • extra_trees 시도
  • path_smooth 증가 시도

더 알아보기