DecisionTree / RandomForest

김혜인·2023년 5월 25일

머신러닝

목록 보기
9/11

의사결정나무(DecisionTree)

  • 질문해서 데이터 분류(yes/no)
    - 분류: 불순도 낮추도록
    - 회귀: 오차가 적도록

용어

  • Root Node : 시작 node
  • Decision Node (Intermediate Node): 중간 node
  • Leaf Node(Terminal Node) : 마지막 단계(트리의 끝)에 있는 노드

하이퍼파라미터

  • max_depth : 트리 최대 깊이(default: 불순도:0/MSE:0)
  • max_leaf_nodes : leaf node개수 제한(default: None:제한 X)
  • min_samples_leaf : leaf node 최소 sample수 지정(비율로도O), (default: 1:제한X )
  • max_features : 지정한 개수의 feature만 사용
  • min_samples_split : 분할을 위한 최소 필요 샘플 수:n개보다 적은 샘플은 더 이상 분할X(default: 2)
  • criterion : 각 노드의 불순도 계산 방식(분류: gini(default), entropy/회귀:squared_error(default), absolute_error, friedman_mse, poisson)

Feature(컬럼) 중요도 조회

  • featureimportances : feature별 중요도 반환

  • wine dataset : color 분류

#데이터 불러오기
import pandas as pd

wine = pd.read_csv('data/wine.csv')


#데이터 분리
X = wine.drop(columns='color')
y = wine['color']

##quality를 Label Encoding 처리
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
le.fit(['A','B','C'])
X['quality'] = le.transform(X['quality'])

#train/test 분리
from sklearn.model_selection import train_test_split
X_train, X_test, y_train,y_test = train_test_split(X, y, test_size=0.25, stratify=y, random_state=0)

from sklearn.tree import DecisionTreeClassifier
tree = DecisionTreeClassifier(random_state=0)

tree.fit(X_train, y_train)

#학습 한 tree정보
tree.get_depth() # depth, level을 조회  >>max_depth
tree.get_n_leaves() #leaf node의 개수

#함수로 평가결과 조회
from metrics import print_metrics_classification
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], 'Test set 평가결과')


#각 feature(컬럼)의 중요도(점수)
tree.feature_importances_
  • graphviz로 tree구조 시각화
### graphviz를 이용해 tree 구조 시각화
from sklearn.tree import export_graphviz
from graphviz import Source
graph = Source(export_graphviz(tree, #학습한 DecisionTree 모델
                               feature_names = X_train.columns,
                               class_names=['White', 'Red'],
                               rounded = True,
                               filled=True
                              ))

GridSearchCV
max_dept
max_leaf_nodes
min_samples_leaf
max_features

-기준: 정확도

-feature importances_ 확인
-tree 구조 확인(graphviz)

from sklearn.model_selection import GridSearchCV 

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 = GridSearchCV(DecisionTreeClassifier(random_state=0), 
                  params, 
                  scoring="accuracy",
                  cv=5, 
                  n_jobs=-1)
gs.fit(X_train, y_train)

print('best_score:', gs.best_score_)
print('best param:', gs.best_params_)

best_model = gs.best_estimator_

fi = pd.Series(best_model.feature_importances_, index=X.columns)
fi.sort_values(ascending=False)

graph = Source(export_graphviz(best_model,
                feature_names = X.columns,
                class_names=['White', 'Red'],
                filled=True,
                rounded=True))

-회귀

import pandas as pd
from sklearn.model_selection import train_test_split

def get_boston_dataset(path='data/boston_hosing.csv', test_size=0.25):
    df = pd.read_csv(path)
    X = df.drop(columns='MEDV')
    y = df['MEDV']
    dataset = train_test_split(X, y, test_size=test_size, random_state=0)
    return dataset

from dataset import get_boston_dataset

X_train, X_test, y_train, y_test = get_boston_dataset()
X_train.shape, X_test.shape

#모델링
from sklearn.tree import DecisionTreeRegressor
tree_rg = DecisionTreeRegressor(max_depth=2, random_state=0)
tree_rg.fit(X_train, y_train)

graph2 = Source(export_graphviz(tree_rg, 
                                feature_names=X_train.columns,
                                filled=True,
                                rounded=True))

Ensemble(앙상블)

  • 여러모델 사용 > 학습 > 결합
  • for 과적합X, 성능 ↑
  • 투표방식
  • 부스팅

Random Forest(랜덤포레스트)

  • Decision Tree 기반

주요 하이퍼파라미터

  • n_estimators : DecisionTree 모델의 개수 (클수록 좋음)
  • max_features : 선택할 feature 개수(클수록 feature 차이 크고, 작을 수록 차이가 적게 남)
  • DecisionTree의 하이퍼파라미터들(Tree의 최대 깊이, 가지를 치기 위한 최소 샘플 수 등)
#데이터 분리
X_train, X_test, y_train, y_test = get_wine_dataset()

#모델 생성, 학습, 검증
from sklearn.ensemble import RandomForestClassifier

rfc = RandomForestClassifier(n_estimators=500, #DecisionTree 모델 개수(최소 200개 이상)
                             max_features=10, #sampling할 feature의 개수, default: 'auto' - sqrt(전체feature수)
                             max_depth=5, #500개의 decisiontree에 공통적으로 적용될 hyper parameter
                             random_state=0,
                             n_jobs=-1
                            )

#학습
rfc.fit(X_train,y_train)

#검증
pred_train = rfc.predict(X_train)
pred_test = rfc.predict(X_test)

proba_pos_train = rfc.predict_proba(X_train)[:,1]
proba_pos_test = rfc.predict_proba(X_test)[:,1]

print_metrics_classification(y_train,pred_train, proba_pos_train,'train set')
print_metrics_classification(y_test,pred_test, proba_pos_test,'test set')

#feature importance
fi_rf = pd.Series(rfc.feature_importances_, index=X_train.columns)
fi_rf = fi_rf.sort_values(ascending=False)

-GridSearch

#데이터 로드
(X_train, X_test, y_train, y_test), feature_names = get_breast_cancer_dataset() #scaling=True)
print(X_train.shape, X_test.shape)
print(X_train.mean(axis=0))
print(X_train.std(axis=0))

#모델 생성
params = {
    "n_estimators":range(100,501,100),
    "max_features":range(1,31),
    'max_depth':range(1,6,1),
    'min_samples_leaf':range(4,50)
    
}
rfc = RandomForestClassifier(random_state=0)
gs = GridSearchCV(rfc, params, scoring='accuracy', cv=4, n_jobs=-1)

#학습
gs.fit(X_train,y_train)

print(gs.best_score_)
print(gs.best_params_)

result_df = pd.DataFrame(gs.cv_results_).sort_values('rank_test_score')

best_model = gs.best_estimator_
fi = pd.Series(best_model.feature_importances_, index=feature_names).sort_values(ascending=False)

pred_test = best_model.predict(X_test)
print_metrics_classification(y_test, pred_test)

0개의 댓글