이제, 모델 정확도를 측정하는 방법을 알았으므로
어떤 모델이 가장 좋은 예측치를 제공하는지 다른 모델들로 실험해볼 수 있다.
scikit-learn의 documentation에서 Decision Tree에 대한 많은 옵션이 있음을 확인할 수 있다.
가장 중요한 옵션은 트리의 depth(깊이)를 결정하는 것이다.
트리의 깊이는, 예측에 도달하기 전에 트리가 분할되는 횟수를 측정한 값이다. (참고 링크)
아래는 비교적 얕은(낮은 depth를 가지는) 트리의 예시이다.
실전에서는 트리가 top level과 leaf 사이에 10개의 분할을 갖는건 종종 일어나는 일이다.
트리가 깊어질수록 데이터셋은 더 적은 수의 주택이 포함된 leaf로 분리된다.
트리가 오직 한 개의 분할만 갖는다면, 이 트리는 원본 데이터를 2개의 그룹으로 분할한다.
만약 각 그룹이 또 분할되면, 주택을 총 4개의 그룹으로 분할하게 된다.
이 그룹들 각각을 또다시 분할하면, 총 8개의 그룹이 생긴다.
각 층마다 더 많은 분할을 시켜 그룹 수를 계속 두 배로 늘리면 총 210개의 그룹이 생긴다.
10층쯤 도달하면 1024개의 잎(leaf)이 되는데, 즉 1024개 그룹의 집값이라고 볼 수 있다.
잎이 많아질수록 각 잎에 포함되는 주택의 수는 줄어든다.
매우 적은 수의 주택이 있는 잎은, 그 주택들에 대해서는 예측도가 매우 높아지지만, 새로운 데이터에 대해서는 정확도가 매우 떨어지는 예측을 할 것이다.
이는 모델이 훈련 데이터에만 거의 완벽하게 맞춰지고,
새로운 데이터에 대해서는 제대로 작동하지 않게되는 Overfitting(과적합)이라는 현상이다.
반대로, 나무를 매우 얕게 만들면 주택을 아주 뚜렷한 그룹으로 나누지 않는다.
예를 들어, 극단적으로 tree가 주택을 2~4개로 나누더라도, 각 그룹에는 여전히 다양한 종류의 주택이 있다.
이것으로 학습하여 예측된 결과는 학습 데이터 내에서 예측을 하더라도 여전히 대부분의 정답에서 멀리 떨어져 있을 것이다.
마찬가지로 validation에서도 성능은 좋지 않을 것이다.
모델이 데이터의 중요한 차이와 패턴을 잡아내지 못해 훈련데이터에서마저 성능이 떨이지는 것을 Underfitting(과소적합)이라고 한다.
우리는 검증 데이터로 추정한 새로운 데이터에서의 정확도가 중요하므로, Overfitting과 Underfitting 사이의 최적 지점을 찾는 것이 관건이다.
(아래 그림에서 빨간색 validation 곡선의 낮은 지점)
트리의 깊이를 조정하기 위한 몇 가지 방법이 있고, 대부분은 트리를 통과하는 일부 경로가 다른 경로보다 더 깊도록 만든다.
그러나 max_leaf_nodes
인수는 overfitting과 underfitting을 제어하는 매우 합리적인 방법을 제공한다.
모델이 더 많은 잎을 만들수록 위 그래프의 Underfitting 영역에서 Overfitting영역으로 더 많이 이동하게 된다.
utility 함수
를 사용해서max_leaf_nodes
에 대한 다양한 값의 MAE 점수를 비교할 수 있다.
from sklearn.metrics import mean_absolute_error
from sklearn.tree import DecisionTreeRegressor
def get_mae(max_leaf_nodes, train_X, val_X, train_y, val_y):
model = DecisionTreeRegressor(max_leaf_nodes=max_leaf_nodes, random_state=0)
model.fit(train_X, train_y)
preds_val = model.predict(val_X)
mae = mean_absolute_error(val_y, preds_val)
return(mae)
train_X
, val_X
, train_y
, val_y
로 나눠두었음 import pandas as pd
# Load data
melbourne_file_path = '../input/melbourne-housing-snapshot/melb_data.csv'
melbourne_data = pd.read_csv(melbourne_file_path)
# 누락된 값에 대한 행 제거
filtered_melbourne_data = melbourne_data.dropna(axis=0)
# target, features 정하기
y = filtered_melbourne_data.Price
melbourne_features = ['Rooms', 'Bathroom', 'Landsize', 'BuildingArea',
'YearBuilt', 'Lattitude', 'Longtitude']
X = filtered_melbourne_data[melbourne_features]
from sklearn.model_selection import train_test_split
# training/validation으로 각각 분리하기
train_X, val_X, train_y, val_y = train_test_split(X, y,random_state = 0)
for-loop를 사용하여 max_leaf_nodes
에 대해 서로 다른 값으로 구축된 모델의 정확도를 비교할 수 있다.
for max_leaf_nodes in [5, 50, 500, 5000]:
my_mae = get_mae(max_leaf_nodes, train_X, val_X, train_y, val_y)
print("Max leaf nodes: %d \t\t Mean Absolute Error: %d" %(max_leaf_nodes, my_mae))
[결과]
Max leaf nodes: 5 Mean Absolute Error: 347380
Max leaf nodes: 50 Mean Absolute Error: 258171
Max leaf nodes: 500 Mean Absolute Error: 243495
Max leaf nodes: 5000 Mean Absolute Error: 254983
이 max_leaf_nodes 값 중에는 500이 가장 최적의 leaf 개수임을 알 수 있다.
모델은 다음 두 문제를 가질 수 있다.
overfitting :
미래에 반복되지 않을 가짜 패턴을 잡아냄 정확도 하락
underfitting :
관련된 패턴을 알아내지 못함 정확도 하락
후보가 된 모델의 정확도를 측정하기 위해,
모델의 학습에 사용되지 않는 validation data를 사용한다.
이를 통해 우린느 많은 모델을 후보로 두어 실험하고,
가장 좋은 성능을 갖는 모델을 뽑는다.