포스팅 목적
결정트리 Decision Tree Classifier와
결정트리를 기반으로 앙상블 학습하는 Random Forest에서 확인할 수 있는
피쳐 중요도에 대해 정리해보는 시간.
다른 학습기들에서도 똑같이 사용할 수 있는지는 아직 모르겠다.
feature_importances_ 프로퍼티에 대해 간단히 알아보자.
피쳐 중요도
이 프로퍼티 feature_importances_는 결정트리에서 노드를 분기할때,
해당 피쳐가 클래스를 나누는데 얼마나 영향을 미쳤는지를 표기하는 척도이다.
노말라이즈된 ndarray를 반환하기 때문에 0~1값을 가진다.
0이면 클래스를 구분하는데 해당 피쳐가 선택되지 않았다는것,
1이면 해당 피쳐가 클래스를 완벽하게 나누었다는것을 의미한다
실습1: iris basic
우선 iris 데이터셋에 아래와같이 간단한 결정트리를 만들어보자.
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
import numpy as np
# 내가 사랑하는 붓꽃 데이터셋 로드
iris = load_iris()
# 결정트리 생성
dt = DecisionTreeClassifier()
# 성능을 시험할 것은 아니니까 모든 데이터셋을 학습시킨다
dt.fit(iris.data, iris.target)
# feature importance 추출
print('피쳐 목록:\n\t{0}'.format(iris.feature_names))
print("피쳐 중요도:\n\t{0}".format(np.round(dt.feature_importances_, 2)))
피쳐는 sepal length, sepal width, petal length, petal width 네 가지가 있는데
붓꽃 클래스를 결정트리로 분류하는데에는 petal length와 width값이 중요하게 작용하는것으로 보인다.
이 세번째, 네번째 피쳐의 중요도를 합치면 거의 1에 수렴하므로,
앞의 두 피쳐는 클래스를 구분하는 데 미치는 영향이 미미하다는 뜻이 된다.
sepal length와 width를 x축과 y축으로 산점도를 그려보면 아래와 같다.
두개의 피쳐만으로도 클래스가 충분히 잘 구분된다는 것을 확인할 수 있다.
import matplotlib.pyplot as plt
plt.scatter(iris.data[:,2], iris.data[:,3],
c=iris.target, s=25, cmap='rainbow', edgecolor='k')
실습2: many features
이번엔 한 발 나아가, 위스콘신 유방암 데이터셋에 랜덤 포레스트를 적용하는 경우를 실습해보자.
유방암 데이터셋은 피쳐가 많아 한눈에 보기 어렵다.
이런 경우 처리하는 로직을 간단하게 정리해두려 한다.
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import f1_score
import pandas as pd
# 위스콘신 유방암 데이터 로드, train_test_split으로 데이터 나누기
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, test_size=0.2)
# 기본설정 랜덤포레스트
rf = RandomForestClassifier(n_jobs=-1) # 모든 코어 사용
# 피쳐중요도만 확인할 것이기 때문에 fit만 한다.
rf.fit(X_train, y_train)
# 그냥 확인하기에 피쳐종류가 30개나 되어 한눈에 들어오지 않는다.
print(rf.feature_importances_, '\n')
# 시리즈로 만들어 인덱스를 붙인다
ser = pd.Series(rf.feature_importances_, index=cancer.feature_names)
# 내림차순 정렬을 이용한다
top15 = ser.sort_values(ascending=False)[:15]
print(top15)
위와 같이 피쳐들이 30개나 되는 경우, 육안으로 어떤 피쳐가 중요한 지 확인하기 어렵다.
Series를 만들어 sort_values()를 이용해 중요도 순으로 상위 피쳐들만 뽑는 코드를 작성했다.
아래는 이를 barplot으로 시각화한 코드를 작성했다.
barplot에다가 시리즈만 x와 y에 넣어주면 간단하게 막대그리프를 그릴 수 있다.
import matplotlib.pyplot as plt
import seaborn as sns
plt.figure(figsize=(8,6))
plt.title('Feature Importances Top 15')
sns.barplot(x=top15, y=top15.index)
plt.show()
Conclusion
feature_importances_에 대해 알아보았다.
실습1: iris basic
iris 데이터셋의 petal 값만으로 그래프를 그렸는데, 꽤 잘 클래스가 구분되는것을 관찰할 수 있었다!
해당 피쳐의 중요도값이 1에 가까우면, 그만큼 클래스 구분이 잘 된다는 것을 알 수 있었다.
실습2: many features
위스콘신 유방암 데이터세트를 이용하여 랜덤포레스트 코드를 작성했다.
피쳐가 30개나 되어 한눈에 확인하기 어려웠다.
판다스 시리즈를 이용하여 sort_values()메소드로 내림차순 정렬하였고,
seaborn barplot 그래프를 써서 시각화하였다.
'PL > Python' 카테고리의 다른 글
Pandas merge함수 사용법 기초 (0) | 2022.10.26 |
---|---|
numpy.r_ 연산자 사용법 (0) | 2022.10.21 |
[seaborn] barplot 기초 (0) | 2022.10.18 |
데이터분석: 카디널리티 (Cardinality) (0) | 2022.10.18 |
graphviz 설치 및 기본 사용법 개요 (1) | 2022.10.18 |
댓글