의사결정나무(Decision Tree)
분기를 아무때나하나?
분기를 하는 기준이 무엇인가?
근데 잠깐
순도(purity)/불순도(impurity)가 뭔데?
그럼 이제 의사결정트리에서 사용되는 용어에 대해 알아보자.
앞의 포스팅에서 과대적합과 일반화에 다뤘었던 것을 기억해보자.
여기에서도 과대적합(Overfitting) 문제가 발생할 수 있다.
의사결정트리에서 사용하는 최적의 성능을 찾기위한 하이퍼파라미터가 있다.
컬럼들의 중요도도 조회할 수 있다.
개념은 이제 이해가 되었다면 예제를 보자.
Wine Dataset을 이용하여 color를 분류할 것이다.
데이터셋: Wine Dataset
import pandas as pd
wine = pd.read_csv('data/wine.csv')
wine.shape
결과: (6497, 13)
데이터셋의 정보를 확인해보자.
wine.info()
이번에는 0,1로 이루어져서 target으로 분리할 color의 0,1개수를 검색해보자.
wine['color'].value_counts(normalize=True)
자 그럼 데이터셋 사용에 앞서 어떤 식으로 이루어져있는지 확인했으니 본격적으로 시작해보자.
# 1. X, y 분리
X = wine.drop(columns='color')
y = wine['color']
X.shape, y.shape
결과: ((6497, 12), (6497,))
# 2. quality를 Label Encoding 처리
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit(['A', 'B', 'C']) # 리스트 학습
X['quality'] = le.transform(X['quality']) # 변환
# 확인
X["quality"].value_counts()
에서
로 변환되었다.
from sklearn.model_selection import train_test_split, GridSearchCV, RandomizedSearchCV
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
from graphviz import Source
from metrics import print_metrics_classification
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, stratify=y, random_state=0)
tree = DecisionTreeClassifier(random_state=0)
tree.fit(X_train, y_train)
# depth, level을 조회
tree.get_depth()
결과: 13
# leaf node의 개수
tree.get_n_leaves()
결과: 55
X_train이 1일때로 조회
print_metrics_classification(y_train,
tree.predict(X_train),
tree.predict_proba(X_train)[:, 1],
"Train set 평가결과")
print_metrics_classification(y_test,
tree.predict(X_test),
tree.predict_proba(X_test)[:, 1],
"Testset 평가결과")
test set이 train set보다는 성능이 떨어지지만 0.9대로 좋은 성능을 나타낸다.
# graphviz를 이용해 tree 구조 시각화
graph = Source(export_graphviz(tree, #학습한 DecisionTree 모델
feature_names=X_train.columns,
class_names=["White", "Red"],
rounded=True,
filled=True
))
graph
# 각 feature(컬럼)의 중요도 (점수)
fi = pd.Series(tree.feature_importances_, index=X.columns)
fi.sort_values(ascending=False)
total sulfur dioxide과 chlorides 중요도가 높은 것을 확인 할 수 있다.
# GridSearch를 이용해 최적의 파라미터 조회
params = {
"max_depth":range(1, 14),
"max_leaf_nodes":range(10, 34),
"min_samples_leaf":range(10, 1000, 50),
"max_features":range(1, 13)
}
gs = RandomizedSearchCV(DecisionTreeClassifier(random_state=0),
params, scoring='accuracy', cv=5, n_jobs=-1, n_iter=60)
gs.fit(X_train, y_train)
print("best score:", gs.best_score_)
print("best param:", gs.best_params_)
best score: 0.9696222818933291
best param: {'min_samples_leaf': 110, 'max_leaf_nodes': 22, 'max_features': 9, 'max_depth': 3}
best_model = gs.best_estimator_
fi = pd.Series(best_model.feature_importances_, index=X.columns)
fi.sort_values(ascending=False)
최적의 파라미터로 구한 total sulfur dioxide과 chlorides 중요도가 더 높은 것을 확인할 수 있다.
graph = Source(export_graphviz(best_model,
feature_names=X.columns,
class_names=["White", "Red"], filled=True, rounded=True))
graph
Ensemble(앙상블)
하나의 모델만을 학습시켜 사용하지 않고 여러 모델을 학습시켜 결합하는 방식으로 문제를 해결하는 방식이다.
개별로 학습한 여러 모델을 조합해 과적합을 막고 일반화 성능을 향상시킬 수 있다.
앙상블의 종류(투표방식 / 부스팅)
투표방식(Bagging / Voting)
부스팅(Boosting)
투표방식 중의 하나인 같은 유형의 알고리즘들을 조합하되 각각의 학습하는 데이터는 다르게하는 Bagging 방식을 기반으로 하는 Random Forest (랜덤포레스트)에 대하여 알아보자.
Random Forest (랜덤포레스트)
주요 하이퍼파라미터