티스토리 뷰

Untitled8

Iris 데이터를 이용해 간단한 랜덤 포레스트 구현

(1) Iris Data 소개

Iris 데이터는 붓꽃의 3가지 종류를 기록한 데이터이다.
Iris 데이터에는 붓꽃 줄기의 길이, 너비 그리고 붓꽃 잎의 길이와 너비 등 4개의 특징이 있다.
그리고 목표 데이터, 즉 붓꽃의 종류인 target은 0, 1, 2로 되어 있는데 이는 각각 setosa, versicolor, virginica를 나타낸다.
전체 데이터의 크기는 150개(line)이다.

(2) 필요한 패키지 및 라이브러리 로드

In [66]:
from sklearn.datasets import load_iris

Iris 데이터를 사용하기 위해 sklearn.DataSets 패키지에서 load_iris모듈을 import한다.
sklearn.datasets 서브 패키지는 scikit-learn 패키지 중 일반적인 참조 데이터 셋을 load하는 모듈로 많은 샘플 데이터 셋을 무료로 간편하게 다운로드 할 수 있게 도와준다.

In [2]:
from sklearn.metrics import accuracy_score

Random Forest 예측 모듈의 성능을 평가하기 위해 sklearn.metrics 패키지에서 accuracy_score 모듈을 improt 한다.
sklearn.metrics는 성능 평가를 제공하는 패키지이고 accuracy_score는 예측 결과의 Accuracy를 계산하는 모듈이다.

In [4]:
import numpy as np

numpy 패키지를 import하고 np라고 따로 명명하였다.
numpy는 파이썬 언어를 위한 행렬, 벡터 등의 수학 계산을 위한 자료구조와 계산 함수를 제공하는 패키지이다.

In [5]:
import pandas as pd

pandas 패키지를 import하고 pd라고 따로 명명하였다.
pandas는 데이터 분석, 가공, 처리 등을 쉽게 하기 위한 자료구조와 처리 함수들을 제공하는 패키지이다.

(3) Training data와 Test data 설정

In [7]:
#loading the iris dataset
iris = load_iris()

load_iris() 함수를 사용해 iris 데이터를 로드하고 iris라는 변수에 저장한다.
변수 iris에는 feature와 target이 같이 있는데 예측 모듈을 학습시키려면 이를 구분해야 한다.
iris.data 함수를 사용하면 iris에서 feature 데이터만 호출하게 된다. 그리고 iris.target은 iris에서 target 데이터만 호출한다.
이 두 함수를 사용하면 iris에서 feature와 target을 쉽게 분리할 수 있다.

훈련 데이터와 테스트 데이터를 분리할 때 우리는 전체 데이터에서 80%를 훈련에 사용하고 나머지 20% 데이터로 성능을 테스트 하려고 한다.
즉 150개 iris데이터에서 120개 데이터를 훈련 set으로 하고 나머지 30개 데이터를 테스트 set으로 하는 것이다.

In [8]:
#training data 설정
x_train = iris.data[:-30]
y_train = iris.target[:-30]

iris.data 함수를 호출해 iris feature 데이터에서 앞쪽 120개 특징 데이터를 x_train과 y_train이라는 변수에 저장한다.
여기서 iris.data 함수 뒤 중괄호 안에':-30'은 결과 값에서 처음부터 마지막 30번째 값까지만 선택한다는 의미이다.
여기서 -30은 데이터를 뒤로부터 count할 때 30번째 위치를 의미한다.
전체 iris 데이터는 150개이고 여기서 마지막 30개를 제외하면 120개가 된다.

In [16]:
#test data 설정
x_test = iris.data[-30:] # test feature data
y_test = iris.target[-30:] # test feature data

iris feature 데이터 중 뒤로부터 30개 데이터를 x_test와 y_test라는 변수에 저장한다.

(4) Training data와 Test data의 target 출력

In [17]:
print(y_train)
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2]
In [18]:
print(y_test)
[2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]

