Machine Learning/Advanced (hands on machine learning)

20. 앙상블 학습과 랜덤 포레스트 - 랜덤 포레스트

jwjwvison 2021. 5. 22. 18:16

 랜덤 포레스트는 일반적으로 배깅 방법(또는 페이스팅)을 적용한 결정 트리의 앙상블이다. 전형적으로 max_samples를 훈련 세트의 크기로 지정한다. BaggingClassifier에 DecisionTreeClassifier를 넣어 만드는 대신 결정 트리에 최적화되어 사용하기 편리한 RandomForestClassifier를 사용할 수 있다.(비슷하게 회귀 문제를 위한 RandomForestRegressor 가 있다). 다음은 최대 16개의 리프 노드를 갖는 500개 트리로 이뤄진 랜덤 포레스트 분류기를 여러 CPU코어에서 훈련 시키는 코드이다.

from sklearn.ensemble import RandomForestClassifier

rnd_clf=RandomForestClassifier(n_estimators=500,max_leaf_nodes=16,n_jobs=-1)
rnd_clf.fit(X_train,y_train)

y_pred_rf=rnd_clf.predict(X_test)

 

 RandomForestClassifier는 몇 가지 예외가 있지만 (트리 성장의 조절을 위한) Decision Tree Classifier의 매개변수와 앙상블 자체를 제어하는 데 필요한 BaggingClassifier의 매개변수를 모두 가지고 있다.

 

 랜덤 포레스트 알고리즘은 트리의 노드를 분할할 때 전체 특성 중에서 최선의 특성을 찾는 대신 무작위로 선택한 특성 후보 중에서 최적의 특성을 찾는 식으로 무작위성을 더 주입한다. 이는 결국 트리를 더욱 다양하게 만들고 편향을 손해보는 대신 분산을 낮추어 전체적으로 더 훌룡한 모델을 만들어 낸다. 다음은 BaggingClassifier를 사용해 앞의 RandomForestClassifier와 거의 유사하게 만든 것이다.

 

<엑스트라 트리>

 랜덤 포레스트레어 트리를 만들 때 각 노드는 무작위로 특성의 서브셋을 만들어 분할에 사용한다. 트리를 더욱 무작위하게 만들기 위해 (보통의 결정 트리처럼) 최적의 임계값을 찾는 대신 후보 특성을 사용해 무작위로 분할한 다음 그중에서 최상의 분할을 선택한다.

 앞에서 설명한것 같이 극단적으로 무작위한 트리의 랜덤 포레스트를 익스트림 랜덤 트리(extremely randomized tree)앙상블 (또는 줄여서 엑스트라 트리extra tree)라고 부른다. 여기서도 역시 편향이 늘어나지만 대신 분산을 낮추게 된다. 모든 노드에서 특성마다 가장 최적의 임계값을 찾는 것이 트리 알고리즘에서 가장 시간이 많이 소요되는 작업 중 하나이므로 일반적인 랜덤 포레스트보다 엑스트라 트리가 훨씬 빠르다.

 

 엑스트라 트리를 만들려면 사이킷런의 ExtraTreesClassifier를 사용한다. 사용법은 RandomForestClassifier와 같다. 마찬가지로 ExtraTreeRegressor도 RandomForestRegressor와 같은 API를 제공한다.

 

<특성 중요도>

 랜덤 포레스트의 또 다른 장점은 특성의 상대적 중요도를 측정하기 쉽다는 것이다. 사이킷런은 어떤 특성을 사용한 노드가 평균적으로 불순도를 얼마나 감소시키는지 확인하여 특성의 중요도를 측정한다. 

 사이킷런은 훈련이 끝난 뒤 특성마다 자동으로 이 점수를 계산하고 중요도의 전체 합이 1이 되도록 결괏값을 정규화 한다. 이 값은 feature_importances_ 변수에 저장되어 있다. 예를 들어 다음 코드는 iris 데이터셋에 RandomForestClassifier를 훈련시키고 각 특성의 중요도를 출력한다.

from sklearn.datasets import load_iris
iris=load_iris()
rnd_clf=RandomForestClassifier(n_estimators=500,n_jobs=-1)
rnd_clf.fit(iris['data'],iris['target'])
for name, score in zip(iris['feature_names'],rnd_clf.feature_importances_):
  print(name,score)

 

 랜덤 포레스트는 특히 특성을 선택해야 할 때 어떤 특성이 중요한지 빠르게 확인할 수 있어 매우 편리하다.