일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 백엔드
- 프로젝트
- randomForest
- 2차 실전프로젝트
- springSTS
- intent
- 국비지원
- 선형모델 분류
- 내일배움카드
- 안드로이드
- 머신러닝
- JSP/Servlet
- 비스포크시네마
- ERD
- 활성화함수
- 스마트인재개발원
- 크롤링
- 1차프로젝트
- MVCmodel
- KNN모델
- MSE
- 교차검증
- 손실함수
- 오픈소스깃허브사용
- gitclone
- 취업성공패키지
- 하이퍼파라미터튜닝
- semantic_segmentation
- 2차프로젝트
- 취업연계
- Today
- Total
또자의 코딩교실
[스마트인재개발원] 머신러닝 - Decision Tree 알고리즘(실습과 함께) 본문
Decision Tree Model이란?
= 컴퓨터가 혼자 질문과 답을 진행하는 스무고개.
= 질문에 따라 예/아니오로 답하며 데이터를 나누며 나눠지지 않을 때 까지 나누는 과정을 반복하여 학습하는 모델.
분류와 회귀에 모두 사용가능하다.
새로운 데이터가 들어오면 해당하는 범주를 찾아 분류라면 더 많은 클래스를 선택하고, 회귀라면 평균을 구하는 방식으로 작동한다.
특성중요도를 계산하여 어떤 특성이 분류를 가장 효율적으로 수행하는지 계산하여 제공할 수 있다.
Decision Tree Model은 어떤식으로 모델이 학습을 진행했는지 시각화 하여 display하기 좋지만,
질문에 따라 데이터를 흑/백으로 일일히 나누려하는 기본적인 작동방식때문에
질문들이 많아질수록 train data에 대해 세세한 공부를 해버려 과대적합이 되기 굉장히 쉬운 단점을 가진다.
Decision Tree의 장단점
- 장점
- 모델의 쉬운 시각화 (white box model)
- 각 특성이 개별처리 되어 데이터 스케일에 영향을 받지 않는다. 따라서 knn과 달리 특성의 정규화나 표준화가 필요하지 않다.
- 트리 구성시에 각 특성의 중요도를 계산하기 때문에 특성 선택(Feature selection)에 활용될 수 잇다.
- 단점
- 가지치기를 사용함에도 불구하고 과대적합되는 경향이 있어 일반화 성능이 좋지 않다.
- 기울기가 있는 데이터들을 분리하기에 쉽지 않다.
이를 극복하기 위해 과대적합을 제어하기 위한 세부 설정 특성을 많이 준비하여 보완하려는 시도가 있었다.
먼저 Decision Tree의 기본적인 구성요소를 그림으로 간략히 나타낸 사진을 보면서 같이 설명하겠다.
사진을 먼저 설명하자면
각각 root node는 분기점을 나누는 최초의 질문이며,
leaf node는 분기점의 종착지인 마지막 고유속성값이다.
depth는 root node로 부터 해당 노드가 떨어진 거리이다. 이는 즉, 물어보는 질문의 갯수이다.
이를 머신러닝에서는 세부설정으로 지정할 수 있는데 바로 아래의 매개변수 항목들을 제어함으로써 가능하다.
Deicision Tree Model Parameter
- max_depth : depth의 최대값을 제한시키는 것
- (ex. max_depth =3 : 내 아래로 질문은 각각 3개까지만!)
- max_leaf_nodes : 불순도가 낮은 순으로 질문들을 제어하면서 최종 leaf node의 갯수를 지정하는 것
- (ex. max_leaf_nodes = 17 : 최종 순수 노드값이 17개가 되면 더이상의 질문을 멈춰라!)
- min_sample_split : 노드가 분할 하기 위한 sample 데이터 포인트의 최소 개수를 지정
- (ex. min_sample_split = 100 : train data를 질문으로 나눈다가 쪼개서 나오는 질문 노드의 sample 갯수가 100이하일 경우 더이상의 질문을 멈춰라!)
- min_sample_leaf : 리프 노드를 구성하는 최소 샘플의 개수를 지정
- (ex. min_sample_leaf = 150 : train data를 질문으로 나눈다가 쪼개서 나오는 리프 노드(=답 노드)의 갯수가 150이하일 경우 더이상의 질문을 멈춰라!)
- criterion : 불순도 측정방법. 지니 불순도를 확인하거나 entropy를 확인한다.
- 지니 불순도 (Gini Impurity) : 질문을 선택할 때에 있어 순수한 집단의 기준으로 나누는 기준을 판단하는 척도.최대치가 0.5인 수치로 0이 될수록 잘 분리가 되었다 판단 가능하다.
- entropy : 정보량을 의미. 높을수록 정보가 많은 상태이지만 정보가 참일 확률은 낮아진다.. 지니 불순도보다 구간이 두배로 더 넓다.
- 지니 불순도의 구간은 [0, 0.5]인 반면, 엔트로피의 구간은 [0, 1.0]이다.
- 계산에 로그를 사용하기 때문에 더 복잡하고 결과적으로 불순도의 계산이 더 빨라진다.
사전 가지치기 vs 사후 가지치기
사전 가지치기 = Decision Tree Model Parameter 제어
사후 가지치기 = 아래층 노드부터 합해가는 과정. 교차검증 점수가 최소가 되는 분할이 되도록 트리를 줄임.
이제 mushroom 데이터를 활용한 이진분류 문제를 통해 실습하며 Decision Tree Model을 학습해보자.
#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#원본 데이터 read_csv
data = pd.read_csv("data/mushroom.csv")
#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#train 문제 data 및 답 data 분리
X=data.loc[:,'cap-shape':]
y=data.loc[:,'poisonous']
#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#문제데이터의 구성요소 파악
X['cap-shape'].value_counts()
#실행결과
x 3656
f 3152
k 828
b 452
s 32
c 4
Name: cap-shape, dtype: int64
문제데이터와 답 데이터를 분리하고 나면 나오는 결과는 모두 text형태의 범주형 데이터이다.
Decision Tree Model은 Object형태의 데이터를 학습할 수 없기 때문에 int64자료형을 가진 수치형 데이터로 바꿔주는 작업을 진행하여 학습해야한다.
따라서 Encoding을 진행한다. (반대로 Int64 > Object 형태는 Binning)
파이썬에서 인코딩은 바꿀 데이터들에 대한 딕셔너리를 만들어 map함수로 바꾸어주는 방법과 원핫인코딩으로 인코딩을 진행하는 총 두가지의 방법이 있다.
원핫 인코딩은 0으로 이루어진 벡터에 단 한개의 1의 값으로 해당 데이터의 값을 구별하는 것이다. 매우 기초적이면서도 아주 흔히 사용되는 기법으로 딥러닝 뿐만 아니라 데이터 마이닝, 자연어 처리 등 아직도 많은 분야에서 사용되고 있는 기법이다.
다음은 인코딩과정을 진행하는 코드이다.
#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#map함수를 사용한 인코딩
#Label Incoding
#copy() 해당 데이터 프레임의 내용을 복사해서 새로운 데이터 프레임을 만들어줌.
X1 = X.copy()
X1['cap-shape'] = X1['cap-shape'].map({'x':0, 'b':1, 's':2, 'f':3, 'k':4, 'c':5})
# 바꾼 데이터 라벨링을 다시 cap-shape에 넣어 변경해준다.
#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#One-Hot 인코딩
X2 = X.copy()
X_one_hot = pd.get_dummies(X2)
#get_dummies 함수를 이용해 원핫인코딩 진행
인코딩을 진행한 데이터들을 train_test_split함수를 통해 분리한 후 모델링(모델 선택, 모델 학습, 모델 평가)를 진행하겠다. 다음은 모델링 과정을 진행하는 코드이다.
#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#train_test_split 함수를 통해 데이터 분리
X_train, X_test, y_train, y_test = train_test_split(X_one_hot,y, test_size=0.3,
random_state=777)
X_train.shape, X_test.shape, y_train.shape, y_test.shape
#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#모델 선택
tree_model = DecisionTreeClassifier()
#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#모델 학습 및 평가
tree_model.fit(X_train, y_train)
tree_model.score(X_train, y_train)
tree_model.score(X_test, y_test)
#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#결정 트리 과정 직접적으로 확인하기
from sklearn.tree import export_graphviz
export_graphviz(tree_model, out_file='tree.dot',
#(tree model에는 아무런 파라미터를 주지 않아서 순수노드로 변할때 까지 영원히 쪼개버림)
class_names=['식용','독'],
feature_names=X_one_hot.columns,
impurity=True, #True일 경우 지니 불순도가 얼마인지 표시됨.
filled=True) #색깔 채우기
import graphviz
with open('tree.dot', encoding='UTF-8') as f:
dot_graph = f.read()
display(graphviz.Source(dot_graph))
각각의 정확도는 1.0이 나왔다. 코드의 결과로 확인한 시각화된 결정트리 과정은 다음과 같다.
samples = K 해당 조건에 해당하는 데이터의 갯수 (n+p=K)
value = [n,p] 각각 0번째 조건에 해당하는 갯수, 각각 1번째 조건에 해당하는 기준으로 value의 모든 값을 더하면 samples 수와 일치한다.
하얀색으로 가까워 질 수록 지니계수가 높은 질문(=불순도가 높아 분류가 정확하게 되지 않았던 질문)이다.
모든 노드가 순수 노드까지 잘 나왔으나 생략된 형태이다.
과대적합이 될 가능성이 있다.
이제는 Decision Tree를 통한 특성중요도를 확인해보자.
imp =tree_model.feature_importances_
#tree_model.feature_importances_() >> () 존재 >> method
#tree_model.feature_importances_ >> () 존재 X >> field
#오타 주의!
fi_s = pd.Series(imp, index=X_one_hot.columns, name='imp')
fi_s.sort_values(ascending=False) #ascending = False : 내림차순으로 정렬해라.
#ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
#실행 결과
odor_n 0.618109
stalk-root_c 0.176252
stalk-surface-below-ring_y 0.087053
spore-print-color_r 0.035702
gill-spacing_w 0.024559
...
gill-color_g 0.000000
gill-color_e 0.000000
gill-color_b 0.000000
gill-size_b 0.000000
habitat_w 0.000000
Name: imp, Length: 117, dtype: float64
실행 결과를 통해 가장 중요한 특성은 odor_n이란 것을 확인할 수 있다.
'코딩공부 > 머신러닝 & 딥러닝' 카테고리의 다른 글
[스마트인재개발원] 머신러닝 - 정규화 (0) | 2021.12.09 |
---|---|
[스마트인재개발원]머신러닝 - 교차검증 (0) | 2021.12.08 |
[스마트인재개발원] 근본중의 근본) iris 데이터를 활용한 KNN 분류실습 (0) | 2021.12.08 |
[스마트인재개발원] Kaggle 경진대회 (스압주의) (0) | 2021.12.06 |
[스마트인재개발원] 머신러닝을 통한 Kaggle 데이터 분석하기 (0) | 2021.11.29 |