본문 바로가기
Data_engineering/Machine_learning

[알고리즘] 앙상블_랜덤포레스트_그레이디언트

by kyhh1229 2023. 2. 26.

 

정형 데이터와 비정형 데이터

 

  • 정형 데이터
  • ex) csv 파일에 가지런히 정리되어 있는 데이터들
  • 정형 데이터는 CSV나 데이터베이스 혹은 Excel에 저장하기 쉽다
  • 비정형 데이터
  • 데이터베이스나 엑셀로 표현하기 어려운 것들
  • ex) 책의 글 과 같은 텍스트 , 카메라로 찍은 사진 , 핸드폰으로 듣는 음악 등

 

지금까지 배운 머신러닝 알고리즘은 정형 데이터에 잘 맞는다

그중에 정형 데이터를 다루는 데 가장 뛰어난 성과를 내는 알고리즘이 앙상블 학습

이 알고리즘은 대부분 결정트리를 기반으로 만들어졌다

 


그럼 비정형 데이터에는 어떤 알고리즘을 사용해야 할까?

  • 신경망 알고리즘

비정형 데이터는 규칙성을 찾기 어려워 전통적인 머신러닝 방법으로는 모델을 만들기 까다롭다

하지만 신경망 알고리즘의 놀라운 발전 덕분에 사진을 인식하고 텍스트를 이해하는 모델을 만들 수 있다

 


 

랜덤 포레스트 ( RandomForest )

랜덤 포레스트는 앙상블 학습의 대표 주자 중 하나로 안정적인 성능 덕분에 널리 사용되고 있다

가장 먼저 랜덤포레스트를 시도해 보길 권한다

 

이름에서 유추 할 수 있듯이 랜덤 포레스트는 결정 트리를 랜덤하게 만들어

결정 트리(나무)의 숲을 만듭니다

그리고 각 결정트리의 예측을 사용해 최종 예측을 만듭니다

 

먼저 랜덤 포레스트는 각 트리를 훈련하기 위한 데이터를 랜덤하게 만드는데 방법이 독특하다

우리가 입력한 훈련 데이터에서 랜덤하게 샘플을 추출해 데이터를 만든다

이 때 한 샘플이 중복되어 추출 될 수도 있다

 

EX)

1,000개의 샘플이 들어있는 가방에서 100개의 샘플을 뽑는다면 먼저 1개를 뽑고 뽑았던 1개를 다시 가방에 넣는다

이런식으로 계속해서 100개를 가방에서 뽑으면 중복된 샘플을 뽑을 수 있다

이렇게 만들어진 샘플을 부트스트랩 샘플 이라고 부른다

 

부트스트랩 샘플은 훈련 세트의 크기와 같게 만든다

1,000개의 샘플이 들어있는 가방에서 중복하여 1,000개의 샘플을 뽑는다

 

 

부트스트랩이란?

 

데이터 세트에서 중복을 허용하여 데이터를 샘플링하는 방식

가방 1,000개의 샘플이 있을 때 먼저 1개를 뽑고, 다시 가방에 넣어 그 다음 샘플을 뽑는 방식

또한 각 노드를 분할할 때 전체 특성중 일부 특성을 무작위로 고른 다음 그 중에서 최선의 분할을 찾는다

 

 

 

분류모델 RandomForesClassifier

  • 전체 특성 개수의 제곱근 만큼의 특성을 선택
  • 4개의 특성이 있다면 노드마다 2개를 랜덤하게 선택하여 사용

회귀모델 RandomForesRegressor

  • 전체 특성 사용

사이킷런의 랜덤 포레스트는 기본적으로 100개의 결정 트리를 이런 방식으로 훈련한다

분류일 때는 각 트리의 클래스별 확률을 평균하여 가장 높은 확률을 가진 클래스를 예측으로 삼는다

회귀일 때는 단순히 각 트리의 예측을 평균한다

 

 

분류와 회귀

  • 분류는 샘플을 몇 개의 클래스 중 하나로 분류하는 문제
  • 회귀는 임의의 어떤 숫자를 예측하는 문제

랜덤 포레스트는 랜덤하게 선택한 샘플과 특성을 사용하기 때문에

훈련 세트에 과대적합되는 것을 막아주고 검증 세트와 테스트 세트에서 안정적인 성능을 얻을 수 있다

종종 기본 매개변수 설정만으로도 아주 좋은 결과를 낸다

 


 

사이킷런의 RandomForestClassifier 클래스

화이트 와인 분류 문제에 적용해보자

 

판다스 와인 데이터셋을 불러오고 train과 test를 나눈다

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
wine = pd.read_csv('경로')
data = wine[['alcohol','sugar','pH']].to_numpy()
target = wine['class'].to_numpy()

X_tr,X_te,y_tr,y_te = train_test_split(data,target,testsize=0.2,random_state=42)

 

cross_validate() 함수를 사용해 교차 검증을 수행해 보겠다

RandomForestClassifier는 기본적으로 100개의 결정트리를 사용하므로

