Gidhub BE Developer

Project [3:4]

2018-02-14
goodGid

머신러닝 - 결정 트리(Decision Tree)를 기반으로 운동 경기 결과 예측하기

  1. 지도 학습이란 ?
  2. 개발 환경 설정 : skikit-learn과 pandas
  3. 분류 문제와 결정 트리
  4. 교차 검증
  5. NBA 경기 데이터 수집 및 전처리

분류 문제와 결정 트리

주어진 데이터가 어디에 속하는지 예측하는 문제를 분류(Classification)문제라고 하며,

개, 고양이처럼 선택 항목이 두 가지인 경우를 이항 클래스 분류

NBA 팀에서 올해 챔피언에 오를 팀을 맞추는 경우와 같이

선택 항목이 여러 가지인 경우를 다중 클래스 분류라고 한다.


즉, 훈련 데이터에서 관심을 두는 하나 이상의 특성 값과

그와 연관된 클래스 혹은 타겟 값을 바탕으로 모델을 학습시키고,

학습된 모델을 이용하여 테스트 데이터의 특성 값으로부터 클래스 값을 쳬윽하는 것이다.

분류 문제의 해결은 지도 학습 중 회귀 분석, 서포트 벡터 머신, 결정 트리 등으로도 가능하다.


결정 트리는 지도 학습의 하나로 훈련 데이터로부터 트리 형태의 분류기를 구축하여

테스트 데이터에 대해서 그에 맞는 클래스 값을 예측하는 것이다.

여기서 단말 노드는 최종 의사 결정 결과를 나타내며,

단말 노드를 제외한 노드들은 결정 노드로서 입력된 특성에 대해서

데이터 값을 평가하는 데 사용된다.



붓꽃 데이터를 이용해 결정 트리를 학습시키고,

예측하는 일련의 과정을 알아보자.

머신 러닝 예제로 자주 사용되는 데이터로

scikit-learn 라이브러리의 datasets 패키지에 기본적으로 포함돼 있으며,

load_iris() 함수를 이용해 붓꽃 데이터를 로딩할 수 있다.

iris.data에는 측정한 개별 꽃의 꽃받침 길이, 꽃받침 너비, 꽃잎 길이, 꽃잎 너비가 저정되어 있으며

iris.target에는 정수로 꽃의 종류가 각각 저장되어 있고,

iris.target_names에는 각 정수에 해당하는 실제 꽃 이름이 저장되어 있다.

from sklearn import datasets

iris = datasets.load_iris()

print(iris.data[:5])                # 5개의 붓꽃 데이터를 출력

print(iris.target[:5])              # 5개의 붓꽃 데이터가 어떤 종류에 속하는지 확인

print(iris.target_names[0])         # 0번 붓꽃 종류의 이름을 확인




[[5.1 3.5 1.4 0.2]
 [4.9 3.  1.4 0.2]
 [4.7 3.2 1.3 0.2]
 [4.6 3.1 1.5 0.2]
 [5.  3.6 1.4 0.2]]

[0 0 0 0 0]

setosa



train_test_split()을 이용하면 샘플링 데이터에서 선별 시

편향되지 않은 임의의 학습 데이터테스트 데이터를 분류할 수 있다.


다음 예제는 전체 데이터 중 40%를 모델의 학습 데이터로 x_train, y_train

나머지 60%를 테스트 데이터로 x_test, y_test에 각각 분류하는 예제이다.


여기서 random_seed 인자는 내부적으로 임의이 값을 생성하는 시드 값으로 사용되는데,

이 값을 고정하지 않으면 예제에서 입력이 같더라도 학습된 모델의 결과가 달라질 수 있으므로

모든 예제에서 이 값을 고정하여 사용한다.

from sklearn import datasets
from sklearn.model_selection import train_test_split

iris = datasets.load_iris()
x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target,test_size=0.4,random_state=7)



이제 결정 트리 객체를 생성하고,

fit() 메서드를 이용해 결정 트리 객체를 학습시켜 보겠다.

이렇게 학습된 결정 트리 객체는 붓꽃의 꽃잎과 꽃받침의 각 길이와 너비를 바탕으로

