5장 - 트리 알고리즘
파이썬 코드
https://github.com/JHWannabe/self-taught_machine_learning_code.git
5.1 결정 트리
판다스 데이터프레임의 유용한 메서드 2개
- info() : 데이터프레임의 각 열의 데이터 타입과 누락된 데이터가 있는지 확인하는 데 사용
- describe() : 열에 대한 간략한 통계를 출력 (최소(min), 최대(max), 평균값(mean), 표준편차(std), 중간값(50%), 1사분위수(25%), 3사분위수(75%) 등)
스케일 값이 다르다 → 사이킷런의 StandardScaler 클래스를 사용해 feature를 표준화함
StandardScaler 클래스를 사용해 훈련 세트를 전처리 함.
결정 트리 모델 : 마치 스무 고개와 같음
사이킷런의 DecisionTreeClassifier 클래스를 사용함.
ㄴ 결정트리 모델을 만들 때 random_state를 지정하는 이유 : 결정 트리 알고리즘은 약간의 무작위성이 주입되어 실행할 때마다 점수가 조금씩 달라질 수 있어 같은 결과를 유지하려면 random_state를 지정해야 한다.
결정트리 모델을 그림으로 표현하는 법 : plot_tree() 함수를 사용해 결정트리를 그림으로 출력해 줌.
트리의 깊이를 제한해서 출력하면 다음과 같다.
- max_depth 매개변수를 1로 주면 루트 노드를 제외하고 하나의 노드를 더 확장하여 그린다.
- filled 매개변수에서 클래스에 맞게 노드의 색을 칠할 수 있다.
- feature_names 매개변수에는 feature의 이름을 전달할 수 있다.
지니 불순도 (gini impurity)
결정 트리 모델은 부모 노드와 자식 노드의 불순도 차이가 가능한 크도록 트리를 성장시킨다.
부모 노드와 자식 노드의 불순도 차이를 계산하는 방법
정보 이득 (information gain) : 부모와 자식 노드 삿이의 불순도 차이
엔트로피 불순도 (entropy impurity)
가지치기 (pruning)
- 결정 트리에서 가지치기를 하는 가장 간단한 방법은 트리의 최대 깊이를 지정하는 것
ㄴ 훈련 세트의 성능은 낮아져도 테스트 세트의 성능은 거의 그대로임
※ 결정 트리는 표준화 전처리 과정이 필요 없다.
특성 중요도 (feature importances)
- 결정 트리에 사용된 특성이 불순도를 감소하는데 기여한 정도를 나타내는 값
- 결정 트리 모델의 feature_importances_ 속성에 저장되어 있음.
- 각 노드의 정보 이득과 전체 샘플에 대한 비율을 곱한 후 특성별로 더하여 계산.
- 특성 중요도를 활용하면 결정 트리 모델을 특성 선택에 활용할 수 있음 → 결정 트리 알고리즘의 장점
5.2 교차 검증과 그리드 서치
검증 세트 (Validation Set)
- 테스트 세트를 사용하지 않으면 모델이 과대적합인지 과소적합인지 판단하기 어러움
- 테스트 세트를 사용하지 않고 측정하는 간단한 방법은 훈련 세트를 또 나누는 것
교차 검증 (Cross Validation)
- 검증 세트를 만드느라 훈련 세트가 줄어듦.
- 교차 검증을 이용하면 안정적인 검증 점수를 얻고 훈련에 더 많은 데이터를 사용할 수 있음.
- 검증 세트를 떼어 내어 평가하는 과정을 여러 번 반복함. 점수를 평균하여 최종 검증 점수를 얻음.
- 보통 5-fold, 10-fold를 많이 사용. → 데이터의 8~90%까지 훈련에 사용할 수 있음.
cross_validate() : 사이킷런의 교차 검증 함수
cross_val_score() : cross_validate()의 전신이면서 cross_validate() 함수의 결과 중에서 test_score 값만 반환
이 함수는 fit_time, score_time, test_score 키를 가진 딕셔너리를 반환함.
ㄴ 처음 2개의 키는 각각 모델을 훈련하는 시간과 검증하는 시간을 의미.
ㄴ 교차 검증의 최종 점수는 test_score 키에 담긴 5개의 점수를 평균하여 얻음. 이름은 test_score지만 검증 폴드의 점수.
한가지 주의점 : 훈련 세트를 섞어 폴드를 나누지 않음. → 교차 검증을 할 때 훈련 세트를 섞으려면 분할기(splitter)를 지정.
ㄴ 회귀 모델일 경우 KFold 분할기를 사용 / 분류 모델일 경우 타깃 클래스를 골고루 나누기 위해 StratifiedKFold를 사용
하이퍼파라미터 튜닝
모델 파라미터 : 머신러닝 모델이 학습하는 파라미터
하이퍼파라미터 : 모델이 학습할 수 없어서 사용자가 지정해야만 하는 파라미터
ㄴ 머신러닝 라이브러리를 사용할 때 이런 하이퍼파라미터는 모두 클래스나 메서드의 매개변수로 표현됨.
---> AutoML : 사람의 개입 없이 하이퍼파라미터 튜닝을 자동으로 수행하는 기술
그리드 서치(Grid Search)
- 사이킷런의 GridSearchCV 클래스는 친절하게도 하이퍼파라미터 탐색과 교차 검증을 한 번에 수행.
- 별도로 cross_validate() 함수를 호출할 필요 X
n_jobs : 병렬 실행에 사용할 CPU 코어 수를 지정 (기본값은 1, -1로 지정하면 시스템에 있는 모든 코어 사용)
그리드 서치 과정
- 먼저 탐색할 매개변수를 지정한다.
- 그다음 훈련 세트에서 그리드 서치를 수행하여 최상의 평균 검증 점수가 나오는 매개변수 조합을 찾는다. 이 조합은 그리드 서치 객체에 저장된다.
- 그리드 서치는 최상의 매개변수에서 (교차 검증에 사용한 훈련 세트가 아니라) 전체 훈련 세트를 사용해 최종 모델을 훈련한다. 이 모델도 그리드 서치 객체에 저장된다.
랜덤 서치 (Random Search)
- 매개변수의 값이 수치일 때 값의 범위나 간격을 미리 정하기 어려울 수 있음.
- 너무 많은 매개변수 조건이 있어 그리드 서치 수행 시간이 오래 걸릴 수 있음.
- 매개변수 값의 목록을 전달하는 것이 아니라 매개변수를 샘플링할 수 있는 확률 분포 객체를 전달한다.
ㄴ 싸이파이(scipy)에서 2개의 확률 분포 클래스 uniform, randint
ㄴ 싸이파이의 stats 서브 패키지에 있는 uniform과 randint 클래스는 모두 주어진 범위에서 고르게 값을 뽑는다.
ㄴ (난수 발생기랑 유사)
5.3 트리의 앙상블
정형 데이터와 비정형 데이터
- 정형 데이터 : 어떤 구조로 되어있다는 뜻. → CSV나 데이터베이스, 엑셀에 저장하기 쉬움
- 비정형 데이터 : 데이터베이스나 엑셀로 표현하기 어려운 것들 (텍스트 데이터, 사진, 디지털 음악 등)
ㄴ 텍스트나 사진을 데이터베이스에 저장할 수는 없나?
ㄴ 저장할 수 있다. NoSQL 데이터베이스는 엑셀이나 CSV에 담기 어려운 텍스트나 JSON 데이터를 저장하는 데 용이
앙상블 학습(Ensemble Learning) : 정형 데이터를 다루는 데 가장 뛰어난 성과를 내는 알고리즘 → 대부분 결정 트리를 기반으로 만들어짐.
비정형 데이터는 7장에서 배울 신경망 알고리즘을 사용함.
랜덤 포레스트
- 앙상블 학습의 대표 주자 중 하나로 안정적인 성능 덕분에 널리 사용되고 있음
- 결정 트리를 랜덤하게 만들어 결정 트리의 숲을 만듦 → 각 결정 트리의 예측을 사용해 최종 예측을 만듦
랜덤 포레스트의 훈련 데이터 : 입력한 훈련 데이터에서 랜덤하게 샘플을 추출하여 훈련 데이터를 만듦 (이 때 한 샘플이 중복되어 추출될 수 있음)
부트스트랩 샘플 (Bootstrap Sample) : 데이터 세트에서 중복을 허용하여 데이터를 샘플링하는 방식
RandomForestClassifier : 분류 모델로 기본적으로 전체 특성 개수의 제곱근만큼의 특성을 선택함.
RandomForestRegressor : 회귀 모델로 전체 특성을 사용함.
사이킷런의 랜덤 포레스트는 기본적으로 100개의 결정 트리를 훈련함.
그 다음 분류일 때는 각 트리의 클래스별 확률을 평균하여 가장 높은 확률을 가진 클래스를 예측으로 삼음.
회귀일 때는 단순히 각 트리의 예측을 평균함.
랜덤 포레스트는 결정 트리의 앙상블이기 때문에 DecisionTreeClassifier가 제공하는 중요한 매개변수를 모두 제공한다.
ㄴ criterion, max_depth, max_features, min_samples_split, min_impurity_decrease, min_samples_leaf 등
또한 결정 트리의 큰 장점 중 하나인 특성 중요도를 계산한다.
랜덤 포레스트의 특성 중요도는 각 결정 트리의 특성 중요도를 취합한 것이다.
랜덤 포레스트와 결정 트리의 특성 중요도가 다른 이유는 랜덤 포레스트가 특성의 일부를 랜덤하게 선택하여 결정 트리를 훈련하기 때문이다. 그결과 하나의 특성에 과도하게 집중하지 않고 좀 더 많은 특성이 훈련에 기여할 기회를 얻는다. 이는 과대적합을 줄이고 일반화 성능을 높이는 데 도움이 된다.
RandomForestClassifier에는 자체적으로 모델을 평가하는 점수를 얻을 수 있다.
OOB(Out of Bag) 샘플 : 부트스트랩 샘플에 포함되지 않고 남는 샘플
OOB 샘플을 이용하여 부트스트랩 샘플로 훈련한 결정 트리를 평가할 수 있음.(검증 세트의 역할)
이 점수를 얻으려면 RandomFoerestClassifier 클래스의 oob_score 매개변수를 True로 지정해야 함.(기본값은 False)
엑스트라 트리(Extra Tree)
- 랜덤 포레스트와 매우 비슷하게 동작함.
- 랜덤 포레스트와 엑스트라 트리의 차이점은 부트스트랩 샘플을 사용하지 않는다는 점. (각 결정 트리를 만들 때 전체 훈련 세트 사용) → 대신 노드를 분할할 때 가장 좋은 분할을 찾는 것이 아니라 무작위로 분할함.
2절에서 DecisionTreeClassifier의 splitter 매개변수를 'random'으로 지정했는데, 엑스트라 트리가 사용하는 결정 트리가 바로 splitter='random'인 결정 트리이다.
하나의 결정트리에서 특성을 무작위로 분할한다면 성능이 낮아지겠지만 많은 트리를 앙상블 하기 때문에 과대적합을 막고 검증 세트의 점수를 높이는 효과가 있다.
사이킷런에서 제공하는 엑스트라 트리는 ExtraTreesClassifier이다.
엑스트라 트리의 회귀 버전은 ExtraTreesRegressor 클래스이다.
그레디언트 부스팅(Gradient Boosting)
- 깊이가 얕은 결정 트리를 사용하여 이전 트리의 오차를 보완하는 방식으로 앙상블 하는 방법.
- 사이킷런의 GradientBoostingClassifier는 기본적으로 깊이가 3인 결정 트리를 100개 사용함.
- 깊이가 얕은 결정트리를 사용하기 때문에 과대적합에 강하고 일반적으로 높은 일반화 성능을 기대할 수 있음.
- 경사 하강법을 사용하여 트리를 앙상블에 추가
- 분류에서는 로지스틱 손실 함수를 사용하고 회귀에서는 평균 제곱 오차 함수를 사용함.
subsample : 트리 훈련에 사용할 훈련 세트의 비율 (기본값은 1.0으로 전체 훈련 세트를 사용)
ㄴ 1보다 작으면 훈련 세트의 일부를 사용 → 마치 경사 하강법 단계마다 일부 샘플을 랜덤하게 선택하여 진행하는
확률적 경사 하강법이나 미니배치 경사 하강법과 비슷함.
히스토그램 기반 그레디언트 부스팅(Histogram-based Gradient Bootsting)
- 정형 데이터를 다루는 머신러닝 알고리즘 중에 가장 인기가 높은 알고리즘.
- 입력 특성을 256개의 구간으로 나눠 노드를 분할할 때 최적의 분할을 매우 빠르게 찾을 수 있음.
- 256개의 구간 중에서 하나를 떼어 놓고 누락된 값을 위해서 사용함.
ㄴ 따라서 입력에 누락된 특성이 있더라도 이를 따로 전처리할 필요가 없음.
- HistGradientBoostingClassifier는 기본 매개변수에서 안정적인 성능을 얻을 수 있음.
ㄴ 트리의 개수를 지정하는데 n_estimators 대신에 부스팅 반복 횟수를 지정하는 max_iter를 사용함.
사이킷런의 히스토그램 기반 그레디언트 부스팅은 아직 테스트 과정에 있어 클래스를 사용하려면
sklearn.experimental 패키지 아래에 있는 enable_hist_gradient_boosting 모듈을 임포트해야함.
permutation_importance() : 히스토그램 기반 그레디언트 부스팅의 특성 중요도 계산 함수
ㄴ 특성을 하나씩 랜덤하게 섞어서 모델의 성능이 변화하는지를 관찰하여 어떤 특성이 중요한지를 계산함.
ㄴ 훈련 세트뿐만 아니라 테스트 세트에도 적용할 수 있고 사이킷런에서 제공하는 추정기 모델에 모두 사용할 수 있음.
permutation_importance() 함수가 반환하는 객체는 반복하여 얻은 특성 중요도(importances), 평균(importances_mean), 표준 편차(importances_std)를 담고 있음.
히스토그램 기반 그레디언트 부스팅의 회귀 버전은 HistGradientBoostingRegressor 클래스에 구현되어 있음.
사이킷런 말고도 그레디언트 부스팅 알고리즘을 구현한 라이브러리가 여럿 있음.
ㄴ XGBoost : 코랩에서 사용 가능하고, 사이킷런의 cross_validate() 함수와 함께 사용할 수도 있음.
ㄴ tree_method 매개변수를 'hist'로 지정하면 히스토그램 기반 그레디언트 부스팅을 사용할 수 있음.
ㄴ LightGBM : 마이크로소프트에서 만든 라이브러리. 빠르고 최신 기술을 많이 적용하고 있어 인기가 점점 높아짐.