훈련 데이터와 테스트 데이터의 분리를 완료한 다음 훈련 데이터의 목표 값과 테스트 데이터의 목표 값을 각각 출력해 보았다.

위에 출력한 "0,1,2" 세가지 목표 값이 있다.
그런데 목표 값 2는 상대적으로 양이 적은 편이다.
그리고 테스트 데이터의 목표 값을 보면 전부 2이다.
이는 훈련 데이터와 테스트 데이터의 분리가 합리적이지 않다는 것을 의미한다.
하지만 우리는 먼저 이 데이터로 간단한 예측 모듈을 생성해 보겠다.

(5) 랜덤 포레스트 분류기 생성

In [19]:
#RandomForestClassifier 클래스를 import
from sklearn.ensemble import RandomForestClassifier

Random Forest 예측 모듈을 생성하기 위해 RandomForestclassifier 모듈을 import해야 한다.
RandomForestClassifier는 sklearn.ensemble 모듈에 속하는데 sklearn.ensemble 모듈에는 분류, 회귀 및 이상 탐지를 위한 앙상블 기반의 방법을 포함하고 있다.
RandomForestClassifier는 Random Forest 분류기를 포함한 모듈이다.

In [20]:
#tree의 개수 Random Forest 분류 모듈 생성
rfc = RandomForestClassifier(n_estimators=10)
rfc
Out[20]:
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
            max_depth=None, max_features='auto', 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, n_estimators=10, n_jobs=None,
            oob_score=False, random_state=None, verbose=0,
            warm_start=False)

RandomForestClassifier함수에 n_estimators=10을 주어 트리의 개수 10인 RandomForest 분류 모델을 생성하고 변수 rfc에 저장한다.
생성한 RandomForest 분류/예측 모듈을 출력해보면 RandomForestClassifier에는 많은 parameter가 있고 default 값도 정해져 있다.
여기서 많이 사용되는 몇 개의 파라미터만 설명하고 상세한 내용은 아래 참조 url에서 확인할 수 있다.
파라미터 n_estimators는 의사결정트리의 개수를 나타내며 기본 값은 10이다.

(6) 랜덤 포레스트 분류 학습

In [34]:
# rfc.fin()에 훈련 데이터를 입력해 Random Forest 모듈을 학습
rfc.fit(x_train, y_train)
#Test data를 입력해 target data를 예측 (매번 달라짐)
prediction = rfc.predict(x_test)
#예측 결과 precision과 실제 test data의 target을 비교
print(prediction==y_test)
[ True False  True False  True  True False False  True False  True  True
  True False False  True  True  True False  True  True  True  True  True
  True  True  True  True  True  True]

(7) 랜덤 포레스트 분류 예측 결과

In [35]:
#Random forest 정확도 측정
rfc.score(x_test, y_test)
Out[35]:
0.7333333333333333

rfc.score()는 RandomForestClassifier 클래스 안에 있는 분류 결과의 정확도(Accuracy)를 계산한는 함수이다. 입력 데이터는 Test Data의 feature와 target 값이다. 테스트 데이터에 대한 예측 결과의 정확도는 0.7667이다.

(8) 랜덤 포레스트 분류 성능 평가

In [38]:
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report

분류 예측 모듈의 평가에는 Accuracy뿐만 아니라 Precision, Recall도 많이 사용된다.
sklearn.metrics 모듈은 scikit-learn 패키지 중 모델의 성능 평가 방법을 모아 놓은 모듈이다.
이 모듈에서 accuracy_score와 clasification_report를 import 해 모델의 성능을 다시 평가해 보려고 한다.
함수 accuracy_score()는 분류 결과의 Accuracy를 계산하고, 함수 classification_report()는 분류 결과의 Precision, Recall을 계산한다.

In [39]:
print("Accuracy is: ", accuracy_score(prediction, y_test))
Accuracy is:  0.7333333333333333

Accuracy를 계산하는 코드이고 일곱 번째 Line은 Precision과 Recall을 계산하는 코드이다.

