Python/ML & DL 공부

[ML] 05-1 결정 트리

dori_0 2022. 3. 11. 00:05

혼자 공부하는 머신러닝+딥러닝 책을 바탕으로 공부한 내용입니다.

 

CH5 트리 알고리즘 ①

화이트 와인을 찾아보자

 


 

알코올 도수, 당도, pH 데이터를 기준으로 화이트 와인을 골라내보자
로지스틱 회귀 모델, 결정 트리

 

 

▶ 로지스틱 회귀로 와인 분류하기

# 6,497개 와인 샘플 데이터 불러오기
import pandas as pd
wine = pd.read_csv("https://bit.ly/wine_csv_data")
wine.head()

  • class은 타깃값으로 0이면 레드 와인, 1이면 화이트 와인(양성 클래스)이다.

 

데이터를 살펴보자

wine.info()

  • 결측치는 없는 것으로 확인된다
wine.describe()

  • alcohol, sugar, pH의 스케일이 다르므로 표준화 전처리를 해주어야 한다.

 

train set, test set으로 나누고 표준화 전처리를 해주자

 

이때, 샘플의 개수가 많기 때문에 20%만 test set으로 지정해주었다.

( train_test_split() 함수는 설정값을 지정하지 않으면 25%를 test set으로 지정한다. )

# train set, test set으로 나누기
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)

# 표준화 전처리
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)

  • train set는 5,197개 test set는 1,300개로 잘 나눠진 것을 확인할 수 있다.

 

이제 로지스틱 회귀 모델을 훈련하고 점수를 출력해보자

# 로지스틱 회귀 모델 훈련
from sklearn.linear_model import LogisticRegression
lr = LogisticRegression()
lr.fit(train_scaled, train_target)
print(lr.score(train_scaled, train_target))  #0.7808350971714451
print(lr.score(test_scaled, test_target))  #0.7776923076923077
  • train set, test set의 점수가 모두 낮은 것으로 보아 다소 과소적합 된 것으로 보인다.

 

 

▶ 결정 트리

이번에는 DecisionTreeClassifier 클래스를 사용해 결정 트리 모델을 훈련해보자

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))

# 결정 트리 그려보기
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
plt.figure(figsize=(10,7))
plot_tree(dt)
plt.show()

  • 맨 위의 노드를 루트 노드, 맨 아래의 노드를 리프 노드라고 한다

 

 

결정 트리를 자세히 살펴보자

max_depth로 노드의 개수 지정, filled=True로 노드의 색 지정, feature_names로 특성의 이름을 전달하였다.

# 자세히 살펴보기
plt.figure(figsize=(10,7))
plot_tree(dt, max_depth=1, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()

  • 루트 노드에서 당도가 -0.239 이하이면 왼쪽 가지, 그렇지 않으면 오른쪽 가지로 간다.
  • 리프 노드에서 가장 많은 클래스가 예측 클래스가 된다

 

 

▶ 불순도

gini ( 지니 불순도 )

  • DecisionTreeClassifier 클래스의 criterion 매개변수의 기본값
    • criterion='entropy'를 지정하면 엔트로피 불순도를 사용할 수 있음
    • 지니 불순도는 제곱을 사용하지만 엔프로피 불순도는 밑이 2인 로그를 사용
  • 지니 불순도 = 1 - (음성 클래스 비율²+ 양성 클래스 비율²)
  • 순수 노드 : 노드에 하나의 클래스만 있어 지니 불순도가 0이 되는 경우
  • 결정 트리 모델은 부모 노드(parent node)와 자식 노드(child node)의 불순도 차이가 가능한 크도록 트리를 성장시킴

 

정보 이득

  • 부모 노드와 자식 노드의 불순도 차이
  • 정보 이득 = 부모의 불순도 - (왼쪽 노드 샘플 수 / 부모의 샘플 수) X 왼쪽 노드 불순도 - (오른쪽 노드 샘플 수 / 부모의 샘플 수) X 오른쪽 노드의 불순도

 

 

▶ 가지치기

결정 트리에서 가지치기를 하는 방법은 최대 깊이를 지정하는 것이다

 

최대 깊이를 3으로 지정해 점수를 측정해보고 시각화 해보자

# 최대 깊이를 3으로 지정
dt = DecisionTreeClassifier(max_depth=3, random_state=42)
dt.fit(train_scaled, train_target)
print(dt.score(train_scaled, train_target))  #0.8454877814123533
print(dt.score(test_scaled, test_target))  #0.8415384615384616

plt.figure(figsize=(20,15))
plot_tree(dt, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()

  • 처음에는 당도를 기준으로 분류한다.
  • 주황색을 띄는 노드는 음성 클래스가 더 많으므로 레드 와인으로 예측하고 있다

 

 

 

결정트리의 장점 ① 표준화 전처리 과정이 필요 없다.

특성값의 스케일은 결정 트리 알고리즘에 아무런 영향을 끼치지 않는다.

전처리 하기 전 데이터로 훈련해 결과를 확인해보자

# 전처리 전 데이터로 훈련
dt = DecisionTreeClassifier(max_depth=3, random_state=42)
dt.fit(train_input, train_target)
print(dt.score(train_input, train_target))  #0.8454877814123533
print(dt.score(test_input, test_target))  #0.8415384615384616

plt.figure(figsize=(20,15))
plot_tree(dt, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()

  • 전처리 하기 전과 후의 결정 트리 결과가 같은 것을 확인할 수 있다.

 

 

결정트리의 장점 ② 특성 중요도를 알 수 있다.

특성 중요도를 활용하면 결정 트리 모델을 특성 선택에 활용할 수 있다는 장점이 있다.

# 특성 중요도 확인
print(dt.feature_importances_)

  • 당도가 약 0.87로 가장 중요한 특성이라는 것을 알 수 있다.

 

 

▶ 정리

  1. 결정 트리는 예/아니오에 대한 질문을 이어나가며 정답을 찾아 학습하는 알고리즘
    • 비교적 예측 과정을 이해하기 쉽고 성능이 뛰어남
    • 데이터 표준화 전처리가 필요 없음
    • 특성 중요도를 알 수 있음
  2. 결정 트리는 제한 없이 성장하면 훈련 세트에 과대적합되기 쉬움
    • 가지치기로 결정 트리의 성장을 제한해야함

 

'Python > ML & DL 공부' 카테고리의 다른 글

[ML] 05-3 트리의 앙상블  (0) 2022.03.11
[ML] 05-2 교차 검증과 그리드 서치  (0) 2022.03.11
[ML] 04-2 확률적 경사 하강법  (0) 2022.03.10
[ML] 04-1 로지스틱 회귀  (0) 2022.03.07
[ML] 03-3 특성 공학과 규제  (0) 2022.03.07