Chapter 05-1
결정 트리
- 결정 트리(Decision Tree)
예, 아니오에 대한 질문을 이어가면서 정답을 찾아 학습하는 알고리즘
사이킷런의 DecisionTreeClassifier 클래스 사용
특성값의 스케일은 결정 트리 알고리즘에 영향을 미치지 않기 때문에 표준화 전처리를 할 필요없다.
특성 중요도(불순도를 감소하는데 기여한 정도)를 활용하면 결정 트리 모델을 특성 선택에 활용할 수 있다.
불순도: 결정 트리가 최적의 질문을 찾기 위한 기준
지니 불순도(Gini impuricity)는 1 - (음성 클래스 비율의 제곱 + 양성 클래스 비율의 제곱)으로 구한다.
지니 불순도가 0이라면 순수 노드라고 부른다.
결정 트리 모델은 부모 노드와 자식 노드의 불순도 차이(정보 이득, information gain)가 가능한 크도록 트리를 성장 시킨다.
가지치기: 트리의 최대 깊이를 지정하여 가지치기를 한다.
DecisionTreeClassifier 클래스의 max_depth 매개변수를 지정한다.
- 함수 모음
info(): 데이터프레임의 각 열의 데이터 타입과 누락된 데이터가 있는지 확인하는 메서드
describe(): 열에 대한 간략한 통계를 출력해주는 메서드
plot_tree(): 결정 트리를 이해하기 쉬운 트리 그림으로 출력해주는 함수
코랩 실습 화면
# 결정 트리 모델
dt = DecisionTreeClassifier(random_state = 42)
dt.fit(train_scaled, train_target)
print("결정 트리 모델 훈련 세트 점수: ", dt.score(train_scaled, train_target))
print("결정 트리 모델 테스트 세트 점수: ", dt.score(test_scaled, test_target))
# 트리 그림 출력
plt.figure(figsize=(10, 7))
plot_tree(dt)
plt.show()
# 깊이 1로 제한한 트리 그림
plt.figure(figsize=(10, 7))
plot_tree(dt, max_depth=1, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()
# 깊이 3의 결정 트리 모델
dt = DecisionTreeClassifier(max_depth=3, random_state = 42)
dt.fit(train_scaled, train_target)
print("깊이 3의 결정 트리 모델 훈련 세트 점수: ", dt.score(train_scaled, train_target))
print("깊이 3의 결정 트리 모델 테스트 세트 점수: ", dt.score(test_scaled, test_target))
# 깊이 3의 결정 트리 그림
plt.figure(figsize=(20, 15))
plot_tree(dt, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()
# 데이터 전처리없이 결정 트리 모델 훈련
dt = DecisionTreeClassifier(max_depth=3, random_state=42)
dt.fit(train_input, train_target)
print("데이터 전처리없이 결정 트리 모델 훈련 세트 점수: ", dt.score(train_input, train_target))
print("데이터 전처리없이 결정 트리 모델 테스트 세트 점수: ", dt.score(test_input, test_target))
# 데이터 전처리없는 결정 트리 그림
plt.figure(figsize=(20, 15))
plot_tree(dt, filled=True, feature_names=['alcohol', 'sugar', 'pH'])
plt.show()
- 출력 화면
결정 트리 모델 훈련 세트 점수: 0.996921300750433
결정 트리 모델 테스트 세트 점수: 0.8592307692307692
깊이 3의 결정 트리 모델 훈련 세트 점수: 0.8454877814123533
깊이 3의 결정 트리 모델 테스트 세트 점수: 0.8415384615384616
데이터 전처리없이 결정 트리 모델 훈련 세트 점수: 0.8454877814123533
데이터 전처리없이 결정 트리 모델 테스트 세트 점수: 0.8415384615384616
Chapter 05-2
교차 검증과 그리드 서치
검증 세트(validation set): 훈련 세트를 또 나눠서 테스트 세트를 사용하지 않고 모델을 평가하는 세트
교차 검증(cross validation): 검증 세트를 떼어 내어 평가하는 과정을 여러 번 반복하는 것
이 점수를 평균하여 최종 검증 점수를 얻는다.
기본 미션
교차 검증을 그림으로 설명하기
코랩 실습 화면
# 교차 검증
# cross_validate() 사용
scores = cross_validate(dt, train_input, train_target)
print("교차 검증: ", scores)
# 교차 검증의 최종 점수 (test_score 의 평균)
print("교차 검증의 최종 점수: ", np.mean(scores['test_score']))
# 훈련 세트를 섞은 교차 검증
# StratifiedKFold() 사용
splitter = StratifiedKFold(n_splits=10, shuffle=True, random_state=42)
scores = cross_validate(dt, train_input, train_target, cv=splitter)
print("훈련 세트를 섞은 교차 검증의 최종 점수: ", np.mean(scores['test_score']))
- 출력 화면
교차 검증: {'fit_time': array([0.00725913, 0.00694489, 0.00768757, 0.0073359 , 0.00700569]), 'score_time': array([0.00112009, 0.00117517, 0.00124049, 0.00114226, 0.00115561]), 'test_score': array([0.86346154, 0.85 , 0.87487969, 0.85755534, 0.8373436 ])}
교차 검증의 최종 점수: 0.856648034352558
훈련 세트를 섞은 교차 검증의 최종 점수: 0.8591544390099303
하이퍼파라미터 튜닝: 하이퍼파라미터는 모델이 학습할 수 없어서 사용자가 지정해야만 하는 파라미터라 한다.
튜닝은 라이브러리가 제공하는 기본값을 그대로 사용해 모델을 훈련하고 교차 검증을 통해서 매개변수를 조금씩 바꾼다.
그리드 서치(Grid Search): 하이퍼파라미터 탐색을 자동화해 주는 도구
사이킷런의 GridSearchCV 클래스 사용
코랩 실습 화면
# 하이파라미터 탐색과 교차 검증 한번에 수행
# GridSearch 클래스 사용
params = {'min_impurity_decrease': [0.0001, 0.0002, 0.0003, 0.0004, 0.0005]}
gs = GridSearchCV(DecisionTreeClassifier(random_state=42), params, n_jobs=-1)
gs.fit(train_input, train_target)
# GridSearch가 찾은 검증 점수가 가장 높은 모델
dt = gs.best_estimator_
print("GridSearch를 이용한 교차 검증의 최종 점수: ", dt.score(train_input, train_target))
print("GridSearch가 찾은 최적의 매개변수: ", gs.best_params_)
print("교차 검증의 평균 점수: ", gs.cv_results_['mean_test_score'])
# 교차 검증의 평균 점수 중 가장 큰 값 찾기
# argmax() 사용
best_index = np.argmax(gs.cv_results_['mean_test_score'])
print("argmax()로 찾은 최적의 매개변수: ", gs.cv_results_['params'][best_index])
- 출력 화면
GridSearch를 이용한 교차 검증의 최종 점수: 0.9615162593804117
GridSearch가 찾은 최적의 매개변수: {'min_impurity_decrease': 0.0001}
교차 검증의 평균 점수: [0.86819297 0.86453617 0.86492226 0.86780891 0.86761605]
argmax()로 찾은 최적의 매개변수: {'min_impurity_decrease': 0.0001}
랜덤 서치(Random Search): 매개변수를 샘플링할 수 있는 확률 분포 객체를 전달한다. 연속된 매개변수 값을 탐색할 때 유용하다.
코랩 실습 화면
# 0~9의 랜덤 숫자 10개 출력
rgen = randint(0, 10)
rgen.rvs(10)
# 1000개의 숫자 샘플링 후 0~9의 각 개수 출력
np.unique(rgen.rvs(1000), return_counts=True)
# uniform 클래스로 0~1사이의 랜점 숫자 10개 출력
ugen = uniform(0, 1)
ugen.rvs(10)
# 탐색할 매개변수의 범위 지정
params = {'min_impurity_decrease': uniform(0.0001, 0.001),
'max_depth': randint(20, 50),
'min_samples_split': randint(2, 25),
'min_samples_leaf': randint(1, 25),
}
# 교차 검증 수행 및 최적의 매개변수 조합 찾기
gs = RandomizedSearchCV(DecisionTreeClassifier(random_state=42), params, n_iter=100, n_jobs=-1, random_state=42)
gs.fit(train_input, train_target)
print("최적의 매개변수 조합: ", gs.best_params_)
print("최고의 교차 검증 점수: ", np.max(gs.cv_results_['mean_test_score']))
# 최적 모델의 성능 홧인
dt = gs.best_estimator_
print("최적 모델의 점수: ", dt.score(test_input, test_target))
- 출력 화면
최상의 매개변수 조합: {'max_depth': 14, 'min_impurity_decrease': 0.0004, 'min_samples_split': 12}
최상의 교차 검증 점수: 0.8683865773302731
최적의 매개변수 조합: {'max_depth': 39, 'min_impurity_decrease': 0.00034102546602601173, 'min_samples_leaf': 7, 'min_samples_split': 13}
최고의 교차 검증 점수: 0.8695428296438884
최적 모델의 점수: 0.86
- 함수 모음
cross_validate(): 교차 검증 함수, 평가할 모델 객체를 첫 번째 매개변수로 전달하고 훈련 세트를 전달한다.
회귀 모델일 경우 KFold 분할기를 사용하고 cv=StratifiedKFold()를 전달한다.
Chapter 05-3
트리의 앙상블
정형 데이터(structured data): 어떤 구조의 형태로 되어 있는 데이터 ex) CSV, 데이터베이스, 엑셀 등
비정형 데이터(unstructured data): 정형 데이터와 반대되는 데이터 ex) 텍스트 데이터, 사진, 음악 등
앙상블 학습(ensemble learning): 정형 데이터를 다루는 알고리즘 중 가장 뛰어난 성과를 내는 알고ㅗ리즘
대부분 결정 트리를 기반으로 만들어져 있다.
- 랜덤 포레스트(Random Forest)
결정 트리를 랜덤하게 만들어 결정 트리의 숲을 만든다. 그리고 각 결정 트리의 예측을 사용해 최종 예측을 만든다.
훈련 데이터에서 랜덤하게 샘플을 추출하여 훈련 데이터를 만든다. 샘플이 중복되어 추출될 수도 있다. (부트스트랩 샘플)
앙상블 학습의 대표 주자 중 하나로 안정적인 성능을 갖고있다.
사이킷런의 RandomForestClassifier 클래사 사용
부트스트랩 샘플(bootstrap sample): 훈련 데이터에서 랜덤하게 샘플을 추출하여 훈련 데이터를 만드는 것, 중복 추출도 가능
OOB 샘플(out of bag): 부트스트랩 샘플에 포함되지 않고 남는 샘플
선택 미션
Ch.05(05-3) 앙상블 모델 손코딩 코랩 화면 인증하기
코랩 실습 화면
data = wine[['alcohol', 'sugar', 'pH']].to_numpy()
target = wine['class'].to_numpy()
train_input, test_input, train_target, test_target = train_test_split(data, target, test_size = 0.2, random_state = 42)
# 랜덤 포레스트 모델
rf = RandomForestClassifier(n_jobs=-1, random_state=42)
# 교차 검증
# cross_validate 함수 사용
scores = cross_validate(rf, train_input, train_target, return_train_score=True, n_jobs=-1)
print("랜덤 포레스트 모델 훈련 세트 점수: ", np.mean(scores['train_score']))
print("랜덤 포레스트 모델 테스트 세트 점수: ", np.mean(scores['test_score']))
rf.fit(train_input, train_target)
print("랜덤 포레스트 모델의 특성 중요도: ", rf.feature_importances_)
# OOB 샘플 사용
# oob_score 매개변수 True로 전달
rf = RandomForestClassifier(oob_score=True, n_jobs=-1, random_state=42)
rf.fit(train_input, train_target)
print("랜덤 포레스트 모델의 OOB 점수: ", rf.oob_score_)
- 출력 화면
랜덤 포레스트 모델 훈련 세트 점수: 0.9973541965122431
랜덤 포레스트 모델 테스트 세트 점수: 0.8905151032797809
랜덤 포레스트 모델의 특성 중요도: [0.23167441 0.50039841 0.26792718]
랜덤 포레스트 모델의 OOB 점수: 0.8934000384837406
- 엑스트라 트리(Extra Trees)
랜덤 포레스트와 비슷하게 동작하지만 부트스트랩 샘플을 사용하지 않는다.
각 결정 트리를 만들 때 전체 훈련 세트를 사용한다.
대신 노드를 분할할 때 무작위로 분할한다.
사이킷런의 ExtraTreesClassifier 클래스 사용
코랩 실습 화면
# 엑스트라 트리 모델
et = ExtraTreesClassifier(n_jobs=-1, random_state=42)
score = cross_validate(et, train_input, train_target, return_train_score=True, n_jobs=-1)
print("엑스트라 트리 모델 훈련 세트 점수: ", np.mean(scores['train_score']))
print("엑스트리 트리 모델 테스트 세트 점수: ", np.mean(score['test_score']))
et.fit(train_input, train_target)
print("엑스트라 트리 모델의 특성 중요도: ", et.feature_importances_)
- 출력 화면
엑스트라 트리 모델 훈련 세트 점수: 0.9973541965122431
엑스트리 트리 모델 테스트 세트 점수: 0.8887848893166506
엑스트라 트리 모델의 특성 중요도: [0.20183568 0.52242907 0.27573525]
- 그레이디언트 부스팅(gradient boosting)
깊이가 얕은 결정 트리를 사용, 결정 트리를 연속적으로 추가하여 손실 함수를 최소화하는 앙상블 방법
사이킷런의 GradientBoostingClassifier 클래스 사용
코랩 실습 화면
# 그레이디언트 부스팅 모델
gb = GradientBoostingClassifier(random_state=42)
score = cross_validate(gb, train_input, train_target, return_train_score=True, n_jobs=-1)
print("그레이디언트 부스팅 모델 훈련 세트 점수: ", np.mean(scores['train_score']))
print("그레이디언트 부스팅 모델 테스트 세트 점수: ", np.mean(scores['test_score']))
# 트리 개수와 학습률 늘린 그레이디언트 부스팅 모델
gb = GradientBoostingClassifier(n_estimators=500, learning_rate=0.2, random_state=42)
score = cross_validate(gb, train_input, train_target, return_train_score=True, n_jobs=-1)
print("트리 늘린 그레이디언트 부스팅 모델 훈련 세트 점수: ", np.mean(score['train_score']))
print("트리 늘린 그레이디언트 부스팅 모델 테스트 세트 점수: ", np.mean(score['test_score']))
gb.fit(train_input, train_target)
print("트리 늘린 그레이디언트 부스팅 모델의 특성 중요도: ", gb.feature_importances_)
- 출력 화면
그레이디언트 부스팅 모델 훈련 세트 점수: 0.9973541965122431
그레이디언트 부스팅 모델 테스트 세트 점수: 0.8905151032797809
트리 늘린 그레이디언트 부스팅 모델 훈련 세트 점수: 0.9464595437171814
트리 늘린 그레이디언트 부스팅 모델 테스트 세트 점수: 0.8780082549788999
트리 늘린 그레이디언트 부스팅 모델의 특성 중요도: [0.15872278 0.68010884 0.16116839]
- 히스토그램 기반 그레이디언트 부스팅(Histogram-based Gradient Boosting)
데이터를 전처리할 필요 없는 모델
사이킷런의 HistGradientBoostingClassifier 클래스 사용
XGBoost, LightGBM 라이브러리로 히스토그램 기반 그레이디언트 부스팅을 사용할 수 있다.
코랩 실습 화면
# 히스토그램 기반 그레이디언트 부스팅
hgb = HistGradientBoostingClassifier(random_state=42)
score = cross_validate(hgb, train_input, train_target, return_train_score=True)
print("히스토그램 기반 그레이디언트 부스팅 모델 훈련 세트 점수: ", np.mean(score['train_score']))
print("히스토그램 기반 그레이디언트 부스팅 모델 테스트 세트 점수: ", np.mean(score['test_score']))
hgb.fit(train_input, train_target)
result = permutation_importance(hgb, train_input, train_target, n_repeats=10, random_state=42, n_jobs=-1)
print("히스토그램 기반 그레이디언트 부스팅 모델의 특성 중요도: ", result.importances_mean)
print("히스토그램 기반 그레이디언트 부스팅 모델의 성능 점수: ", hgb.score(test_input, test_target))
# XGBoost 라이브러리를 이용한 히스토그램 기반 그레이디언트 부스팅 모델
xgb = XGBClassifier(tree_method='hist', random_state=42)
score = cross_validate(xgb, train_input, train_target, return_train_score=True)
print("XGBoost의 히스토그램 기반 그레이디언트 부스팅 모델 훈련 세트 점수: ", np.mean(scores['train_score']))
print("XGBoost의 히스토그램 기반 그레이디언트 부스팅 모델 테스트 세트 점수: ", np.mean(scores['test_score']))
# LightGBM 라이브러리를 이용한 히스토그램 기반 그레이디언트 부스팅 모델
lgb = LGBMClassifier(random_state=42)
scores = cross_validate(lgb, train_input, train_target, return_train_score=True, n_jobs=-1)
print("LightGBM의 히스토그램 기반 그레이디언트 부스팅 모델 훈련 세트 점수: ", np.mean(scores['train_score']))
print("LightGBM의 히스토그램 기반 그레이디언트 부스팅 모델 테스트 세트 점수: ", np.mean(score['test_score']))
- 출력 화면
히스토그램 기반 그레이디언트 부스팅 모델 훈련 세트 점수: 0.9321723946453317
히스토그램 기반 그레이디언트 부스팅 모델 테스트 세트 점수: 0.8801241948619236
히스토그램 기반 그레이디언트 부스팅 모델의 특성 중요도: [0.08876275 0.23438522 0.08027708]
히스토그램 기반 그레이디언트 부스팅 모델의 성능 점수: 0.8723076923076923
XGBoost의 히스토그램 기반 그레이디언트 부스팅 모델 훈련 세트 점수: 0.9973541965122431
XGBoost의 히스토그램 기반 그레이디언트 부스팅 모델 테스트 세트 점수: 0.8905151032797809
LightGBM의 히스토그램 기반 그레이디언트 부스팅 모델 훈련 세트 점수: 0.935828414851749
LightGBM의 히스토그램 기반 그레이디언트 부스팅 모델 테스트 세트 점수: 0.8799326275264677
- 함수 모음
permutation_importance(): 히스토그램 기반 그레이디언트 부스팅의 특성 중요도 계산 함수