TOP
class="layout-aside-left paging-number">
본문 바로가기
데이터분석 만능열쇠 [파이썬]/<파이썬 머신러닝>

[파이썬] 분류 > 앙상블 - 2 : 랜덤 포레스트

by 기록자_Recordian 2024. 6. 27.
728x90
반응형
시작에 앞서
해당 내용은 '<파이썬 머신러닝 완벽 가이드> 권철민 지음. 위키북스' 를 토대로 작성되었습니다. 보다 자세한 내용은 해당 서적에 상세히 나와있으니 서적을 참고해 주시기 바랍니다.

앙상블 학습(Ensemble Learning)
 

[파이썬] 분류: 앙상블 학습(Ensemble Learning) - 1

시작에 앞서해당 내용은 ' 권철민 지음. 위키북스' 를 토대로 작성되었습니다. 보다 자세한 내용은 해당 서적에 상세히 나와있으니 서적을 참고해 주시기 바랍니다.앙상블 학습(Ensemble Learning) 

puppy-foot-it.tistory.com


랜덤 포레스트

 

랜덤 포레스트는 배깅의 대표적인 알고리즘인데, 배깅은 같은 알고리즘으로 여러 개의 분류기를 만들어서 보팅으로 최종 결정하는 알고리즘이다.

 

랜덤 포레스트는 앙상블 알고리즘 중 비교적 빠른 수행 속도를 가지고 있으며, 다양한 영역에서 높은 예측 성능을 보이고 있다.

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

 

사이킷런은 RadomForestClassifier 클래스를 통해 랜덤 포레스트 기반의 분류를 지원한다.

 

[행동 인식 데이터 세트를 이용해 예측 수행]

새로운 주피터 노트북에서 진행하되, 재수행 시마다 동일한 예측 결과를 출력하기 위해, 그리고 사용자 행동 데이터 세트에 DataFrame을 반환하는 get_human_dataset() 함수를 가져오기 위해 기존의 예측 분석과 동일한 디렉터리에 생성한다.

 

기존에 진행했던 행동 인식 데이터 관련 내용은 하단 참고

 

[파이썬] 결정트리 - 사용자 행동 인식 데이터 세트

시작에 앞서해당 내용은 ' 권철민 지음. 위키북스' 를 토대로 작성되었습니다. 보다 자세한 내용은 해당 서적에 상세히 나와있으니 서적을 참고해 주시기 바랍니다.사용자 행동 인식 데이터 세

puppy-foot-it.tistory.com

 

(물론, 새로운 디렉터리에 수행해도 된다. 이러한 경우, 행동 인식 데이터 코드는 get_human_dataset() 함수 생성까지 동일하다 - 혹시 몰라서 하단에 코드를 남긴다.)

※ 물론, 사이킷런에서 앙상블의 랜덤 포레스트 분류기를 import 하는 것도 다르다 (하단 첫째 줄 참고)

# 랜덤 포레스트 (사용자 행동 인식 데이터 세트 활용)
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
# features.txt 파일에는 피처 이름 index와 피처명이 공백으로 분리되어 있음
# 이를 DataFrame으로 로드
feature_name_df = pd.read_csv('C:/Users/niceq/Documents/DataScience/Python ML Guide/human_activity/features.txt',
                               sep='\s+', header=None, names=['column_index', 'column_name'])

# 피처명 index를 제거하고, 피처명만 리스트 객체로 생성한 뒤 샘플로 10개만 추출
feature_name = feature_name_df.iloc[:, 1].values.tolist()
print('전체 피처명에서 10개만 추출:', feature_name[:10])
# 중복된 피처명 파악하기
feature_dup_df = feature_name_df.groupby('column_name').count()
print(feature_dup_df[feature_dup_df['column_index'] > 1].count())
feature_dup_df[feature_dup_df['column_index'] > 1].head()
# 중복된 피처명 파악하기
feature_dup_df = feature_name_df.groupby('column_name').count()
print(feature_dup_df[feature_dup_df['column_index'] > 1].count())
feature_dup_df[feature_dup_df['column_index'] > 1].head()
# get_human_dataset 함수 생성
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'])
    # 중복된 피처명을 수정하는 get_new_feature_name_df()를 이용, 신규 피처명 DF 생성
    new_feature_name_df = get_new_feature_name_df(feature_name_df)

    # DF에 피처명을 칼럼으로 부여하기 위헤 리스트 객체로 다시 변환
    feature_name = new_feature_name_df.iloc[:, 1].values.tolist()

    # 학습 피처 데이터세트와 테스트 피처 데이터를 DF로 로딩. 칼럼명은 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)

    # 학습 레이블과 테스트 레이블 데이터를 DF로 로딩하고 칼럼명은 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'])

    # 로드된 학습/테스트용 DF 모두 반환
    return X_train, X_test, y_train, y_test