n_jobs 매개변수를 -1로 지정하여 모든 CPU 코어를 사용하는것이 좋다

 

cross_validate() 함수의 n_jobs 매개변수도 -1로 지정하여 최대한 병렬로 교차검증을 수행해보겠다

 

return_train_score 매개변수를 True로 지정하면 검증 점수뿐만 아니라 훈련 세트에 대한 점수도 같이 반환한다

훈련 세트와 검증 세트의 점수를 비교하면 과대적합을 파악하는 데 용이하다 (return_train_score 매개변수의 기본값은 False 이다)

 

from sklearn.model_selection import cross_validate
from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(n_jobs= -1 , randomstate=42 )
scores = cross_validate(rf,X_tr,X_te,return_train_score=True,n_jobs= -1)

print(np.mean(scores['train_score']),np.mean(scores['test_score']))
0.9973541965122431 , 0.8905151032797809

출력된 결과를 보면 훈련 세트에 다소 과대적합된 것 같다

여기서는 알고리즘을 조사하는것이 목적이므로 매개변수를 더 조정하지 않도록 하겠다

랜덤 포레스트는 결정 트리의 앙상블이기 때문에 DecisionTreeClassifier가 제공하는 중요한 매개변수를 모두 제공한다

 

  • criterion
  • max_depth
  • max_features
  • min_samples_split
  • min_impurity_decrease
  • min_samples_leaf 등등

 


그레이디언트 부스팅 ( gradient boosting )

그레이디언트 부스팅은 깊이가 얇은 결정 트리를 사용하여

이전 트리의 오차를 보완하는 방식으로 앙상블 하는 방법

 

사이킷런의 GradientBoostingClassifier는 기본적으로 깊이가 3인 결정 트리를 100개 사용한다

깊이가 얕은 결정 트리를 사용하기 때문에 과대적합에 강하고 일반적으로 높은 일반화 성능을 기대할 수 있다

 

그레이디언트란 이름처럼 *경사 하강법을 사용하여 트리를 앙상블에 추가한다

분류에서는 로지스틱 손실 함수를 사용하고 회귀에서는 평균 제곱 오차 함수를 사용한다

 


 

경사 하강법

 

‘경사’는 말 그대로 기울기를 말하는것

‘하강법’ 은 ‘내려가는 방법’

다시말해 경사 하강법은 경사를 따라 내려가는 방법을 말한다

 

EX)

산에서 내려온다는 가정하에 집으로 돌아가려면 등산로 입구까지 내려가야한다

하지만 어떤 산길도 척척 내려갈 수 있는 초능력이 있다면 가장 빠른길로 가는것이 좋다

가장 빠른길은 경사가 가장 가파른 길이다

 

경사 하강법은 이런 방식이다

가장 가파른 경사를 따라 원하는 지점에 도달하는 것이 목표

 

하지만 한번에 걸음이 너무 크면 경사를 따라 내려가지 못하고 오히려 올라갈 수가 있다

실제로 산에서 내려올 때는 천천히 조금씩 내려와야 한다

나뭇잎 속에 가려진 웅덩이가 있을지도 모르니까 말이다

 

경사 하강법도 마찬가지다

가장 가파른 길을 찾아 내려오지만 조금씩 내려오는 것이 중요하다

이렇게 내려오는 과정이 바로 경사 하강법 모델을 훈련하는것

 

경사 하강법은 손실 함수를 산으로 정의하고 가장 낮은 곳을 찾아 내려오는 과정으로 설명했다

이 때 가장 낮은 곳을 찾아 내려오는 방법은 모델의 가중치와 절편을 조금씩 바꾸는것

 


 

그레이디언트 부스팅 gradient boosting

 

결정 트리를 계속 추가하면서 가장 낮은 곳을 찾아 이동한다

위 예시처럼 손실 함수의 낮은 곳으로 천천히 조금씩 이동해야 한다

그레이디언트 부스팅도 마찬가지다

 

그래서 깊이가 얕은 트리를 사용하는거다 또 학습률 매개변수로 속도를 조절한다

위의 와인 데이터셋에 이어서 점수를 확인해보자

 

from sklearn.ensemble import GradientBoostingClassifier
gb = GradientBoostingClassifier(random_state=42)

scores = cross_validate(gb,X_tr,X_te,return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']),np.mean(scores['test_score']))
0.8881086892152563 0.8720430147331015

 

거의 과대적합이 되지 않는다

그레이디언트 부스팅은 결정 트리의 개수를 늘려도 과대적합에 매우 강하다

학습률을 증가시키고 트리의 개수를 늘리면 조금 더 성능이 향상 될 수 있다

'Data_engineering > Machine_learning' 카테고리의 다른 글

[sklearn] accuracy_score  (0) 2023.02.27
[Machine learning] 교차검증  (0) 2023.02.27
[알고리즘] K-Nearest Neighbors  (0) 2023.02.26
[sklearn] predict ()  (0) 2023.02.26
[sklearn] score()  (0) 2023.02.26

댓글