1) 결정트리 생성¶
정답에 가장 빨리 도달하는 질문목록을 학습하는 것!!!!¶
데이터를 통해 각 마디에서 적절한 분리규칙을 찾아 결정트리의 질문목록을 생성함¶
트리 성장중 적절한 정지규칙을 만족하면 트리의 자식마디 생성을 중단¶
분리규칙을 설정하는 분리기준은 목표변수가 이산형 데이터인지, 연속형 데이터인지에 따라 다름¶
1. 이산형 목표변수¶
- 지도학습 문제(분류분석)¶
- 기준값에 따른 분리기준¶
(1) 카이제곱 통계량 p값 : p값이 가장 작은 예측변수와 그 떄의 최적분리에 의해 자식마디 형성¶
(2) 지니지수 : 지니지수를 감소시키는 예측변수와 그 때의 최적분리에 의해 자식마디 형성¶
(3) 엔트로피지수 : 엔트로피지수가 가장 작은 예측변수와 이떄의 최적분리에 의해 자식마디를 형성¶
2.연속형 목표변수¶
- 지도학습 문제(회귀분석)¶
- 기준값에 따른 분리기준¶
(1) 분산분석에서 F통계량 : p값이 가장 작은 예측변수와 그 떄의 최적분리에 의해 자식마디 형성¶
(2) 분산의 감소량 : 분산의 감소량을 최대화하는 기준의 최적분리에 의해 자식마디 형성¶
코드실습¶
In [2]:
#데이터 불러오기
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/ADPclass/ADP_book_ver01/main/data/credit_final.csv')
display(df)
x = df.drop(columns='credit.rating')
y = df['credit.rating']
#데이터 분류
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(x,y,test_size=0.3, stratify=y, random_state=1)
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
#sklearn의 DecisionTreeClassifier로 모델을 학습해보자
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(max_depth=5)
clf.fit(X_train, y_train)
#predict메서드로 예측값을 구한후 분류이므로 혼동행렬을 통해
#성능평가지표를 확인해보자
pred = clf.predict(X_test)
from sklearn.metrics import confusion_matrix, accuracy_score, precision_score, recall_score, f1_score
test_cm = confusion_matrix(y_test, pred)
test_acc = accuracy_score(y_test, pred)
test_prc = precision_score(y_test, pred)
test_rcll = recall_score(y_test, pred)
test_f1 = f1_score(y_test, pred)
print(test_cm)
print(test_acc)
print(test_prc)
print(test_rcll)
print(test_f1)
| credit.rating | account.balance | credit.duration.months | previous.credit.payment.status | credit.purpose | credit.amount | savings | employment.duration | installment.rate | marital.status | ... | residence.duration | current.assets | age | other.credits | apartment.type | bank.credits | occupation | dependents | telephone | foreign.worker | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 1 | 18 | 3 | 2 | 1049 | 1 | 1 | 4 | 1 | ... | 4 | 2 | 21 | 2 | 1 | 1 | 3 | 1 | 1 | 1 |
| 1 | 1 | 1 | 9 | 3 | 4 | 2799 | 1 | 2 | 2 | 3 | ... | 2 | 1 | 36 | 2 | 1 | 2 | 3 | 2 | 1 | 1 |
| 2 | 1 | 2 | 12 | 2 | 4 | 841 | 2 | 3 | 2 | 1 | ... | 4 | 1 | 23 | 2 | 1 | 1 | 2 | 1 | 1 | 1 |
| 3 | 1 | 1 | 12 | 3 | 4 | 2122 | 1 | 2 | 3 | 3 | ... | 2 | 1 | 39 | 2 | 1 | 2 | 2 | 2 | 1 | 2 |
| 4 | 1 | 1 | 12 | 3 | 4 | 2171 | 1 | 2 | 4 | 3 | ... | 4 | 2 | 38 | 1 | 2 | 2 | 2 | 1 | 1 | 2 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 995 | 0 | 1 | 24 | 2 | 3 | 1987 | 1 | 2 | 2 | 3 | ... | 4 | 1 | 21 | 2 | 1 | 1 | 2 | 2 | 1 | 1 |
| 996 | 0 | 1 | 24 | 2 | 4 | 2303 | 1 | 4 | 4 | 3 | ... | 1 | 1 | 45 | 2 | 2 | 1 | 3 | 1 | 1 | 1 |
| 997 | 0 | 3 | 21 | 3 | 4 | 12680 | 4 | 4 | 4 | 3 | ... | 4 | 4 | 30 | 2 | 3 | 1 | 4 | 1 | 2 | 1 |
| 998 | 0 | 2 | 12 | 2 | 3 | 6468 | 4 | 1 | 2 | 3 | ... | 1 | 4 | 52 | 2 | 2 | 1 | 4 | 1 | 2 | 1 |
| 999 | 0 | 1 | 30 | 2 | 2 | 6350 | 4 | 4 | 4 | 3 | ... | 4 | 2 | 31 | 2 | 2 | 1 | 3 | 1 | 1 | 1 |
1000 rows × 21 columns
(700, 20) (300, 20) (700,) (300,) [[ 28 62] [ 25 185]] 0.71 0.7489878542510121 0.8809523809523809 0.8096280087527352
이번에는 classification_report를 통해 결정트리의 분석결과를 확인¶
In [3]:
from sklearn.metrics import classification_report
report = classification_report(y_test, pred)
print(report)
precision recall f1-score support
0 0.53 0.31 0.39 90
1 0.75 0.88 0.81 210
accuracy 0.71 300
macro avg 0.64 0.60 0.60 300
weighted avg 0.68 0.71 0.68 300
트리를 생성하는 데 있어 중요한 변수가 무엇인지 확인하기 위한 변수중요도 확인¶
In [4]:
importances = clf.feature_importances_
column_nm = pd.DataFrame(x.columns)
feature_importances = pd.concat([column_nm, pd.DataFrame(importances)], axis=1)
feature_importances.columns = ['feature_nm','importances']
print(feature_importances)
feature_nm importances 0 account.balance 0.263282 1 credit.duration.months 0.187908 2 previous.credit.payment.status 0.123825 3 credit.purpose 0.059083 4 credit.amount 0.086741 5 savings 0.053080 6 employment.duration 0.000000 7 installment.rate 0.000000 8 marital.status 0.016325 9 guarantor 0.000000 10 residence.duration 0.020960 11 current.assets 0.000000 12 age 0.121337 13 other.credits 0.034003 14 apartment.type 0.021665 15 bank.credits 0.000000 16 occupation 0.011790 17 dependents 0.000000 18 telephone 0.000000 19 foreign.worker 0.000000
In [32]:
#임의의 데이터를 생성해 결정트리로 회귀분석 수행
import numpy as np
np.random.seed(0)
#400개의 요소를 갖는 1차원 배열을 생성하고,
#해당 배열을 열 기준으로 정렬하여 반환하는 코드
X = np.sort(5*np.random.rand(400,1), axis=0)
# 0부터 5까지의 범위를 500개의 동일한 간격으로 분할한 값을 갖는
#1차원 배열을 생성하고,
#이를 2차원 배열로 변환하여 반환하는 코드
T = np.linspace(0, 5, 500)[:, np.newaxis]
# 배열 X의 각 요소에 대해 사인 함수를 계산하고,
#그 결과를 1차원으로 평탄화한 배열을 반환하는 코드
y = np.sin(X).ravel()
#노이즈 추가
y[::1] += 1*(0.5 - np.random.rand(400))
import matplotlib.pyplot as plt
plt.scatter(X,y,s=20, edgecolor = 'black', c='darkorange', label='data')
#회귀분석 모델학습을 위해 학습데이터 평가데이터 분리 (7:3)
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size=0.3, random_state=1)
print(X_train.shape, X_test.shape, y_train.shape, y_test.shape)
#결정트리 회귀모델 생성(max_depth 차이에 따라 결과가 어떻게 달라지는지 확인!!!)
from sklearn.tree import DecisionTreeRegressor
regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_3 = DecisionTreeRegressor(max_depth=8)
#모델 fit
regr_1.fit(X_train, y_train)
regr_2.fit(X_train, y_train)
regr_3.fit(X_train, y_train)
#평가데이터로 예측을 수행후 다양한 성능평가지표를 통해 결정트리의 성능을 평가
#회귀 이므로 mse, mae rmse 로 확인
from sklearn.metrics import mean_squared_error, mean_absolute_error
y_1 = regr_1.predict(X_test)
y_2 = regr_2.predict(X_test)
y_3 = regr_3.predict(X_test)
preds = [y_1, y_2, y_3]
weights = ['max_depth=2','max_depth=5','max_depth=8']
evls = ['mse','mae','rmse']
results = pd.DataFrame(index=weights, columns=evls)
for pred,nm in zip(preds,weights):
mse = mean_squared_error(y_test, pred)
mae = mean_absolute_error(y_test, pred)
rmse = np.sqrt(mse)
results.loc[nm]['mse'] = round(mse,2)
results.loc[nm]['mae'] = round(mae,2)
results.loc[nm]['rmse'] = round(rmse,2)
results
(280, 1) (120, 1) (280,) (120,)
Out[32]:
| mse | mae | rmse | |
|---|---|---|---|
| max_depth=2 | 0.12 | 0.29 | 0.35 |
| max_depth=5 | 0.12 | 0.3 | 0.35 |
| max_depth=8 | 0.15 | 0.32 | 0.39 |
'빅데이터분석기사 준비' 카테고리의 다른 글
| 빅분기6장(앙상블(Ensemble)) (0) | 2023.05.21 |
|---|---|
| 빅데이터 분석기사(작업형 1유형) (0) | 2023.05.20 |
| 빅분기6장(k-최근접 이웃(KNN)) (0) | 2023.05.15 |
| 빅분기6장(서포트 벡터 머신) (0) | 2023.05.12 |
| 빅분기6장(로지스틱 회귀) (0) | 2023.05.09 |