from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier from sklearn.tree import export_graphviz from subprocess import check_call iris = load_iris() x = iris.data[:,2:] # 꽃잎의 길이, 너비 y = iris.target # decision tree 모형 인스턴스 생성 및 하이퍼파라미터(depth) = 3 tree_model = DecisionTreeClassifier(max_depth=3) tree_model.fit(x,y) export_graphviz( tree_model, # 학습한 모형 out_file = './iris_tree_model.dot', # .dot 파일 저장 위치 feature_names = iris.feature_names[2:], # 사용한 변수 이름 class_names = iris.target_names, # 예측할 타겟 클래스 이름 rounded=True, # 사각형 끝을 둥글게 filled=True # 사각형 안 색깔 채우기 ) # 예측한 모형 png로 바꿔서, 시각화 하기 check_call(['dot','-Tpng','iris_tree_model.dot','-o','OutputFile.png'])
⛑ 용어 정리
- Root Node(루트 노드) : 깊이가 0인 꼭대기 노드
- Leaf Node(리프 노드) : 자식 노드가 없는 마지막 노드
- Gini Impurity(지니 불순도) : 한 노드의 모든 샘플이 같은 클래스에 속해있으면, 해당 노드는 순수(gini=0)하다고 한다.
tree_model.predict_proba([[3.1,2]]) >array([[0. , 0.33333333, 0.66666667]]) # 인덱스 2번이 가장 높은 0.6666667이라는 확률값을 산출하여 2번 클래스를 예측한다. tree_model.predict([[3.1,2]]) >array([2])
위에서 말한대로 사이킷런의 결정트리 훈련 방식은 CART(Classification And Regression Tree) 알고리즘을 사용한다.
CART 알고리즘 아이디어
1.훈련 세트 중 하나의 특성과 거기에 대한 임계값을 정한다. ex) "Petal width < 2.6"
2.특성과 임계값을 고를 때는 가장 순수한(pure) 서브셋으로 나눌 수 있는 짝을 찾는다.
3.비용함수(loss function)은 다음과 같다.
4.훈련 세트를 순수하게 잘 나눴다면 위 방식을 반복적으로 지정한 max_depth만큼 서브셋으로 나눈다.
CART 알고리즘은 root node에서부터 최적의 분기를 찾으면서 최대한 불순도를 낮추려고 하는 greedy algorithm(탐욕적 알고리즘)이다.
다르게 말하면, 미래를 생각하지 않고 각 단계에서 가장 최선의 선택을 하는 기법이다. 이렇게 각 단계에서 최선의 선택을 한 것이 전체적으로도 최선이길 바라는 알고리즘, 하지만 종종 충분히 훌륭한 모델을 찾곤 한다.
presort : (기본값 = False) 피팅에서 최상의 분할을 찾는 속도를 높이기 위해 데이터를 사전 정렬할지 여부이다. 대규모 데이터 세트에 대한 의사 결정 트리의 기본 설정의 경우이를 true로 설정하면 훈련 프로세스가 느려질 수 있지만, 더 작은 데이터 세트 또는 제한된 깊이를 사용하면 훈련 속도가 빨라질 수 있습니다.
max_depth : 트리 최대 깊이
min_samples_split : 분할되기 위해 노드가 가져야 하는 최소 샘플 수
min_samples_leaf : leaf node가 가지고 있어야할 최소 샘플 수
min_weight_fraction_leaf : min_samples_leaf와 비슷하지만, 가중치가 부여된 전체 샘플 수에서의 비율
max_leaf_nodes : leaf node의 총 최대 개수
max_features : 최상의 분할을 찾을 때 고려할 기능의 수
TIP : min_으로 시작하는 매개변수 증가 => 모델 규제 증가 => 과적합 감소
TIP : max_으로 시작하는 매개변수 감소 => 모델 규제 증가 => 과적합 감소
from sklearn.tree import DecisionTreeRegressor # max_depth = 3 tree_model = DecisionTreeRegressor(max_depth=3) tree_model.fit(x,y) export_graphviz( tree_model, # 학습한 모형 out_file = './iris_tree_model_reg.dot', # .dot 파일 저장 위치 feature_names = iris.feature_names[2:], # 사용한 변수 이름 rounded=True, # 사각형 끝을 둥글게 filled=True # 사각형 안 색깔 채우기 ) # 예측한 모형 png로 바꿔서, 시각화 하기 check_call(['dot','-Tpng','iris_tree_model_reg.dot','-o','OutputFile_reg.png'])
Decision Tree(결정 트리)는 이해 및 해석이 용이하면서 예측속도가 아주 빠르고 성능도 좋다.
하지만 결정트리는 계단 모양의 Decision Boundary(결정 경계)를 만들기 때문에 훈련 세트의 회전에 아주 민감하다.
왼쪽의 그림의 경우에는 결정트리로 쉽게 classification을 할 수 있다.
하지만 왼쪽의 그림을 오른쪽 그림처럼 회전을 시키게 된다면, 결정트리는 복잡하게 형성이 된다.
만약 오른쪽의 그림을 새로운 데이터로 예측한다면 일반화되기란 어려울 것이다.
그래서 위와 같은 문제를 해결하기 위해서, PCA(Principal Component Analysis)방법을 사용할 수 있다.
다음장에서 볼 랜덤 포레스트는 많은 트리의 예측들을 평균내어서 위에서 언급한 불안정성들을 어느정도 극복할 수 있다.