X_train, X_test, y_train, y_test = get_human_dataset()

여기까지는 동일하고,

하단 내용을 입력하여 랜덤 포레스트를 통한 예측 성능 평가를 수행하면 된다.

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

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


랜덤 포레스트 하이퍼 파라미터 및 튜닝

 

랜덤 포레스트 같은 트리 기반의 앙상블 알고리즘의 단점

- 하이퍼 파라미터가 많다. ▶ 튜닝을 위한 시간이 많이 소요된다.

- 튜닝을 위한 시간을 많이 소모했음에도 예측 성능이 향상되지 않는 경우가 많다.

 

※ 트리 기반 자체의 하이퍼 파라미터는 원래 많은데다가 배깅, 부스팅, 학습, 정규화 등을 위한 하이퍼 파라미터까지 추가되어 다른 머신러닝 알고리즘에 비해 많을 수 밖에 없다.

 

[랜덤 포레스트 하이퍼 파라미터]

  • n_estimators: 랜덤 포레스트에서 결정 트리의 개수 지정 (디폴트 10개). 많을수록 좋은 성능을 기대할 수 있으나, 학습수행 시간 증가
  • max_features: 최적의 분할을 위해 고려할 최대 피처 개수(디폴트 'auto' = 'sqrt') 전체 피처 중 전체 피처의 루트 만큼 선정 (예를 들어 전체 피처가 16개라면 분할을 위해 4개 참조)
  • max_depth, min_samples_leaf, min_samples_split 등 결정 트리에서 과적합을 개선하기 위해 사용되는 파라미터 역시 랜덤 포레스트에서 동일하게 적용

참고 - 결정 트리 파라미터

 

[GridSearchCV를 이용해 랜덤 포레스트의 하이퍼 파라미터 튜닝]

(사용자 행동 데이터 세트 그대로 사용, n_estimators = 100, CV = 2)

# GridSearchCV를 이용해 랜덤 포레스트의 하이퍼 파라미터 튜닝
from sklearn.model_selection import GridSearchCV

params = {
    'max_depth' : [8, 16, 24],
    'min_samples_leaf' : [1, 6, 12], 
    'min_samples_split' : [2, 8, 16]
}

# RandomForestClassifier 객체 생성 후 GridSearchCV 수행
# 멀티 코어 환경에서는 n_jobs=-1 파라미터 추가 시 모든 CPU 코어를 이용해 학습 가능
rf_clf = RandomForestClassifier(n_estimators=100, 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_))

▶ max_depth 16, min_samples_leaf 6, min_samples_split 2 일 때 2개의 CV 세트에서 약 91.65%의 정확도가 측정되었다.

 

[추출된 최적 하이퍼 파라미터로 별도의 테스트 데이터 세트에서 예측 성능 측정]

# 추출된 최적 하이퍼 파라미터로 별도의 테스트 데이터 세트에서 예측 성능 측정
rf_clf1 = RandomForestClassifier(n_estimators=100, min_samples_leaf=6, max_depth=16,
                                min_samples_split=2, 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)))


피처의 중요도 시각화

 

RandomForestClassifier 역시 feature_importances_ 속성을 이용해 알고리즘이 선택한 피처의 중요도를 파악할 수 있다.

 

[피처의 중요도를 파악해 막대그래프로 시각화]

#피처의 중요도를 파악해 막대그래프로 시각화
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

ftr_importances_values = rf_clf1.feature_importances_
# Top 중요도로 정렬을 쉽게 하고, 시본(Seaborn)의 막대그래프로 쉽게 표현하기 위해 Series 변환
ftr_importances = pd.Series(ftr_importances_values, index=X_train.columns)

# 중요도 값 순으로 Series를 정렬
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()

▶ angle(X.gravityMean), tGravityAcc-mean()-Y, tGravityAcc-min()-X 등이 높은 피처 중요를 가지고 있다.


 

 

728x90
반응형