어떤 종류에 속하는지 구분할 수 있게 된다.

import numpy
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier

iris = datasets.load_iris()

x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target,test_size=0.4,random_state=7)

clf = DecisionTreeClassifier(random_state=7)
resut = clf.fit(x_train, y_train)
print(resut)



DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
            max_features=None, max_leaf_nodes=None,
            min_impurity_decrease=0.0, min_impurity_split=None,
            min_samples_leaf=1, min_samples_split=2,
            min_weight_fraction_leaf=0.0, presort=False, random_state=7,
            splitter='best')



predict() 메서드로 학습된 결정 트리 모델에

입력된 데이터의 결과를 예측할 수 있다.

다음은 테스트 데이터로 예측 결과 y_predict를 얻어와서

실제 값 y_test와 얼마나 일치하는지 정확도를 측정해 보자.

import numpy
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier

iris = datasets.load_iris()

x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target,test_size=0.4,random_state=7)

clf = DecisionTreeClassifier(random_state=7)
# [1]
clf.fit(x_train, y_train)

# [2]
y_predict = clf.predict(x_test)
print(y_predict[:5])


accuracy = numpy.mean(y_test == y_predict)


print("Accuarcy is {0:.2f}".format(accuracy * 100))

print("Accuarcy by score() is {0:.2f}".format(clf.score(x_test,y_test) * 100))

  • 학습된 모델의 정확도를 측정하려면 단순히 score() 메서드를 이용하는 것이 더 수월하다.

  • [1] 없이 [2]을 실행시키면 다음과 같은 Error가 발생한다.

  raise NotFittedError(msg % {'name': type(estimator).__name__})
sklearn.exceptions.NotFittedError: This DecisionTreeClassifier instance is not fitted yet. Call 'fit' with appropriate arguments before using this method.

교차 검증

우리가 사용할 수 있는 데이터 중

모든 데이터를 학습 데이터로만 사용하면

훈련 데이터에 과도하게 적합하게 학습된 나머지 새로운 테스트 데이터에 대해서는

올바르게 분류하지 못하는 문제가 발생할 수 있다

이러한 상태를 과적합(Overfitting)이라 하며,

이러한 문제를 방지하기 위해 가용 데이터 중에서

일정 부분은 학습된 모델을 검증하는데 사용해야 한다.


하지만 사용 가능한 데이터가 많지 않은 상황에서

학습에 사용할 데이터 샘픙르 줄이게 되면 생성되는 모델이

학습에 사용한 데이터에 매우 의존적이게 되는 문제가 발생한다.


이 문제는 교차 검증으로 해결할 수 있으며,

교차 검증은 학습 데이터와 검증 데이터를 별도로 분리하는 대신에

전체 데이터를 K개의 작은 집합으로 분리하여 다음과 같은 괒어을 반복 수행한다.

  1. 학습 데이터로 K-1개의 집합을 사용해 모델을 학습시킨다.
  2. 남은 1개의 집합을 학습된 모델의 검증에 사용한다.

이러한 과정은 수행 시간은 오래 걸리지만,

샘플 데이터가 적은 환경에서도 충분한 학습 데이터를 확보할 수 있으며,

학습된 모델이 과적합인지 검증할 방법을 제공한다.


sciki-learn 라이브러리에서는 교차 검증으로 학습된 모델을 평가할 수 있는

cross_val_score() 메서드를 제공한다.

이 메서드를 이용하면 앞서 설명한 학습 데이터 K개의 집합으로 분리하여

반복 수행하는 것과 같은 방법으로 모델을 검증할 수 있다.

import numpy
from sklearn import datasets
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.tree import DecisionTreeClassifier

iris = datasets.load_iris()

x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target,test_size=0.4,random_state=7)

clf = DecisionTreeClassifier(random_state=7)
scores = cross_val_score(clf, iris.data, iris.target, scoring='accuracy')

print("Accuracy : {0:.1f} (+/- {1:.2f}%)" .format(numpy.mean(scores) * 100 , numpy.std(scores)))




Accuracy : 96.7 (+/- 0.03%)


Recommend

Index