from sklearn.model_selection import train_test_split
from sklearn.datasets import make_moons
X, y = make_moons(n_samples=500, noise=0.30, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
log_clf = LogisticRegression(solver="lbfgs", random_state=42)
rnd_clf = RandomForestClassifier(n_estimators=100, random_state=42)
svm_clf = SVC(gamma="scale", random_state=42)
voting_clf = VotingClassifier(
estimators=[('lr', log_clf), ('rf', rnd_clf), ('svc', svm_clf)],
voting='hard')
voting_clf.fit(X_train, y_train)
from sklearn.metrics import accuracy_score
for clf in (log_clf, rnd_clf, svm_clf, voting_clf):
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print(clf.__class__.__name__, accuracy_score(y_test, y_pred))
LogisticRegression 0.864 RandomForestClassifier 0.896 SVC 0.896 VotingClassifier 0.912
투표 기반 분류기가 다른 개별 분류기보다 성능이 조금 더 높음
개별 분류기의 예측을 평균 내어 확률이 가장 높은 클래스를 예측하는 방법을 간접 투표(soft voting)라 함
직접 투표 방식보다 간접 투표가 보통 성능이 더 좋음
7.2 배깅과 페이스팅¶
같은 알고리즘을 사용하고 훈련 세트의 서브셋을 무작위로 구정하여 분류기를 각기 다르게 학습시키는 방법도 존재
훈련 세트에서 중복을 허용하여 샘플링하는 방식을 배깅(bagging)이라 하며, 중복을 허용하지 않고 샘플링 하는 방식을 페이스팅(pasting)
7.2.1 사이킷런의 배깅과 페이스팅¶
bootstrap=True은 배깅, bootstrap=False는 패이스팅
n_jobs 매개변수는 사이킷런이 훈련과 예측에 사용할 CPU 코어 수를 지정함(-1로 지정하면 가용한 모든 코어를 사용)
배깅의 경우 bootstrap=True, 페이스팅의 경우 bootstrap=False로 지정
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
# 배깅 사용 결정 트리
bag_clf = BaggingClassifier(
DecisionTreeClassifier(), n_estimators=500,
max_samples=100, bootstrap=True, random_state=42)
bag_clf.fit(X_train, y_train)
y_pred = bag_clf.predict(X_test)
from sklearn.metrics import accuracy_score
print(accuracy_score(y_test, y_pred))
0.904
# 단일 결정 트리
tree_clf = DecisionTreeClassifier(random_state=42)
tree_clf.fit(X_train, y_train)
y_pred_tree = tree_clf.predict(X_test)
print(accuracy_score(y_test, y_pred_tree))
0.856
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
import numpy as np
def plot_decision_boundary(clf, X, y, axes=[-1.5, 2.45, -1, 1.5], alpha=0.5, contour=True):
x1s = np.linspace(axes[0], axes[1], 100)
x2s = np.linspace(axes[2], axes[3], 100)
x1, x2 = np.meshgrid(x1s, x2s)
X_new = np.c_[x1.ravel(), x2.ravel()]
y_pred = clf.predict(X_new).reshape(x1.shape)
custom_cmap = ListedColormap(['#fafab0','#9898ff','#a0faa0'])
plt.contourf(x1, x2, y_pred, alpha=0.3, cmap=custom_cmap)
if contour:
custom_cmap2 = ListedColormap(['#7d7d58','#4c4c7f','#507d50'])
plt.contour(x1, x2, y_pred, cmap=custom_cmap2, alpha=0.8)
plt.plot(X[:, 0][y==0], X[:, 1][y==0], "yo", alpha=alpha)
plt.plot(X[:, 0][y==1], X[:, 1][y==1], "bs", alpha=alpha)
plt.axis(axes)
plt.xlabel(r"$x_1$", fontsize=18)
plt.ylabel(r"$x_2$", fontsize=18, rotation=0)
fig, axes = plt.subplots(ncols=2, figsize=(10,4), sharey=True)
plt.sca(axes[0])
plot_decision_boundary(tree_clf, X, y)
plt.title("Decision Tree", fontsize=14)
plt.sca(axes[1])
plot_decision_boundary(bag_clf, X, y)
plt.title("Decision Trees with Bagging", fontsize=14)
plt.ylabel("")
plt.show()
배깅이 페이스팅보다 편향이 조금 더 높음, 하지만 다양성을 추가하는 페이스팅은 상관관계를 줄이므로 앙상블의 분산을 감소시킴
전반적으로 배깅이 더 나은 모델을 만들기 때문에 일반적으로 선호
시간과 CPU 파워에 여유가 있다면 교차 검증으로 배깅과 페이스팅 모두 평가해 더 나은 쪽을 선택하는 것이 더 좋음
7.2.2 oob 평가¶
배깅을 사용하면 어떤 샘플은 한 예측기를 위해 여러 번 샘플링되고 어떤 것은 전혀 선택되지 않을 수 있음
훈련에 선택되지 않은 훈련 샘플을 oob(out-of-bag) 샘플이라고 부름
예측기가 훈련되는 동안에는 oob 샘플을 사용하지 않으므로 별도의 검증 세트를 사용하지 않고 oob 샘플을 사용해 평가할 수 있음
bag_clf = BaggingClassifier(
DecisionTreeClassifier(), n_estimators=500,
bootstrap=True, oob_score=True, random_state=40)
bag_clf.fit(X_train, y_train)
bag_clf.oob_score_
0.8986666666666666
from sklearn.metrics import accuracy_score
y_pred = bag_clf.predict(X_test)
accuracy_score(y_test, y_pred)
0.912
oob 평가와 테스트 세트에서의 정확도가 비슷한 것을 확인(차이가 많이 나면 문제)
oob_decisionfunction 을 통해 oob 샘플에 대한 결정 함수의 값도 확인 가능
7.3 랜덤 패치와 램덤 서브스페이스¶
BaggingClassifier는 특성 샘플링도 지원, 매우 고차원의 데이터셋을 다룰 때 유용
훈련 특성과 샘플을 모두 샘플링하는 것을 랜덤 패치 방식, 훈련 샘플을 모두 사용하고 특성은 샘플링하는 방식을 랜덤 서브스페이스 방식이라고 함
특성 샘플링은 더 다양한 예측기를 만들며 편향을 늘리는 대신 분산을 낮춤
7.4 랜덤 포레스트¶
랜덤 포레스트는 일반적으로 배깅 방법(또는 페이스팅)을 적용한 결정트리의 앙상블
트리의 노드를 분할할 때 전체 특성 중에서 최선의 특성을 찾는 대신 무작위로 선택한 특성 후보 중에서 최적의 특성을 찾는 식으로 무작위성을 더 주입, 이는 트리를 더욱 다양하게 만들고 편향을 손해보는 대신 분산을 낮추어 전체적으로 더 훌륭한 모델을 만듦
7.4.1 엑스트라 트리¶
극단적으로 무작위한 트리의 랜덤 포레스트를 익스트림 랜덤 트리 앙상블이라고 부름
최적의 임계값을 찾는 대신 후보 특성을 사용해 무작위로 분할한 다음 그중에서 최상의 분할을 선택
랜덤 포레스트보다 작업 소요 시간이 훨씬 빠름(편향은 증가, 분산은 감소)
7.4.2 특성 중요도¶
특성의 상대적 중요도를 측정하기 쉬움, 어떤 특성이 중요한지 빠르게 확인 가능
중요도의 전체 합이 1이 되도록 feature_importances 변수에 저장
7.5 부스팅¶
부스팅(boosting)은 약한 학습기를 여러 개 연결하여 강한 학습기를 만드는 앙상블 방법
앞의 모델을 보완해나가면서 일련의 예측기를 학습시키는 것으로 가장 인기 있는 것은 에이다부스트(AdaBoost)와 그레이디언트 브스팅(gradient boosting)
7.5.1 에이다부스트¶
이전 모델이 과소적합했던 훈련 샘플의 가중치를 더 높혀 새로운 예측기는 학습하기 어려운 샘플에 점점 더 맞춰지게 되는데 이런 방식을 에이다부스트에서 사용하는 방식
첫 번째 분류기를 훈련 세트에서 훈련시키고 예측을 만듬, 그다음에 알고리즘이 잘못 분류된 훈련 샘플의 가중치를 상대적으로 높혀 다시 예측하고 계속 업데이트하는 방식
7.5.2 그레이디언트 부스팅¶
에이다부스트처럼 반복마다 샘플의 가중치를 수정하는 대신 이전 예측기가 만든 잔여 오차에 새로운 예측기를 학습시킴
learning_rate 매개변수가 각 트리의 기여 정도를 조절, 0.1처럼 낮게 설정하면 앙상블을 훈련 세트에 학습시키기 위해 많은 트리가 필요하지만 일반적으로 예측의 성능은 좋아짐
XGBoost는 대표적인 그레이디언트 부스팅
7.6 스태킹¶
- 앙상블에 속한 모든 예측기의 예측을 취합하는 간단한 함수(직접 투표 등)를 사용하는 대신, 취합하는 모델을 훈련시키고자 하는 방법
연습문제¶
정확히 같은 훈련 데이터로 다섯 개의 다른 모델을 훈련시켜서 모두 95% 정확도를 얻었다면 이 모델들을 연결하여 더 좋은 결과를 얻을 수 있을까요? 가능하다면 어떻게 해야 할까요? 그렇지 않다면 왜일까요?
앙상블을 만들어 더 나은 결과를 기대할 수 있다. 모델이 서로 다르다면 더 좋다. 그리고 다른 훈련 샘플에서 훈련되었다면 더더욱 좋다. (배깅 / 페이스팅의 핵심). 그렇지 않아도 모델이 서로 많이 다르면 여전히 좋은 결과를 낸다.
직접 투표와 간접 투표 분류기 사이의 차이점은 무엇일까요?
직접 투표 분류기는 횟수를 중요시하여, 가장 많은 투표를 얻은 클래스를 선택. (다수결)간접 투표 분류기는 각 클래스의 평균적인 확률 추정값을 계산해서 가장 높은 확률을 가진 클래스를 고름. 이 방법은 신뢰가 높은 투표에 더 가중치를 주고 종종 더 나은 성능을 낸다. 하지만 앙상블에 있는 모든 분류기가 클래스 확률을 추정할 수 있어야 사용 가능하다.
배깅 앙상블의 훈련을 여러 대의 서버에 분산시켜 속도를 높일 수 있을까요? 페이스팅 앙상블, 부스팅 앙상블, 랜덤 포레스트, 스태킹 앙상블의 경우는 어떨까요?
배깅 앙상블의 각 예측기는 독립적이므로 여러 대의 서버에 분산하여 앙상블의 훈련 속도를 높일 수 있다. 페이스팅, 랜덤 포레스트도 마찬가지.하지만 부스팅 앙상블의 예측기는 이전 예측기를 기반으로 만들어지기 때문에 훈련이 순차적이어야하고, 여러 대의 서버에 분산해서 얻을 수 있는 이득이 없다.스태킹 앙상블의 경우 한 층의 모든 예측기가 각각 독립적이므로 여러대의 서버에서 병렬로 훈련될 수 있다. 하지만 한 층에 있는 예측기들은 이전 층의 예측기들이 훈련된 후에 훈련될 수 있다.
oob 평가의 장점은 무엇인가요?
배깅 앙상블의 각 예측기가 훈련에 포함되지 않은 샘플을 사용해 평가된다. 이는 추가적인 검증 세트가 없어도 편향되지 않게 앙상블을 평가하도록 도와준다. 그러므로 훈련에 더 많은 샘플을 사용할 수 있어서 앙상블의 성능은 조금 더 향상 될 것
무엇이 엑스트라 트리를 일반 랜덤 포레스트보다 더 무작위하게 만드나요? 추가적인 무작위성이 어떻게 도움이 될까요? 엑스트라 트리는 일반 랜덤 포레스트보다 느릴까요, 빠를까요?
랜덤 포레스트에서 트리가 성장할 때 각 노드에서 특성의 일부를 무작위로 선택해 분할에 사용한다. 가능한 최선의 임계점을 찾는게 아니라, 각 특성에 대해 랜덤한 임계점을 사용한다, 이 추가적인 무작위성은 규제처럼 작동한다. 즉 랜포가 과대적합이라면 엑스트라는 X. 가능한 최선의 임계점을 찾는게 아니라 랜포보다 훈련이 더 빠르다. 그러나 예측을 할 때는 랜덤 포레스트 보다 더 빠르지도 느리지도 않다.
아다부스트 앙상블이 훈련 데이터에 과소적합되었다면 어떤 매개변수를 어떻게 바꾸어야 할까요?
예측기의 수를 증가시키거나, 기반 예측기의 규제 하이퍼파라미터를 감소시켜 볼 수 있다. 또한 학습률을 약간 증가시켜 볼 수 있다.
그래디언트 부스팅 앙상블이 훈련 데이터에 과대적합되었다면 학습률을 높여야 할까요, 낮춰야 할까요?
학습률을 감소시켜야한다 ( 예측기 수가 너무 많으면 ) 알맞은 개수를 찾기 위해 조기 종료 기법을 사용할 수 있다.
from IPython.core.display import display, HTML
display(HTML("<style>.container {width:100% !important;}</style>"))
C:\Users\we626\AppData\Local\Temp\ipykernel_8888\3013929331.py:1: DeprecationWarning: Importing display from IPython.core.display is deprecated since IPython 7.14, please import from IPython display from IPython.core.display import display, HTML
'Book report > 핸즈온 머신러닝' 카테고리의 다른 글
[핸즈온 머신러닝] Chapter 6. 결정 트리 (0) | 2024.04.01 |
---|---|
[핸즈온 머신러닝] Chapter 5. 서포트 벡터 머신 (0) | 2023.09.12 |
[핸즈온 머신러닝] Chapter 4. 모델 훈련 (0) | 2023.09.06 |
[핸즈온 머신러닝] Chapter 3. 분류 (0) | 2023.08.28 |
[핸즈온 머신러닝] Chapter 2. 머신러닝 프로젝트 처음부터 끝까지 (0) | 2023.08.04 |