안 쓰던 블로그

배깅, 랜덤 포레스트 본문

머신러닝/머신러닝

배깅, 랜덤 포레스트

proqk 2021. 2. 7. 16:03
반응형

배깅Bagging

-Bootstrap Aggregating의 약자

1) 동일한 알고리즘을 사용하는 일정 수의 분류기를 생성

2) 각각의 분류기에 부트스트래핑Bootstrapping 분할 방식으로 생성된 샘플데이터를 학습

3) 최종적으로 각각의 결과를 보팅을 통해 예측 결정한다

 

랜덤 포레스트

-배깅의 대표적인 알고리즘은 랜덤 포레스트Random Forest

-여러 개의 결정 트리 분류기가 전체 데이터에서 배깅 방식으로 각자의 데이터를 샘플링하여 개별적으로 학습 수행, 최종적으로 모든 분류기가 보팅을 통해 예측 결정을 한다

 

-개별 분류기의 기반 알고리즘은 결정 트리, 개별 트리가 학습하는 데이터 세트는 부트스트래핑 분할 방식이 적용된 데이터 세트

-부트스트래핑 분할 방식: 전체 데이터에서 여러 개의 데이터 세트를 분리하는데 데이터가 일부 중첩되게 샘플링되어 분리함

 

 

장점

-결정 트리의 쉽고 직관적인 장점을 그대로 가지고 있음

-앙상블 알고리즘 중 비교적 빠른 수행 속도를 가지고 있음

-다양한 분야에서 좋은 성능을 나타냄

 

단점

-하이퍼 파라미터가 많아 튜닝을 위힌 시간이 많이 소요됨

 

랜덤 포레스트 실습

import pandas as pd

def get_new_feature_name_df(old_feature_name_df):
    feature_dup_df = pd.DataFrame(data=old_feature_name_df.groupby('column_name').cumcount(), columns=['dup_cnt'])
    feature_dup_df = feature_dup_df.reset_index()
    new_feature_name_df = pd.merge(old_feature_name_df.reset_index(), feature_dup_df, how='outer')
    new_feature_name_df['column_name'] = new_feature_name_df[['column_name', 'dup_cnt']].apply(lambda x : x[0]+'_'+str(x[1]) 
                                                                                           if x[1] >0 else x[0] ,  axis=1)
    new_feature_name_df = new_feature_name_df.drop(['index'], axis=1)
    return new_feature_name_df

중복된 feature명에 대해 원본 feature명 뒤에 _1, 2..를 추가한다

 

import pandas as pd

def get_human_dataset( ):
    
    # 각 데이터 파일들은 공백으로 분리되어 있으므로 read_csv에서 공백 문자를 sep으로 할당.
    feature_name_df = pd.read_csv('./human_activity/features.txt',sep='\s+',
                        header=None,names=['column_index','column_name'])
    
    # 중복된 feature명을 새롭게 수정하는 get_new_feature_name_df()를 이용하여 새로운 feature명 DataFrame생성. 
    new_feature_name_df = get_new_feature_name_df(feature_name_df)
    
    # DataFrame에 피처명을 컬럼으로 부여하기 위해 리스트 객체로 다시 변환
    feature_name = new_feature_name_df.iloc[:, 1].values.tolist()
    
    # 학습 피처 데이터 셋과 테스트 피처 데이터을 DataFrame으로 로딩. 컬럼명은 feature_name 적용
    X_train = pd.read_csv('./human_activity/train/X_train.txt',sep='\s+', names=feature_name )
    X_test = pd.read_csv('./human_activity/test/X_test.txt',sep='\s+', names=feature_name)
    
    # 학습 레이블과 테스트 레이블 데이터을 DataFrame으로 로딩하고 컬럼명은 action으로 부여
    y_train = pd.read_csv('./human_activity/train/y_train.txt',sep='\s+',header=None,names=['action'])
    y_test = pd.read_csv('./human_activity/test/y_test.txt',sep='\s+',header=None,names=['action'])
    
    # 로드된 학습/테스트용 DataFrame을 모두 반환 
    return X_train, X_test, y_train, y_test


