본문 바로가기

Euron/정리

[Week2] 04. 분류(1)

01. 분류(Classfication)의 개요

 

지도학습의 대표적인 유형인 분류(Classification)을 배운다.

분류는 기존 데이터가 어떤 레이블에 속하는지 패턴을 알고리즘으로 인지한 뒤에 새롭게 관측된 데이터에 대한 레이블을 판별하는 것이다.

 

분류 구현 ML 알고리즘

  • 나이브 베이즈 : 베이즈 통계와 생성 모델 기반
  • 로지스틱 회귀 : 독립변수와 선형 관계성에 기반
  • 결정 트리 : 데이터 균일도에 따른 규칙 기반
  • 서포트 벡터 머신 : 개별 클래스 간의 최대 분류 마진을 효과적으로 찾아주는 서포트 벡터 머신
  • 최소 근접 알고리즘 : 근접 거리 기준
  • 신경망 : 심층 연결 기반
  • 앙상블 : 서로 다른(또는 같은) 머신러닝 알고리즘을 결합

분류에서 가장 각광받는 방법 중 하나인 앙상블 방법(Ensemble Method)을 집중적으로 다룬다.

앙상블은 일반적으로 배깅(Bagging)과 부스팅(Boosting) 방식으로 나뉜다.

각 방식의 대표는 랜덤 포레스트(Random Forest)와 그래디언트 부스팅(Gradient Boosting)이 있다.

 

앙상블의 기본 알고리즘은 결정 트리(Decision Tree)이다.

매우 쉽고 유연하게 적용될 수 있는 알고리즘이지만, 과적합(Overfitting)이 발생할 수 있다.

그러나 앙상블은 여러 약한 학습기를 결합해 가중치를 업데이트 하며 예측 성능을 향상시키는데, 결정트리의 단점은 좋은 약한 학습기가 되어 장점으로 작용한다.


02. 결정 트리

결정 트리(Decision Tree)는 ML알고리즘 중 직관적으로 이해하기 쉬운 알고리즘으로, 데이터에 있는 규칙을 학습을 통해 자동으로 찾아내 트리 기반의 분류 규칙을 만드는 것이다.

규칙 노드(Decition Node)로 표시된 노드는 규칙 조건이 되는 것이고, 리프 노드(Leaf Node)로 표시된 노드는 결정된 클래스 값이다. 그리고 새로운 규칙 조건마다 서브 트리가 생성된다.

결정 트리

트리의 깊이가 깊어질수록 과적합으로 인해 결정 트리의 예측 성능이 저하된다.

따라서 최대한 많은 데이터 세트가 해당 분류에 속할 수 있도록 결정 노드의 규칙이 정해저야 한다. 즉, 최대한 균일한 데이터 세트를 구성하도록 분할한다.

결정 노드는 정보 균일도가 높은 데이터 세트를 먼저 선책할 수 있도록 규칙조건을 만든다.

 

정보의 균일도를 측정하는 방법은 엔트로피를 이용한 정보 이득(Information Gain)지수지니 계수가 있다.

  • 정보 이득 : 정보 이득 지수는 1에서 엔트로피 지수를 뺀 값이다. 엔트로피는 주어진 데이터 집합의 혼잡도를 의미한다.  따라서 정보 이득이 높은 속성을 기준으로 분할한다.(엔트로피가 낮은 값==서로 같은 값이 섞여 있음)
  • 지니 계수 : 0으로 갈 수록 평등하다. 즉, 데이터 균일도가 높은 것으로 해석해 지니 계수가 낮은 속성을 기준으로 분할한다.

사이킷런의 DecisionTreeClassfier는 기본으로 지니 계수를 이용해 데이터 세트를 분할한다.

반복적으로 분할을 실행한 뒤, 데이터가 모두 특정 분류에 속하게 되면 분할을 멈추고 분류를 결정한다.

 

결정 트리 모델의 특징

 

결정 트리의 가장 큰 장점은 정보의 '균일도'를 기반으로 하여 알고리즘이 쉽고 직관적이다.

또한 대부분은 피처릐 스케일링과 정규와 같은 전처리 작업이 필요없다.

 

단점은 과적합으로 정확도가 떨어진다.

따라서 트리의 크기를 사전에 제한하는 것이 오히려 성능 튜닝에 도움이 된다.

 

결정 트리 파라미터

 

사이킷런은 분류를 위한 DecisionTreeClassfier와 회귀를 위한 DecisionTreeRegressor 클래스를 제공한다.

 

