📊 분류 분석 - Decision Tree


📌 결정 트리란?

  • 정의
    - 여러가지 규칙을 순차적으로 독립 변수 공간을 분리하며 자식 노드의 혼잡도(불순도)가 낮아질 때까지 분류한다.


📌 혼잡도/불순도란?

  • 정의
    - 결정 트리의 각 노드에서 여러 독립변수가 혼잡된 수치


  • 혼잡도 지표
    - Entorpy
    - Gini 계수


📌 Python 결정트리 그래프 출력 선행 모듈 설치

  • 절차
    1) graphviz 설치
    2) 설치 후 graphviz 폴더의 bin 폴더로 이동
    3) 경로 복사
    4) 고급 시스템 설정 보기 환결 설정 path 수정
    5) 경로 붙여넣기 path 수정 완료
    6) anaconda prompt 실행
    7) pip install graphviz
    8) pip install pydotplus









📊 sklearn Decision Tree 모델


📌 결정트리 모델 학습

  • 1. 라이브러리 Import
import pydotplus
from sklearn import tree
import collections

  • 2. 데이터 준비
x = [[180, 15], [177, 42], [156, 35], [174, 5], [166, 33]]
y = ['man', 'woman', 'woman', 'man', 'woman']
label_names = ['height', 'hair Length']

  • 3. 모델 학습
    criterion 속성 : 노드의 독립변수 혼잡도를 측정할 지표를 설정
    max_depth 속성 : 결정트리의 최대 깊이를 설정
    min_samples_split 속성 : 노드 분할을 위한 최소 표본수 제어 값
model = tree.DecisionTreeClassifier(
	criterion='entropy',
    max_depth=2,
    min_samples_split=
    random_state=0
)
model.fit(x, y)

  • 4. 모델 성능 평가
print('훈련 정확도 : ', model.score(x, y))
# 훈련 정확도 :  1.0

  • 5. 예측값, 실제값 비교
print('예측값 : ', model.predict(x))
print('실제값 : ', y)
# 예측값 :  ['man' 'woman' 'woman' 'man' 'woman']
# 실제값 :  ['man', 'woman', 'woman', 'man', 'woman']

  • 6. 실제 예측하기
mydata = [[171, 78]]
new_pred = model.predict(mydata)
print(new_pred)
# ['woman']

  • 7. 결정트리 시각화
dot_data = tree.export_graphviz(model, feature_names=label_names, out_file=None, filled=True, rounded=True)
graph = pydotplus.graph_from_dot_data(dot_data)
colors = ('red', 'blue')
edges = collections.defaultdict(list)

for e in graph.get_edge_list():
    edges[e.get_source()].append(int(e.get_destination()))

for e in edges:
    edges[e].sort()
    for i in range(2):
        dest = graph.get_node(str(edges[e][i]))[0]
        dest.set_fillcolor(colors[i])

graph.write_png('tree.png')

  • 8. 저장한 이미지 읽기
img = imread('tree.png')
plt.imshow(img)
plt.show()









📊 과적합 방지 방법


📌 과적합 방지 방법1 - train_test_split

  • 학습, 테스트 데이터 분리
    - 데이터세트 하나로 학습하고 테스트하게 되면 과적합을 발생시킨다.
    - 데이터세트를 학습데이터와 테스트데이터로 분리하여 용도에 맞게 학습 및 테스트하여 과적합을 해소한다.
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(train_data, train_label, test_size=0.3, random_state=1)
print(x_train.shape, x_test.shape)
# (105, 4) (45, 4)

# 훈련데이터로 모델 학습
model = DecisionTreeClassifier()
model.fit(x_train, y_train)
y_pred = model.predict(x_test)
print('테스트 정확도 : ', accuracy_score(y_pred, y_test))
# 테스트 정확도 :  0.9555555555555556


📌 과적합 방지 방법2 - 교차검증(cross validation)

  • 교차 검증(Cross Validation)
    - 학습, 테스트 데이터로 분리해도 과적합이 발생된다면 검증데이터 사용 고려
    - 분리한 학습데이터에서 일부를 검증데이터로 사용한다.
    - 전체 학습데이터 = 일부 학습데이터 + 검증데이터
    - 교차검증은 모델 학습 도중에 k번 학습데이터에서 검증데이터를 분리하여 학습 시 검증도 함께 수행한다.