X_train, X_test, y_train, y_test = get_human_dataset()

저번에 썼던 사용자 동작 정보를 가져오는 코드

 

from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import pandas as pd
import warnings
warnings.filterwarnings('ignore')

# 결정 트리에서 사용한 get_human_dataset( )을 이용해 학습/테스트용 DataFrame 반환
X_train, X_test, y_train, y_test = get_human_dataset()

# 랜덤 포레스트 학습 및 별도의 테스트 셋으로 예측 성능 평가
rf_clf = RandomForestClassifier(random_state=0)
rf_clf.fit(X_train , y_train)
pred = rf_clf.predict(X_test)
accuracy = accuracy_score(y_test , pred)
print('랜덤 포레스트 정확도: {0:.4f}'.format(accuracy))

데이터 프레임을 만들고 RandomForestClassifier로 랜덤 포레스트 학습, 예측, 평가

 

 

사이킷런의 랜덤 포레스트 하이퍼 파라미터

n_estimators: 결정 트리의 개수를 지정, 디폴트는 10이고 너무 늘리면 성능은 좋아지지만 시간이 너무 오래 걸림

min_samples_split노드 분할을 하기 위한 최소한의 샘플 데이터수, 과적합 제어

min_samples_leaf: 리프 노드가 되기 위한 최소한의 샘플 데이터수, 과적합 제어

max_features: 최적의 분할을 위해 고려할 최대 피처 개수, 디폴트 auto(결정트리는 디폴트 none인데 다름), int형이면 피처 개수, float형이면 비중, sqrt나 auto는 전체 피처의 제곱근만큼 선정, log면 전체 피처의 log2만큼 선정

max_depth: 트리의 최대 높이, 너무 크면 과적합될 수 있음

max_leaf_nodes: 리프노드의 최대 개수

 

from sklearn.model_selection import GridSearchCV

params = {
    'n_estimators':[100],
    'max_depth' : [6, 8, 10, 12], 
    'min_samples_leaf' : [8, 12, 18 ],
    'min_samples_split' : [8, 16, 20]
}
# RandomForestClassifier 객체 생성 후 GridSearchCV 수행
rf_clf = RandomForestClassifier(random_state=0, n_jobs=-1)
grid_cv = GridSearchCV(rf_clf , param_grid=params , cv=2, n_jobs=-1 )
grid_cv.fit(X_train , y_train)

print('최적 하이퍼 파라미터:\n', grid_cv.best_params_)
print('최고 예측 정확도: {0:.4f}'.format(grid_cv.best_score_))

각 파라미터 값을 넣는다

지금 4x3x3이니까 36번x2개(cv)=72번 수행

n_jobs=-1는 전체 cpu콜을 다 활용하라는 의미..시간이 오래 걸리게 된다

 

rf_clf1 = RandomForestClassifier(n_estimators=300, max_depth=10, min_samples_leaf=8, \
                                 min_samples_split=8, random_state=0)
rf_clf1.fit(X_train , y_train)
pred = rf_clf1.predict(X_test)
print('예측 정확도: {0:.4f}'.format(accuracy_score(y_test , pred)))

최적의 하이퍼 파라미터가 나왔으므로 튜닝된 하이퍼 파라미터로 재 학습하여 예측, 평가를 한다

 

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

ftr_importances_values = rf_clf1.feature_importances_
ftr_importances = pd.Series(ftr_importances_values,index=X_train.columns  )
ftr_top20 = ftr_importances.sort_values(ascending=False)[:20]

plt.figure(figsize=(8,6))
plt.title('Feature importances Top 20')
sns.barplot(x=ftr_top20 , y = ftr_top20.index)
plt.show()

개별 feature들의 중요도를 시각화하면 이렇게 나온다

반응형

'머신러닝 > 머신러닝' 카테고리의 다른 글

XGBoost과 LightGBM 개요  (0) 2021.02.07
부스팅 알고리즘  (0) 2021.02.07
앙상블 개요, 보팅  (0) 2021.02.07
결정 트리 과적합, 결정 트리 실습  (0) 2021.01.31
분류와 결정트리, 결정트리 시각화  (0) 2021.01.31
Comments