메이플의 개발 스토리
[ML] 5-1 결정 트리 본문
결정 트리¶
결정 트리¶
- Decision Tree
- 예/아니오에 대한 질문을 이어나가면서 정답을 찾아 학습하는 알고리즘
- 비교적 예측 과정을 이해하기 쉽고 성능이 뛰어남
dt = DecisionTreeClassifier(random_state=42) dt.fit(train_scaled, train_target)
불순도¶
- Impurity
- 결정 트리가 최적의 질문을 찾기 위한 기준
- 사이킷런은 지니 불순도와 엔트로피 불순도를 제공
정보 이득¶
- Information gain
- 부모 노드와 자식 노드의 불순도 차이
- 결정 트리 알고리즘은 정보 이득이 최대화되도록 학습
가지치기¶
- Pruning
- 결정 트리의 성장을 제한하는 방법
- 결정 트리가 제한 없이 성장하면 훈련 세트에 과대적합되기 쉬움
dt = DecisionTreeClassifier(max_depth=3, random_state=42) dt.fit(train_scaled, train_target)
특성 중요도¶
- 결정 트리에 사용된 특성이 불순도를 감소하는데 기여한 정도
- 특성 중요도를 계산할 수 있는 것이 결정 트리의 또다른 큰 장점
print(dt.feature_importances_)
로지스틱 회귀로 와인 분류하기¶
1) 데이터 불러오기¶
데이터셋 출처 : 캐글의 Red Wine Quality
import pandas as pd
wine = pd.read_csv('https://bit.ly/wine_csv_data')
wine.head()
alcohol | sugar | pH | class | |
---|---|---|---|---|
0 | 9.4 | 1.9 | 3.51 | 0.0 |
1 | 9.8 | 2.6 | 3.20 | 0.0 |
2 | 9.8 | 2.3 | 3.26 | 0.0 |
3 | 9.8 | 1.9 | 3.16 | 0.0 |
4 | 9.4 | 1.9 | 3.51 | 0.0 |
wine.tail()
- info() 메서드 : 데이터프레임의 각 열의 데이터 타입과 누락된 데이터가 있는지 확인할 때 사용
wine.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 6497 entries, 0 to 6496 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 alcohol 6497 non-null float64 1 sugar 6497 non-null float64 2 pH 6497 non-null float64 3 class 6497 non-null float64 dtypes: float64(4) memory usage: 203.2 KB
- describe() 메서드 : 열에 대한 간략한 통계 출력
mean : 평균 </br> std : 표준편차 </br> min : 최소 </br> 25% : 1사분위수 </br> 50% : 2사분위수 </br> 75% : 3사분위수 </br> max : 최대
wine.describe()
alcohol | sugar | pH | class | |
---|---|---|---|---|
count | 6497.000000 | 6497.000000 | 6497.000000 | 6497.000000 |
mean | 10.491801 | 5.443235 | 3.218501 | 0.753886 |
std | 1.192712 | 4.757804 | 0.160787 | 0.430779 |
min | 8.000000 | 0.600000 | 2.720000 | 0.000000 |
25% | 9.500000 | 1.800000 | 3.110000 | 1.000000 |
50% | 10.300000 | 3.000000 | 3.210000 | 1.000000 |
75% | 11.300000 | 8.100000 | 3.320000 | 1.000000 |
max | 14.900000 | 65.800000 | 4.010000 | 1.000000 |
2) 넘파이 배열로 변환해서 훈련 세트와 테스트 세트로 나누기¶
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)
3) 특성을 표준화 처리¶
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)
4) 로지스틱 회귀 모델로 훈련¶
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))
0.7808350971714451 0.7776923076923077
훈련 세트와 테스트 세트의 점수가 모두 낮은 과소적합이 나왔다.
설명하기 쉬운 모델과 어려운 모델¶
print(lr.coef_, lr.intercept_)
[[ 0.51270274 1.6733911 -0.68767781]] [1.81777902]
z = 알코올 도수 X 0.5127 + 당도 X 1.6733 + pH X (-0.6876) + 1.8177
결정 트리¶
1) 결정 트리 모델로 훈련¶
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
훈련 세트는 점수가 높지만 테스트 세트의 점수가 낮으므로 과대적합이다
2) 그래프 출력¶
import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
plt.figure(figsize=(10,7))
plot_tree(dt)
plt.show()
맨위의 노드를 루트 노드, 맨 아래 끝에 달린 노드를 리프 노드라고 한다
3) 트리의 깊이를 제한해서 그래프 출력¶
plt.figure(figsize=(10,7))
plot_tree(dt, max_depth=1, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()
읽는 방법
테스트 조건 (sugar)
불순도 (gini)
총 샘플 수 (samples)
클래스별 샘플 수 (value)
- 왼쪽 아래 화살표 : 테스트 조건에 만족(Yes)
- 오른쪽 아래 화살표 : 테스트 조건에 불만족(No)
plot_tree() 함수에서 filled=True로 지정하면 클래스마다 색깔을 부여하고, 어떤 클래스의 비율이 높아지면 점점 진한 색으로 표시됨
gini, 지니 불순도(Gini impurity)¶
- DecisionTreeClassifier 클래스의 criterion 매개변수의 기본값
- criterion='entropy'를 지정하면 엔트로피 불순도를 사용할 수 있음. </br> 지니 불순도는 제곱을 사용하지만 엔프로피 불순도는 밑이 2인 로그를 사용
- 지니 불순도 = 1 - (음성 클래스 비율²+ 양성 클래스 비율²)
- 순수 노드 : 노드에 하나의 클래스만 있어 지니 불순도가 0이 되는 경우
- 결정 트리 모델은 부모 노드(parent node)와 자식 노드(child node)의 불순도 차이가 가능한 크도록 트리를 성장시킴
정보 이득¶
- information gain
- 부모 노드와 자식 노드의 불순도 차이
- 정보 이득 = 부모의 불순도 - (왼쪽 노드 샘플 수 / 부모의 샘플 수) X 왼쪽 노드 불순도 - (오른쪽 노드 샘플 수 / 부모의 샘플 수) X 오른쪽 노드의 불순도
- 불순도 기준을 사용해 정보 이득이 최대가 되도록 노드를 분할
- 노드를 순수하게 나눌수록 정보 이득이 커짐
4) 결정 트리의 최대 깊이 지정 = 가지치기¶
DecisionTreeClassifier 클래스의 max_depth 매개변수를 통해 트리의 최대 깊이를 지정
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))
0.8454877814123533 0.8415384615384616
훈련 세트의 성능은 낮아졌지만 테스트 세트의 성능은 거의 그대로임
5) 그래프 출력¶
plt.figure(figsize=(20,15))
plot_tree(dt, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()
결정 트리 모델은 불순도를 기준으로 샘플을 나누고 불순도는 클래스별 비율을 가지고 계산하기 때문에 특성값의 스케일이 계산에 영향을 미치지 않는다. </br> 즉, 표준화 전처리를 할 필요가 없다.
6) 표준화 전처리를 하지 않는 훈련 세트와 테스트 세트로 결정 트리 모델을 훈련¶
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))
0.8454877814123533 0.8415384615384616
7) 그래프 출력¶
plt.figure(figsize=(20,15))
plot_tree(dt, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()
8) 특성 중요도 출력¶
- 특성 중요도 : 결정 트리에서 어떤 특성이 가장 유용한지 나타냄
print(dt.feature_importances_)
[0.12345626 0.86862934 0.0079144 ]
[알코올, 당도, 산성도] 에서 당도 특성의 중요도가 가장 높은 것을 볼 수 았다.
확인문제¶
사이킷런의 결정 트리 클래스가 제공하는 매개변수 중 min_impurity_decrease를 사용해 가지치기를 해보겠습니다. 어떤 노드의 정보 이득 X (노드의 샘플 수) / (전체 샘플 수) 값이 이 매개변수보다 작으면 더 이상 분할하지 않습니다. 이 매개변수의 값을 0.0005로 지정하고 결정 트리를 만들어 보세요. </br> 좌우가 균일하지 않은 트리가 만들어지나요? </br> 테스트 세트의 성능은 어떤가요?
dt = DecisionTreeClassifier(min_impurity_decrease=0.0005, random_state=42)
dt.fit(train_input, train_target)
print(dt.score(train_input, train_target))
print(dt.score(test_input, test_target))
0.8874350586877044 0.8615384615384616
plt.figure(figsize=(20,15))
plot_tree(dt, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()
'ML DL' 카테고리의 다른 글
[ML] 5-3 트리의 앙상블 (0) | 2022.01.08 |
---|---|
[ML] 5-2 교차 검증과 그리드 서치 (0) | 2022.01.08 |
[ML] 4-2 확률적 경사 하강법 (0) | 2022.01.08 |
[ML] 4-1 로지스틱 회귀 (0) | 2022.01.08 |
[ML] 3-3 특성 공학과 규제 (0) | 2022.01.08 |