1. 백만 개의 샘플을 가진 훈련 세트에서 (규제 없이) 훈련시킨 결정 트리의 깊이는 대략 얼마일까요?
#
m개의 리프 노드를 포함한 균형이 잘 잡힌 이진 트리의 깊이는 을 반올림 한 것과 같습니다.
이진 결정 트리를 제한을 두지 않고 훈련시키면, 훈련 샘플마다 하나의 리프 노드가 되므로, 어느 정도 균형이 잘 잡힌 트리가 됩니다. 따라서 훈련 세트에 백만 개 샘플이 있다면, 결정 트리의 깊이는 이 될 것입니다.
(실제로는 완벽하게 균형 잡힌 트리가 만들어지지 않기 때문에 조금 더 늘어납니다.
2. 한 노드의 지니 불순도가 보통 그 부모 노드보다 작을까요? 클까요?
일반적으로 작거나 클까요? 아니면 항상 작거나 클까요?
#
한 노드의 지니 불순도는 일반적으로 부모의 불순도보다 낮습니다.
이는 자식의 지니 불순도의 가중치 합이 최소화되는 방향으로 각 노드를 분할하는 CART 알고리즘의 비용 함수 때문입니다. 그러나, 다른 자식 노드의 지니 불순도 감소량이 어느 노드의 불순도 증가량보다 큰 경우라면, 부모의 불순도보다 큰 노드가 생길 수 있습니다.
3. 결정 트리에 훈련 세트가 과대적합되었다면, max_depth를 줄이는 것이 좋을까요?
#
결정 트리가 훈련 세트에 과대적합되었다면, 모델에 제약을 가해 규제해야 하므로 max_depth를 낮추는게 좋습니다.
4. 결정 트리가 훈련 세트에 과소적합되었다면, 입력 특성의 스케일을 조정하는 것이 좋을까요?
#
결정 트리는 훈련 데이터의 스케일이나 원점에 맞추어져있는지 상관하지 않습니다.
5. 백만 개의 샘플을 가진 훈련 세트에 결정 트리를 훈련시키는 데 한 시간이 걸렸다면,
천만 개의 샘플을 가진 훈련 세트는 얼마나 걸릴까요?
#
결정 트리 훈련의 계산 복잡도는 입니다.
그러므로 훈련 세트의 크기에 10을 곱하면 훈련 시간은
배 늘어납니다.
만약 m = 100,000이면, K = 11.7 정도가 되므로, 대략 11.7 시간이 걸릴 것으로 예상할 수 있습니다.
6. 십만 개의 샘플을 가진 훈련 세트가 있다면, presort=True로 지정하는 것이 훈련 속도를 높일까요?
#
데이터셋의 샘플 수가 수천 개 미만일 때, 훈련 세트를 사전에 정렬하면 훈련 속도를 높일 수 있지만,
그 이상이라면 매우 느려집니다.
7. moons 데이터셋에 결정 트리를 훈련시키고, 세밀하게 튜닝해보세요.
1) make_moons(n_samples =1000, noise = 0.4)를 사용해 데이터셋을 생성합니다.
from sklearn.datasets import make_moons
X, y = make_moons(n_samples=10000, noise=0.4, random_state=42)
2) 이를 train_test_split()을 사용해 훈련 세트와 테스트 세트로 나눕니다.
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
3) DecisionTreeClassifier의 최적 매개변수를 찾기 위해 교차 검증과 함께 그리드 탐색을 사용합니다. (GridSearchCV)
힌트 = 여러 가지 max_leaf_nodes 값을 시도해보세요.
from sklearn.model_selection import GridSearchCV
params = {'max_leaf_nodes' : list(range(2, 100)), 'min_samples_split' : [2,3,4]}
grid_search_cv = GridSearchCV(DecisionTreeClassifier(random_state=42), params, cv=3, n_jobs=-1 , verbose=1)
grid_search_cv.fit(X_train, y_train)
grid_search_cv.best_estimator_
#기본적으로 GridSearchCV는 전체 훈련 세트로 찾은 최적의 모델을 다시 훈련시킵니다.
#(refit=False로 지정해서 바꿀 수 있습니다). 그래서 별도로 작업할 필요가 없습니다.
#모델의 정확도를 바로 평가할 수 있습니다.
DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None, max_features=None, max_leaf_nodes=17, min_impurity_decrease=0.0, min_impurity_split=None, min_samples_leaf=1, min_samples_split=2, min_weight_fraction_leaf=0.0, presort=False, random_state=42, splitter='best')
4) 찾은 매개변수를 사용해 전체 훈련 세트에 대해 모델을 훈련시키고, 테스트 세트에서 성능을 측정하면
대략 85~87% 정도 정확도가 나올 것입니다.
from sklearn.metrics import accuracy_score
y_pred = grid_search_cv.predict(X_test)
accuracy_score(y_test, y_pred)
8. 랜덤 포레스트를 만들어보세요.
1) 이전 연습문제에 이어서 훈련 세트의 서브셋을 1,000개 생성합니다.
각각은 무작위로 선택된 100개의 샘플을 담고 있습니다. (힌트 : 사이킷런의 ShuffledSplit)
from sklearn.model_selection import ShuffleSplit
n_trees = 1000
n_instances = 100
mini_sets = []
#1,000개의 서브셋으로 나누고, test_size는 8,000-100개.
rs = ShuffleSplit(n_splits = n_trees, test_size = len(X_train) - n_instances, random_state=42)
#mini_train_index = 100 , mini_test_index = 7,900
for mini_train_index, mini_test_index in rs.split(X_train) :
X_mini_train = X_train[mini_train_index]
y_mini_train = y_train[mini_train_index]
mini_sets.append((X_mini_train, y_mini_train))
2) 앞에서 찾은 최적의 매개변수를 사용해 각 서브셋에 결정 트리를 훈련시킵니다.
테스트세트로 이 1,000개의 결정 트리를 평가합니다.
from sklearn.base import clone
forest = [clone(grid_search_cv.best_estimator_) for _ in range(n_trees)]
accuracy_scores = []
for tree, (X_mini_train, y_mini_train) in zip(forest, mini_sets):
tree.fit(X_mini_train, y_mini_train)
y_pred = tree.predict(X_test)
accuracy_scores.append(accuracy_score(y_test, y_pred))
np.mean(accuracy_scores)
0.8054499999999999
3) 각 테스트 샘플에 대해, 1,000개의 결정 트리 예측을 만들고, 다수로 나온 예측만 취합니다.
(사이파이의 mode()함수 사용) 그러면 테스트 세트에 대한 다수결 예측(majority-vote prediction)이 만들어집니다.
Y_pred = np.empty([n_trees, len(X_test)], dtype=np.uint8)
for tree_index, tree in enumerate(forest):
Y_pred[tree_index] = tree.predict(X_test)
from scipy.stats import mode
y_pred_majority_votes, n_votes = mode(Y_pred, axis=0)
4) 테스트 세트에서 이 예측에 대해 평가합니다.
accuracy_score(y_test, y_pred_majority_votes.reshape([-1]))
연습문제가 쉽지는 않은 것 같습니다. 봐도 촤라락 머리에 그려지지 않아서..ㅎㅎ
다음 장은 랜덤포레스트입니다.
블로그
출처
이 글의 상당 부분은 [핸즈온 머신러닝, 한빛미디어/오렐리앙 제롱/박해선] 서적을 참고하였습니다.
나머지는 부수적인 함수나 메서드에 대해 부족한 설명을 적어두었습니다.
학습용으로 포스팅 하는 것이기 때문에 복제보다는 머신러닝에 관심이 있다면 구매해보시길 추천합니다.
도움이 되셨다면 로그인 없이 가능한
아래 하트♥공감 버튼을 꾹 눌러주세요!
'## 오래된 게시글 (미관리) ## > Python (Linux)' 카테고리의 다른 글
46. Python - 7장 연습문제 (0) | 2019.02.21 |
---|---|
45. Python - 앙상블 학습과 랜덤포레스트 (0) | 2019.02.21 |
43. Python - 결정 트리(Decision Tree) (0) | 2019.02.12 |
42. Python - 5장 연습문제 (0) | 2019.02.10 |
41. Python - SVM 이론 2 (0) | 2019.02.10 |