In [40]:
print(classification_report(prediction, y_test))
              precision    recall  f1-score   support

           1       0.00      0.00      0.00         8
           2       0.73      1.00      0.85        22

   micro avg       0.73      0.73      0.73        30
   macro avg       0.37      0.50      0.42        30
weighted avg       0.54      0.73      0.62        30

C:\Anaconda3\lib\site-packages\sklearn\metrics\classification.py:1143: UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.
  'precision', 'predicted', average, warn_for)

입력 데이터는 예측 결과 값인 prediction과 실제 테스트 데이터의 목표 값인 y_test이다.
결과를 살펴보면 Precision과 Recall은 낮은 것을 알 수 있다.
이것은 우리가 위에서 훈련 데이터와 테스트 데이터를 잘 분리하지 못한 이유로 분류 성능이 낮게 나온 것이다.
데이터 셋에서 훈련 데이터 셋과 테스트 데이터 셋을 분리하는 방법에는 여러가지가 있다.

(9) Training, Test data 재생성

In [41]:
from sklearn.model_selection import train_test_split

함수 train_test_split은 데이터를 무작위로 혼합한 후 Training Data Set과 Test Data Set을 일정한 비율에 따라 분리해준다.

In [42]:
x = iris.data
y = iris.target

x는 iris feature data, y는 iris target data이다.

In [43]:
X_train, X_test, Y_train, Y_test = train_test_split(x, y, test_size=0.2)

데이터를 무작위로 혼합한 후 x의 80%를 X_train, x의 20%를 X_test, y의 80%를 Y_train, y의 20%를 Y_test에 저장한다.

In [44]:
print(y_test)
[2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]

위에서 마지막 30개 데이터를 선택한 테스트 데이터의 목표 값을 출력한다.

In [45]:
print(Y_test)
[1 0 1 1 2 2 1 2 2 0 2 2 0 1 0 2 0 2 0 1 0 2 1 0 1 1 2 0 2 1]

데이터를 무작위로 혼합한 후 선택한 150개 데이터의 20%인 30개 테스트 데이터의 목표 값을 출력한다.

출력결과를 보면 데이터를 혼합한 결과 Y_test에는 목표 데이터의 종류가 이전과는 다르게 동일하지 않다는 것을 알 수 있다.

(10) 랜덤 포레스트 분류 성능 평가

새로 생성한 훈련 셋과 테스트 셋을 이용해 새로운 Random Forest 분류 예측 모델을 생성하고 성능을 다시 측정해 보겠다.

In [47]:
clf = RandomForestClassifier(n_estimators=10)

Tree의 개수가 10인 Random Forest를 생성하고 clf에 저장한다

In [50]:
clf.fit(X_train, Y_train) # X_train과 Y_train을 입력해 모듈을 학습 시킨다.
prediction_1 = rfc.predict(X_test)

predict 함수를 이용해 X_test의 목표를 분류 예측하고 결과를 prediction_1에 저장한다.

In [52]:
#print(prediction_1 == Y_test)
print("Accuracy is: ", accuracy_score(prediction_1, Y_test))
Accuracy is:  0.9333333333333333
In [53]:
print(classification_report(prediction_1, Y_test))
              precision    recall  f1-score   support

           0       1.00      1.00      1.00         9
           1       1.00      0.83      0.91        12
           2       0.82      1.00      0.90         9

   micro avg       0.93      0.93      0.93        30
   macro avg       0.94      0.94      0.94        30
weighted avg       0.95      0.93      0.93        30

accuracy_score 함수와 classification_report 함수로 Accuracy, Precision, Recall을 계산하고 출력한다.
출력 결과를 보면 분류기의 성능인 Accuracy는 0.9333으로 모두 향상 되었다.

이처럼 분류 예측 모듈을 만들 때 훈련 데이터를 제대로 선택해 모듈을 학습시키고 테스트 데이터를 합리적으로 선택하는 것은 매우 중요하다는 것을 알 수 있다.

(11) 랜덤 포레스트 분류 성능 높이는 방법

