일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- deep learning
- 티스토리챌린지
- 딥러닝
- AI
- 머신러닝
- 오블완
- LLM
- GPT-4
- PCA
- LG
- supervised learning
- LG Aimers
- OpenAI
- Machine Learning
- gpt
- ChatGPT
- regression
- 지도학습
- LG Aimers 4th
- 분류
- 회귀
- Classification
- 해커톤
Archives
- Today
- Total
SYDev
Chapter 05-1: 결정 트리 본문
결정 트리 알고리즘을 이해하고, 이를 이용해 분류 문제를 해결해보자.
결정 트리
- 결정 트리(Decision Tree): 분류와 회귀 모두 가능한 지도 학습 모델 중 하나로, 예/아니오 질문을 이어나가며 학습한다.
- 모델을 설명하기가 쉽다.
- 각각의 칸을 node라고 부른다.
- 첫 번째 질문이 존재하는 node는 Root node, 마지막 node는 Terminal node 혹은 Leaf node라 부른다.
결정 트리 알고리즘 작동 과정
- 깊이가 깊을 수록 정확도는 높아지지만, 지나치면 오버피팅이 될 수 있다.
불순도, 지니 인덱스, 엔트로피, 정보 이득,
불순도
- 불순도(Impurity): 해당 범주 안에 불순물이 섞여있는 정도
- 사이킷런이 제공하는 불순도에는 지니 불순도와 엔트로피 불순도가 존재한다.
- 지니 불순도(Gini impurity): 분류 작업에서 노드의 불순도를 측정하는 지표로, 0부터 1까지의 값을 가지며, 0에 가까울수록 노드의 순도가 높음을 의미한다.
- 0.5일 때, 두 클래스의 비율이 반반이 되어 최악의 상황이 됨을 의미한다.
$지니 불순도 = 1 - (음성 클래스 비율^2 + 양성 클래스 비율^2)$
지니 인덱스
- 지니 인덱스(gini index): 불순도를 측정하는 지표로서, 데이터의 통계적 분산정도를 정량화해서 표현한 값이다.
- S: 이미 발생한 사건의 모음
- c: 사건의 개수
엔트로피
- 엔트로피(Entropy): 불순도를 수치적으로 나타낸 척도
- 엔트로피가 1일 때 불순도는 최대이고, 0일 때 불순도는 최소이다.
- 다음은 좌측부터 영역 분할 전 엔트로피, 분할 후 엔트로피이다.
- $p_k$: 영역 A에 속하는 데이터 가운데 k범주에 속하는 데이터 비율
- $R_i$: 분할 전 데이터 가운데 분할 후 k범주에 속하는 데이터 비율
- 범주 1에 속하는 데이터는 빨간 원, 범주 2에 속하는 데이터는 파란 원으로 취급한다.
- 주황색 선에 둘러싸인 영역 A의 엔트로피와 분할 이후의 엔트로피는 다음과 같다.
- 분할 전보다 분할 후에 엔트로피가 감소한 것으로 보아, 분할을 유지하는 것이 더 낫다고 판단된다.
정보 이득
- 정보 이득(Information gain): 주어진 속성이나 특성을 기준으로 데이터를 분할할 때, 얻을 수 있는 정보의 양을 측정하는 지표이다.
- 엔트로피가 1인 상태에서 0.7로 바뀌었다면 정보 이득은 0.3이다.
- 분기 이전(부모 노드)의 엔트로피에서 분기 이후(자식 노드)의 엔트로피를 뺀 수치를 정보 이득이라고 한다.
Information gain = entropy(parent) - [weighted average] entropy(children)
- [weighted average] entropy(children): entropy(children)의 가중평균
- 가중평균을 구하는 이유는, 분기 이후에 범주가 2개 이상으로 쪼개지기 때문이다.
>> 결정 트리 알고리즘은 불순도를 기준으로 정보 이득이 최대가 되도록 노드를 분할한다!
+ 여기서는 엔트로피 불순도를 기준으로 했지만, 지니 불순도 역시 기준이 될 수 있다.
가지치기
- 가지치기(pruning): 터미널 노드가 순수 노드가 된 상태를 Full tree라고 하는데, 이 경우에는 훈련 데이터셋에 과대적합이 될 우려가 있기 때문에 적절하게 터미널 노드를 합쳐줘야 한다. 이를 가지치기라 부르는데, 가지치기의 종류에는 사전 가지치기(pre-pruning)와 사후 가지치기(post-pruning)가 있다.
- 사전 가지치기(pre-pruning): 트리 생성을 일찍 중단하는 방식으로, 트리의 최대 깊이나 터미널 노드의 개수를 사전에 제한하는 방식
- 사후 가지치기(post-pruning): 트리를 만든 후 데이터 포인트가 적은 노드를 삭제하거나 병합하는 방식
- 사이킷런에서는 사전 가지치기만 지원한다.
로지스틱 회귀로 와인 분류
#와인 데이터셋 넘파이 배열로 변환
import pandas as pd
wine.head()
wine.info()
wine.describe()
data = wine[['alcohol', 'sugar', 'pH']].to_numpy()
target = wine['class'].to_numpy()
#훈련, 테스트 데이터셋 분리
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(data, target, test_size=0.2, random_state=42)
print(train_input.shape, test_input.shape)
(5197, 3) (1300, 3)
- 레드 와인과 화이트 와인을 구분하는 이진 분류 문제
- 클래스 0이면 레드 와인, 1이면 화이트 와인
- 화이트 와인이 양성 클래스
- alcohol, sugar, pH의 scale이 다르기 때문에 표준화 과정이 필요하다.
#데이터셋 표준화
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)
#로지스틱 회귀 알고리즘으로 학습
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
lr.fit(train_scaled, train_target)
print(lr.score(train_scaled, train_target))
print(lr.score(test_scaled, test_target))
print(lr.coef_, lr.intercept_)
0.7808350971714451
0.7776923076923077
[[ 0.51270274 1.6733911 -0.68767781]] [1.81777902]
- 훈련, 테스트 데이터셋에서 모두 점수가 낮은 것으로 보아, 모델이 과소적합되었다.
- 회귀 알고리즘의 가중치와 계수를 보고 직관적으로 모델을 설명하기가 어렵다.
결정 트리로 와인 분류
#결정 트리 알고리즘으로 학습
from sklearn.tree import DecisionTreeClassifier
dt = DecisionTreeClassifier(random_state=42)
dt.fit(train_scaled, train_target)
print(dt.score(train_scaled, train_target))
print(dt.score(test_scaled, test_target))
0.996921300750433
0.8592307692307692
-> 과대적합!
#학습시킨 모델을 그림으로 표현
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
plt.figure(figsize=(10,7))
plot_tree(dt)
plt.show()
#최대 깊이를 1로 설정
plt.figure(figsize=(10,7))
plot_tree(dt, max_depth=1, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()
- 매개변수 filled=True로 설정하면 특정 클래스의 비율이 높아질수록 색이 진해짐
#최대 깊이를 3으로 설정
dt = DecisionTreeClassifier(max_depth=3, random_state=42)
dt.fit(train_scaled, train_target)
print(dt.score(train_scaled, train_target))
print(dt.score(test_scaled, test_target))
#최대 깊이가 3인 결정 트리의 형태
plt.figure(figsize=(20,15))
plot_tree(dt, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()
0.8454877814123533
0.8415384615384616
- 당도가 -0.239보다 작고 -0.802보다 크며, 알코올 도수는 0.454보다 작아야 음성 클래스를 가리키는 3번째 터미널 노드에 도달할 수 있다.
- -0.239, -0.082의 당도는 직관적으로 이해하기 어려운 수치이며, 결정 트리에서는 표준화 전처리의 영향을 받지 않기 때문에 표준화되기 전의 데이터셋을 사용해보자.
#표준화 이전의 데이터셋으로 모델 훈련
dt = DecisionTreeClassifier(max_depth=3, random_state=42)
dt.fit(train_input, train_target)
print(dt.score(train_input, train_target))
print(dt.score(test_input, test_target))
plt.figure(figsize=(20,15))
plot_tree(dt, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()
0.8454877814123533
0.8415384615384616
-> 전처리 전과 차이가 없다.
-> 표준화되지 않아 노드의 분기 기준이 직관적으로 이해하기 쉽다.
print(dt.feature_importances_)
[0.12345626 0.86862934 0.0079144 ]
-> 가장 중요한 특성은 두 번째 특성인 sugar!
참고자료
- 박해선, <혼자 공부하는 머신러닝+딥러닝>, 한빛미디어(주), 2022.2.4
- https://bkshin.tistory.com/entry/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-4-%EA%B2%B0%EC%A0%95-%ED%8A%B8%EB%A6%ACDecision-Tree
'KHUDA 4th > 머신러닝 기초 세션' 카테고리의 다른 글
Chapter 05-3: 트리의 앙상블 (0) | 2023.08.22 |
---|---|
Chapter 05-2: 교차 검증과 그리드 서치 (1) | 2023.08.22 |
[KHUDA 4th] 머신러닝 3주차 기초 세션 (08.16) (1) | 2023.08.19 |
Chapter 04-2: 확률적 경사 하강법 (0) | 2023.08.14 |
경사 하강법 (0) | 2023.08.13 |