파라미터(둘 다 동일함

  • min_samples_split
    • 노드를 분할하기 위한 최소한의 샘플 데이터 수 -> 과적합 제어
    • default=2, 작게 설정할 수록 분할 노드가 많아져 과적합 증가
  • min_samples_leaf
    • 분할되는 경우 자식 노드에서 가져야할 최소 샘플 데이터 수
    • 큰값으로 설정될수록 노드 분할을 덜 수행
    • 과적합 제어 용도로 사용되나, 비대칭적 데이터의 경우에는 작게 설정 필요
  • max_features
    • 최적의 분할을 위해 고려할 최대 피처 개수, default=None(모든 피처 사용)
    • int형은 대상 피처의 개수, float형은 대상 피처의 퍼센트
    • sqrt는 전체 피처 개수의 루트값 만큼 선정
    • auto는 sqrt와 동일
    • log는 전체 피처 중 log2(전체 피처 개수) 선정
  • max_depth
    • 트리의 최대 깊이 규정
    • default=None
    • 깊이가 깊어지면 min_samples_split 설정대ㅗㄹ 최대 분할하여 과적합할 수 있으므로 적절하게 제어 필요
  • max_leaf_nodes
    • 말단 노드(leaf)의 최대 개수

 

결정 트리 모델의 시각화

 

Graphviz 패키지를 이용해 시각화한다.

export_graphviz()는 학습이 완료된 Estimator, 피처의 이름 리스트, 레이블 이름 리스트를 인자로 입력받아 결정 트리 규칙을 실제 트리 형태로 시각화해서 보여준다.

결정 트리 시각화

각 지표의 의미

  • pental length(cm) <= 2.45 와 같은 피처의 조건 : 자식 노드를 만들기 위한 규칙 조건. 없으면 leaf node
  • gini : 다음의 value=[]로 주어진 데이터 분포에서의 지니 계수
  • smaples : 현 규칙에 해당하는 데이터 건수
  • value=[] : 클래스 값 기반의 데이터 건수. 이 세트는 클래스 값으로 0,1,2를 가지며, vaule=[41, 40, 39]라면 클래스 값의 순서로 0(setosa) 41개 ... 등으로 구성돼 있다는 의미.
  • 색깔이 짙어질수록 지니 계수가 낮고 해당 레이블에 속하는 샘플 데이터가 많다는 의미이다.

규칙을 정하는 데 있어 피처의 중요한 역할 지표를 DecisionTreeClassfier 객체의 feature_inportances_ 속성으로 제공한다.

feature_importanves_ 속성은 피처가 트리 분할 시 정보 이득이나 지니 계수를 얼마나 효율적으로 잘 개선시켰는지를 정규화된 값으로 표현한 것이다.

 

결정 트리 과적합(Overfitting)

 

결정 트리의 예측 수행 방식과 과적합 문제를 알아본다.

make_classification() 함수를 이용해 분류를 위한 테스트용 데이터를 쉽게 만들 수 있다. 호출시 피처 데이터 세트와 클래스 레이블 데이터 세트를 반환받는다.

특정한 트리 생성 제약이 없는 결정 트리의 학습과 결정 경계를 시각화하면 아래와 같다.

일부 이상치 데이터까지 분류하기 위해 분할이 자주 일어나 결정 기준 경계가 매우 많아졌다. 이러한 겨우 다른 형태의 데이터 세트를 예측하면 예측 정확도가 떨어진다.

 

생성 규칙을 완화한 뒤에는 아래와 같다.

# min_samples_leaf=6 으로 트리 생성 조건을 제약한 Decision Boundary 시각화
dt_clf = DecisionTreeClassifier(min_samples_leaf=6, random_state=156).fit(X_features, y_labels)
visualize_boundary(dt_clf, X_features, y_labels)

이상치에 크게 반응하지 않으며 일반화된 분류 규칙에 따라 분류됐다.

 


03. 앙상블 학습

앙상블 학습 개요

 

앙상블 학습(Ensemble Learning)을 통한 분류는 여러 개의 분류기를 생성하고 그 예측을 결합함으로써 보다 정확한 최종 예측을 도출하는 기법이다.

대부분의 정형 데이터 분류 시에는 앙상블이 뛰어난 성능을 나타낸다.

앙상블 학습의 유형에는 보팅(Voting), 배깅(Bagging), 부스팅(Boosting)의 세 가지가 있다.

 

보팅 유형 - 하드 보팅(Hard Voting)과 소프트 보팅(Soft Voting)

 

하드 보팅을 이용한 분류는 예측한 결괏값들 중 다수의 분류기가 결정한 예측값을 최종 보팅 결괏값으로 선정하는 것이다.

소프트 보팅은 분류기들의 레이블 값 결정 확률을 모두 더하고 이를 평균해서 이들 중 확률이 가장 높은 레이블 값을 최종 보팅 결괏값으로 선정한다.

일반적으로 소프트 보팅이 적용된다.

 

보팅 분류기(Voting Classifier)

 

보팅 방식의 앙상블을 구현한 VotingClassfier 클래스를 제공한다.

인자로 estimator(여러 Classifier 객체들, 튜플 형식)와 voting 값(hard/soft)을 입력받는다.

# 개별 모델은 로지스틱 회귀와 KNN 임. 
lr_clf = LogisticRegression(solver='liblinear')
knn_clf = KNeighborsClassifier(n_neighbors=8)

# 개별 모델을 소프트 보팅 기반의 앙상블 모델로 구현한 분류기 
vo_clf = VotingClassifier( estimators=[('LR',lr_clf),('KNN',knn_clf)] , voting='soft' )

X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, 
                                                    test_size=0.2 , random_state= 156)

