혼공머신 - 8

Apic·2025년 8월 5일
0

데이터 종류

정형 데이터

CSV 파일처럼 가지런히 정렬되어있음

비정형 데이터

글과 같은 텍스트, 이미지, 오디오 등

랜덤 포레스트

대표적인 앙상블 학습

부트스트랩 샘플

1000개의 샘플 중에서 100개를 뽑는다고 했을 때,
1개 뽑고 다시 넣고 다시 하나를 뽑아(중복 가능성 있음) 만들어진 샘플

그리고 랜덤 포레스트는 랜덤으로 특성을 선택하여 사용한다.
예를 들어 총 4개의 특성이 있다고 했을 때 그중 2개를 선택하여 사용한다.

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split, cross_validate
from sklearn.ensemble import RandomForestClassifier

wine = pd.read_csv('https://bit.ly/wine_csv_data')
data = wine[['alcohol', 'sugar', 'pH']]
target = wine['class']
train_input, test_input, train_target, test_target = train_test_split(data, target, test_size=0.2, random_state=42)

rf = RandomForestClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(rf, train_input, train_target, return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
# 0.9973541965122431 0.8905151032797809 => 과대적합

rf.fit(train_input, train_target)
print(rf.feature_importances_)
# [0.23167441 0.50039841 0.26792718] => 중요도 확인

rf = RandomForestClassifier(
    oob_score=True,
    n_jobs=-1,
    random_state=42
)
rf.fit(train_input, train_target)
print(rf.oob_score_) # 0.8934000384837406

엑스트라 트리

랜덤 포레스트와 매우 비슷하게 동작한다.

하지만 차이점은 엑스트라 트리는 부트스트랩 샘플을 사용하지 않는다는 점이다.
결정 트리를 만들 때 전체 훈련 세트를 사용한다.

하지만 분할 할때 그냥 무작위로 분할하게 된다.

from sklearn.ensemble import ExtraTreesClassifier

et = ExtraTreesClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(et, train_input, train_target, return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
# 0.9974503966084433 0.8887848893166506

et.fit(train_input, train_target)
print(et.feature_importances_)
# [0.20183568 0.52242907 0.27573525]

그라디언트 부스팅

깊이가 얕은 결정 트리를 사용하여 이전 트리의 오차를 보완하는 방식으로 앙상블 하는 방법이다.사이킷런에서는 기본적으로 깊이 3인 결정 트리 100개를 사용한다.
얕은 결정 트리를 사용하기 때문에 과대적합에 강하고 일반적으로 높은 일반화 성능을 기대할 수 있다.
경사 하강법을 사용하여 트리를 앙상블에 추가한다.

from sklearn.ensemble import GradientBoostingClassifier

gb = GradientBoostingClassifier(random_state=42)
scores = cross_validate(gb, train_input, train_target, return_train_score= True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
# 0.8881086892152563 0.8720430147331015

gb = GradientBoostingClassifier(
    n_estimators=500,   # 결정 트리 개수
    learning_rate=0.2,  # 학습률 
    random_state=42
)
scores = cross_validate(gb, train_input, train_target, return_train_score= True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
# 0.9464595437171814 0.8780082549788999

히스토그램 기반 그레이디언트 부스팅

정형 데이터를 다루는 머신러닝 알고리즘 중에 가자 인기가 높음
입력 특서을 256개 구간으로 나눠 노드를 분할할 때 최적의 분할을 빠르게 찾을 수 있다.

from sklearn.ensemble import HistGradientBoostingClassifier

hgb = HistGradientBoostingClassifier(random_state=42)
scores = cross_validate(hgb, train_input, train_target, return_train_score = True)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
# 0.9321723946453317 0.8801241948619236

과대적합을 잘 억제하면서 그레이디언트 부스팅보다 조금 더 높은 성능을 제공한다.

여기서는 특성의 중요도를 보여주지 않기 때문에 permutation_importance를 사용한다.
이 함수는 사이킷 런에서 제공하는 모든 모델에 사용할 수 있다.

from sklearn.inspection import permutation_importance

hgb.fit(train_input, train_target)
result = permutation_importance(hgb, train_input, train_target, n_repeats=10, random_state=42, n_jobs=-1)
print(result.importances_mean)
# [0.08876275 0.23438522 0.08027708]
  • imporrtances: 특성 중요도
  • importances_mean: 평균
  • importrances_std: 표준편차

그리고 그레이디언트 부스팅 알고리즘을 구현한 대표적인 라이브러리가 2개 있다.
XGBoostLightGBM이다.

XGBoost

from xgboost import XGBClassifier

xgb = XGBClassifier(tree_method='hist', random_state=42)
scores = cross_validate(xgb, train_input, train_target, return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
# 0.9567059184812372 0.8783915747390243

LightGBM

from lightgbm import LGBMClassifier

lgb = LGBMClassifier(random_state=42)
scores = cross_validate(lgb, train_input, train_target, return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
profile
코딩 공부하는 사람

0개의 댓글