데이터는 정형과 비정형 데이터로 나눌 수 있다. 정형 데이터는 엑셀과 CSV와 같이 행과 열에 따라 나뉨 이와 반대가 비정형 데이터이다. 우리는 이때까지 정형데이터를 사용하여 데이터를 분석했었다. 정형 데이터를 다루는 방법 중에는 가장 좋은 게 앙상블 학습이다. 이 알고리즘은 대부분 결정트리를 기반으로 만들어져 있는데 우리가 사용할 것은 랜덤 포레스트이다. 숲은 나무가 모여서 만들어진다 랜덤 포레스트 또한 다양한 결정 트리들이 모여서 구성되는데 동작과정을 알아보자
먼저 랜덤 포레스트는 각 트리를 훈련하기 위한 데이터를 랜덤 하게 만들어 낸다 이 데이터는 우리가 입력한 훈련데이터에서 랜덤 하게 샘플을 추출해서 만드는데 이때 추출하는 데이터는 중복이 될 수 있다. 따라서 무한한 가짓수의 샘플이 나올 수 있는데 이렇게 만들어진 샘플은 부트스트랩 샘플이라고 한다. 일반적으로 부트스트랩 샘플의 크기는 훈련세트와 같게 만든다.
결정트리의 노드를 나누는 기준인 특성은 분류모델에 따라 약간의 차이가 있는데
RandomForestClassifiter는 전체특성의 제곱근만큼 랜덤 선택하고
RandomForestRegressor은 전체 특성을 사용한다.랜덤 포레스트는 샘플과 특성을 랜덤하게 사용하기 때문에 훈련세트에 대한 과대적합을 막아줌과 동시에 검증 세트와 테스트 세트에서의 안정적인 성능을 얻을 수 있다.이제 데이터를 세팅하고 랜덤포레스트를 학습해 보자
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
wine = pd.read_csv('https://bit.ly/wine_csv_data')
data = wine[['alcohol','sugar','pH']].to_numpy()
target = wine['class'].to_numpy()
train_input, test_input, train_target, test_target = \
train_test_split(data, target, test_size=0.2, random_state=42)
데이터를 세팅했으니 이제 교차 검증과 랜덤 포레스트를 비교해서 알아보자
from sklearn.model_selection import cross_validate
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(rf, train_input, train_target, return_train_score=True, n_jobs=-1)
# return_train_score=True 매개변수의 역할은 검증 점수 뿐 아니라 훈련세트에 대한 점수도 반환해줌
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_) # 각 특성의 중요도를 수치로
#RandomForestClassifier 자체적 점수 평가 기능이 있음
rf = RandomForestClassifier(oob_score=True, n_jobs=-1, random_state=42)
rf.fit(train_input, train_target)
print(rf.oob_score_)
=>
[0.23167441 0.50039841 0.26792718]
0.8934000384837406
여기서 중요한것이 OOB이다. OOB는 out of bag의 약자로 랜덤 포레스트는 샘플을 선택할 때 무작위로 겹치게 만든 부트스트랩 샘플을 이용하기 때문에 이 과정에서 선택하지 않은 샘플들이 남아있을 수 있다. 이런 샘플들을 OOB라고 부른다. OOB는 부트스트랩 샘플의 부산물이긴 하지만 이 또한 샘플의 일부이기 때문에 교차 검증을 대신할 수 있다.
엑스트라 트리
엑스트라 트리는 랜덤 포래스트와 매우 비슷하게 동작하는데 차이점이라고 할 수 있는 것은 엑스트라 트리는 부트스트랩 트리를 사용하지 않는 다는 점이다. 대신 노드 분석이세 무작위로 분할을 한다. 성능은 조금 낮아질 수 있지만 과대적합을 막고 검증 세트가 점수를 높이는 효과는 있다.
#엑스트라 트리 : 차이점 부트스트랩 샘플 사용 여부, 전체를 무작위 분할
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']))
et.fit(train_input, train_target)
print(et.feature_importances_)
=>
0.9974503966084433 0.8887848893166506
[0.20183568 0.52242907 0.27573525]
그래디언트 부스팅
그래디언트 부스팅은 깊이가 얕은 결정 트리를 사용하여 이전 트리의 오차를 보완하는 작업을 말한다. 이는 과대적합에 강하고 높은 일반화 성능을 가진다. 이름에 그레이디언트는 점진적이란 의미인데 이는 앞서 배운 경사 하강법을 사용한다. 이는 사이킷런의 GradientBoostingClassifiter를 사용하여 점수를 확인해 보자.
#그레이디언트 부스팅
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
점수는 약간 낮지만 과대적합이 되지 않는다. 정확도는 결정트리의 개수를 늘려보면 해결이 된다.
히스토그램 기반 그레이디언트 부스팅
히스토리 기반 그레이디언트 는 우선적으로 특성을 256개의 구간으로 나눈다 여기서 하나의 구간은 누락된 값(결손값)을 위한 것으로 둔다. 장점 중 하나는 전처리 과정이 필요 없다. HistGradientBoostingClassifier 클래스는 트리의 개수를 지정할 때 n_estimators대신에 부스팅의 반복 횟수를 지정하는 변수인 max_iter를 사용한다. 과대적합을 잘 억제한다. 기본 그레이디언트 부스팅보다 성능이 높다
#히스토리 기반 그레이디이언트 부스팅
from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingClassifier
from sklearn.model_selection import cross_validate
hgb = HistGradientBoostingClassifier(random_state=42)
scores = cross_validate(hgb, train_input, train_target, return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
#permutation_importance() 는 함수가 반환하는 객체는 반복하여 얻은 특성 중요도,평균 표준편차를 담고있다.
from sklearn.inspection import permutation_importance
hgb.fit(train_input, train_target)
#훈련세트 성능
regult = permutation_importance(hgb, train_input, train_target, n_repeats=10, random_state=42, n_jobs=-1)
print(regult.importances_mean)
#테스트 세트에서의 성능
result = permutation_importance(hgb, test_input, test_target, n_repeats=10, random_state=42, n_jobs=-1)
print(result.importances_mean)
->
0.9321723946453317 0.8801241948619236
[0.08876275 0.23438522 0.08027708]
[0.05969231 0.20238462 0.049 ]
'머신러닝' 카테고리의 다른 글
머신 러닝(with Google Colab) - 6일차(2) (0) | 2024.10.25 |
---|---|
머신 러닝(with Google Colab) - 6일차(1) (2) | 2024.10.21 |
머신 러닝(with Google Colab) - 5일차(2) (1) | 2024.10.18 |
머신 러닝(with Google Colab) - 5일차(1) (0) | 2024.10.17 |
머신 러닝(with Google Colab) - 4일차(2) (1) | 2024.10.17 |