# VotingClassifier 학습/예측/평가. 
vo_clf.fit(X_train , y_train)
pred = vo_clf.predict(X_test)
print('Voting 분류기 정확도: {0:.4f}'.format(accuracy_score(y_test , pred)))

# 개별 모델의 학습/예측/평가.
classifiers = [lr_clf, knn_clf]
for classifier in classifiers:
    classifier.fit(X_train , y_train)
    pred = classifier.predict(X_test)
    class_name= classifier.__class__.__name__
    print('{0} 정확도: {1:.4f}'.format(class_name, accuracy_score(y_test , pred)))

# output

Voting 분류기 정확도: 0.9561
LogisticRegression 정확도: 0.9474
KNeighborsClassifier 정확도: 0.9386

무조건 예측 성능이 향상되지는 않지만, 앙상블 방법은 전반적으로 단일 ML 알고리즘보다 뛰어난 성능을 가지는 경우가 많다.


04. 랜덤 포레스트

 

랜덤 포레스트의 개요 및 실습

 

배깅(Bagging)은 같은 알고리즘으로 여러 개의 분류기를 만들어서 보팅으로 최종 결정하는 알고리즘이다. 

배깅의 대표 알고리즘은 랜덤 포레스트(Random Forest)이다.

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

랜덤 포레스트

랜덤 포레스트의 개별 트리가 학습하는 데이터 세트는 일부가 중첩되게 샘플링된 데이터 세트이다.

이렇게 분리하는 것을 부트스트래핑(bootstraping) 분할 방식이라고 한다.

n_estimator 인자를 이용해 부트스트래핑 샘플링 방식을 조정하여 데이터 서브 세트를 만들 수 있다.

사이킷런의 RandomForestClassifier 클래스를 통해 랜덤 포레스트 기반의 분류를 수행할 수 있다.

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))

# output

랜덤 포레스트 정확도: 0.9253

 

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

 

트리 기반의 앙상블 알고리즘의 단점은 하이퍼 파라미터가 너무 많고, 그로 인해 튜닝 시간이 많이 소모되는 것이다.

랜덤 포레스트는 그나마 하이퍼 파라미터가 적은 편에 속한다.

  • n_estimators : 결정 트리의 개수, default=10. 늘릴수록 학습 수행 시간이 오래 걸리지만, 좋은 성능을 기대할 수 있다.(무조건 향상 x)
  • max_features : 결정 트리의 max_features와 같으나 default는 auto(sqrt)이다. 즉, 전체 피처가 16개라면 분할을 위해 4개를 참조한다.
  • max_depth나 min_samples_leaf, min_samples_split과 같이 과적합 개선을 위한 파라미터를 똑같이 사용 가능

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_estimators는 100, cv는 2로만 성정한다.
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_))

# output

최적 하이퍼 파라미터:
 {'max_depth': 16, 'min_samples_leaf': 6, 'min_samples_split': 2}
최고 예측 정확도: 0.9165

 

또한 feature_importances_ 속성을 이용해 알고리즘이 선택한 피처의 중요도를 알 수 있다.

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

# feature_importances_를 이용해 알고리즘이 선택한 피처릐 중요도 알기
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)
fig1 = plt.gcf()
plt.show()
plt.draw()
fig1.savefig('rf_feature_importances_top20.tif', format='tif', dpi=300, bbox_inches='tight')

# output(시각화)


# 회고

 

동아리와 기계학습 수업에서 배우는 부분에서 겹치는 부분이 있어서 좋다.

동아리는 이러한 함수를 이용해서 더 빠른 알고리즘을 만들고 저러한 단점이 있다~ 그리고 실습 위주라면 수업은 함수와 단점에 대해 더 자세히 배우는 느낌...여러 공식이랑 그래프(+영어)로 배우다 보니 수업은 확실히 어렵다.

 

확실히 실습 위주가 재밌는 듯. 근데 계속 이전에 배운 내용을 까먹는다...

이거도 작성하다가 GridSearchCV가 뭐였지...하고 다시 찾아봤다.

GridSearchCV이란? 뭘까? 사용 방법(예시) (velog.io)

 

GridSearchCV이란? 뭘까? 사용 방법(예시)

안녕하세요. 이번에 소개해드릴거는 GridSearchCV라는 모듈에 대해 설명해 드리고자 합니다. GridSearchCV는 머신러닝에서 모델의 성능향상을 위해 쓰이는 기법중 하나입니다. 사용자가 직접 모델의

velog.io

 열심히 하자.