[ 과적합 발생시 교차검증 ]

1) 필요 라이브러리

from sklearn.model_selection import KFold
import numpy as np

2) 데이터 준비

features = iris.data
label = iris.target

3) KFold 객체 준비

kfold = KFold(n_splits=5)

4) KFold를 이용해 학습, 검증 데이터 분할 (교차검증)

n_iter = 0		# KFold 실행 순번 저장
n_acc = []		# 각 모델의 정확도 저장
for train_index, test_index in kfold.split(features):
    n_iter += 1

    # 학습, 검증 데이터 분할
    x_train, x_test = features[train_index], features[test_index]
    y_train, y_test = label[train_index], label[test_index]

    # 분리된 학습데이터로 모델 학습
    model.fit(x_train, y_train)

    # 각 모델 정확도 평가
    y_pred = model.predict(x_test)
    print(f'{n_iter}번째 모델 정확도 : ', accuracy_score(y_test, y_pred))
    # 1번째 모델 정확도 :  1.0
    # 2번째 모델 정확도 :  0.9666666666666667
    # 3번째 모델 정확도 :  0.9
    # 4번째 모델 정확도 :  0.9333333333333333
    # 5번째 모델 정확도 :  0.8

	# 각 모델의 정확도 저장
    n_acc.append(accuracy_score(y_test, y_pred))

5) 평균 정확도 계산

print('평균 정확도 : ', np.mean(n_acc))
# 평균 정확도 :  0.9199999999999999

[ 불균형한 분포(평향, 왜곡) 발생시 교차검증 ]

불균형이란 특정 레이블 값이 특이하게 많거나 적은 경우

1) 필요 라이브러리

from sklearn.model_selection import StratifiedKFold

2) 데이터 준비

features = iris.data
label = iris.target

3) KFold 객체 준비

skfold = StratifiedKFold(n_splits=5)

4) KFold를 이용해 학습, 검증 데이터 분할 (교차검증)

n_iter = 0		# KFold 실행 순번 저장
n_acc = []		# 각 모델의 정확도 저장
for train_index, test_index in skfold.split(features, label):
    n_iter += 1

    # 학습, 검증 데이터 분할
    x_train, x_test = features[train_index], features[test_index]
    y_train, y_test = label[train_index], label[test_index]

    # 분리된 학습데이터로 모델 학습
    model.fit(x_train, y_train)

    # 각 모델 정확도 평가
    y_pred = model.predict(x_test)
    print(f'{n_iter}번째 모델 정확도 : ', accuracy_score(y_test, y_pred))
    # 1번째 모델 정확도 :  0.9666666666666667
    # 2번째 모델 정확도 :  0.9666666666666667
    # 3번째 모델 정확도 :  0.9
    # 4번째 모델 정확도 :  0.9333333333333333
    # 5번째 모델 정확도 :  1.0

	# 각 모델의 정확도 저장
    n_acc.append(accuracy_score(y_test, y_pred))

5) 평균 정확도 계산

print('평균 정확도 : ', np.mean(n_acc))
# 평균 정확도 :  0.9533333333333334


📌 과적합 방지 방법3 - 교차검증 모듈 사용 (cross_val_score)

  • cross_val_score 모듈
    - KFold 교차검증 지원하는 모듈

  • 1. 필요 라이브러리
from sklearn.model_selection import cross_val_score

  • 2. 데이터 준비
data = iris.data
label = iris.target

  • 3. 모델 준비
model = DecisionTreeClassifier(criterion='entropy', random_state=1)

  • 4. 교차검증 수행
    - estimator 속성 : 정의한 모델 지정
    - X 속성 : 학습 features 지정
    - y 속성 : 학습 label 지정
    - scoring 속성 : 성능 평가 방법 지정
    - cv 속성 : KFold의 k개를 지정
score = cross_val_score(model, data, label, scoring='accuracy', cv=5)

  • 5. 모델 정확도 평가
print('교차 검증별 정확도 : ', score)
print('평균 검증 정확도 : ', np.mean(score))
# 교차 검증별 정확도 :  [0.96666667 0.96666667 0.9 0.93333333 1.]
# 평균 검증 정확도 :  0.9533333333333334


profile
데이터 사이언티스트를 목표로 하는 개발자

0개의 댓글