Random Forest 분류 예측 모듈의 성능을 높이는 방법은 아주 많다.
그 중 제일 간단한 방법은 Random Forest를 생성할 때 트리의 개수를 적당히 확장하는 것이다.
간단하지만 실전에서 많이 사용되는 효율적인 방법 중 하나이다.
하지만 주의할 것은 트리의 개수가 많을수록 random forest의 성능이 높아지는 것은 아니라는 것이다.
트리의 개수가 일정 개수를 넘어가면 오히려 성능이 낮아질 수도 있다.

그리고 또 하나의 간단한 방법은 max_features의 값을 수정하는 것이다.
하지만 여기서는 iris 데이터 셋의 사이즈가 작고 데이터가 간단하기 때문에 성능 차이가 크지 않다.
다음은 Tree가 200개인 Random Forest의 성능 평가이다.

In [56]:
# Initialize the model
clf_2 = RandomForestClassifier(n_estimators=200,     # Number of trees
                              max_features=4,     # Num features considered
                              oob_score=True)     # Use OOB scoring

Tree가 200개인 Random Forest를 생성하였다.
max_features의 값은 4로 설정하고 oob_score의 값은 True로 선택해 Out-Of-Bag을 사용한다고 설정했다.

In [60]:
clf.fit(X_train, Y_train)
prediction_2 = clf.predict(X_test)
print(prediction_2 == Y_test)
print("Accuracy is : ", accuracy_score(prediction_2, Y_test))
print("======================================================")
print(classification_report(prediction_2, Y_test))
[ True  True  True  True  True False  True  True  True  True  True  True
  True  True  True  True  True  True  True  True  True  True False  True
  True  True  True  True False  True]
Accuracy is :  0.9
======================================================
              precision    recall  f1-score   support

           0       1.00      1.00      1.00         9
           1       0.90      0.82      0.86        11
           2       0.82      0.90      0.86        10

   micro avg       0.90      0.90      0.90        30
   macro avg       0.91      0.91      0.90        30
weighted avg       0.90      0.90      0.90        30

위에서와 같이 모듈을 학습시키고 테스트 데이터의 목표를 예측한 결과를 보면 성능이 차이가 보이지 않는다.
이것은 iris 데이터가 간단하고 size가 작기 때문이다.
여기서 oob_score의 값을 True로 선택하였는데 이렇게 하면 특징들의 중요도를 볼 수 있다.

(12) 각 feature의 중요도 확인

In [68]:
for feature, imp in zip(iris.feature_names, clf_2.feature_importances_):
    print(feature, imp)
---------------------------------------------------------------------------
NotFittedError                            Traceback (most recent call last)
<ipython-input-68-c04e4d7f9f5a> in <module>
----> 1 for feature, imp in zip(iris.feature_names, clf_2.feature_importances_):
      2     print(feature, imp)

C:\Anaconda3\lib\site-packages\sklearn\ensemble\forest.py in feature_importances_(self)
    371         feature_importances_ : array, shape = [n_features]
    372         """
--> 373         check_is_fitted(self, 'estimators_')
    374 
    375         all_importances = Parallel(n_jobs=self.n_jobs,

C:\Anaconda3\lib\site-packages\sklearn\utils\validation.py in check_is_fitted(estimator, attributes, msg, all_or_any)
    949 
    950     if not all_or_any([hasattr(estimator, attr) for attr in attributes]):
--> 951         raise NotFittedError(msg % {'name': type(estimator).__name__})
    952 
    953 

NotFittedError: This RandomForestClassifier instance is not fitted yet. Call 'fit' with appropriate arguments before using this method.
In [ ]:
 출처 : 파이썬을 이용한 빅데이터 분석


'beginner > 파이썬 분석' 카테고리의 다른 글

로지스틱 회귀분석 실습  (0) 2019.02.11
인공신경망 실습  (2) 2019.02.10
의사결정 트리 파이썬 코드 실습  (3) 2019.02.02
다중선형회귀분석 실습  (0) 2019.01.30
단일선형회귀분석 ②  (0) 2019.01.28
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함