[Python] Random Forest 최적화 방법
앞서 알아봤던 Random Forest 알고리즘의 최적화하는 방법에 대해 알아보자.
모델에 사용되는 하이퍼파라미터 별 성능을 시각화하여 최적화가 기대되는 값을 찾아내야 한다.
1. 모델 최적화 함수: 학습할 트리 모델 개수 선정
2. 모델 최적화 함수: 최대 깊이 선정
3. 모델 최적화 함수: 분리 노드의 최소 자료 수 선정
4. 모델 최적화 함수: 잎사귀 노드의 최소 자료 수 선정
위와 같이 4가지 하이퍼파라미터에 대해 순차적으로 시행하며 최적화한다.
사용할 데이터셋은 boston 집값예측 예제이며, RandomForestRegressor 로 평가하였다.
# 1. 트리 모델 개수 선정
def optimi_estimator(algorithm, algorithm_name, x_train, y_train, x_test, y_test, n_estimator_min, n_estimator_max):
train_score = []; test_score =[]
para_n_tree = [n_tree*5 for n_tree in range(n_estimator_min, n_estimator_max)]
for v_n_estimators in para_n_tree:
model = algorithm(n_estimators = v_n_estimators, random_state=1234)
model.fit(x_train, y_train)
train_score.append(model.score(x_train, y_train))
test_score.append(model.score(x_test, y_test))
# 트리 개수에 따른 모델 성능 저장
df_score_n = pd.DataFrame({'n_estimators': para_n_tree, 'TrainScore': train_score, 'TestScore': test_score})
# 트리 개수에 따른 모델 성능 추이 시각화 함수 호출
optimi_visualization(algorithm_name, para_n_tree, train_score, test_score, "The number of estimator", "n_estimator")
print(round(df_score_n, 4))
n_estimator_min = 1
n_estimator_max = 50
optimi_estimator(algorithm, algorithm_name,
x_train, y_train, x_test, y_test,
n_estimator_min, n_estimator_max)

트리 개수는 많을수록 과적합 방지에 유리하다. 학습 데이터 기반 모델 정확도와 테스트 데이터 기반 모델 정확도의 차이가 적은 값으로 선정하는 것이 좋으므로 트리 개수가 더 많아져도 성능에 차이가 없다는 점을 고려하여 100으로 선정한다.
# 2. 최대 깊이 선정
def optimi_maxdepth (algorithm, algorithm_name, x_train, y_train, x_test, y_test, depth_min, depth_max, n_estimator):
train_score = []; test_score = []
para_depth = [depth for depth in range(depth_min, depth_max)]
for v_max_depth in para_depth:
model = algorithm(max_depth = v_max_depth,
n_estimators = n_estimator,
random_state=1234)
model.fit(x_train, y_train)
train_score.append(model.score(x_train, y_train))
test_score.append(model.score(x_test, y_test))
# 최대 깊이에 따른 모델 성능 저장
df_score_n = pd.DataFrame({'depth': para_depth, 'TrainScore': train_score, 'TestScore': test_score})
# 최대 깊이에 따른 모델 성능 추이 시각화 함수 호출
optimi_visualization(algorithm_name, para_depth, train_score, test_score, "The number of depth", "n_depth")
print(round(df_score_n, 4))
depth_min = 1
depth_max = 21
optimi_maxdepth(algorithm, algorithm_name,
x_train, y_train, x_test, y_test,
depth_min, depth_max, n_estimator)

최대 깊이는 적을수록 과적합 방지에 유리하고, 학습데이터와 test 데이터의 결과가 적은 값으로 선정한다.
나는 3로 선정하였다.
# 3. 분리 노드의 최소 자료 수 선정
def optimi_minsplit (algorithm, algorithm_name, x_train, y_train, x_test, y_test, n_split_min, n_split_max, n_estimator, n_depth):
train_score = []; test_score = []
para_split = [n_split*2 for n_split in range(n_split_min, n_split_max)]
for v_min_samples_split in para_split:
model = algorithm(min_samples_split = v_min_samples_split,
n_estimators = n_estimator,
max_depth = n_depth,
random_state = 1234)
model.fit(x_train, y_train)
train_score.append(model.score(x_train, y_train))
test_score.append(model.score(x_test, y_test))
# 분리 노드의 최소 자료 수에 따른 모델 성능 저장
df_score_n = pd.DataFrame({'min_samples_split': para_split, 'TrainScore': train_score, 'TestScore': test_score})
# 분리 노드의 최소 자료 수에 따른 모델 성능 추이 시각화 함수 호출
optimi_visualization(algorithm_name, para_split, train_score, test_score, "The minimum number of samples required to split an internal node", "min_samples_split")
print(round(df_score_n, 4))
n_split_min = 1
n_split_max = 101
optimi_minsplit (algorithm, algorithm_name,
x_train, y_train, x_test, y_test,
n_split_min, n_split_max, n_estimator, n_depth)

split 노드의 최소 자료 수는 많을수록 과적합 방지에 유리하다. 노드가 많으면서 학습데이터와 test 데이터 간의 결과 차이가 적은 값으로 선정한다.
# 4. 잎사귀 노드의 최소 자료 수 선정
def optimi_minleaf(algorithm, algorithm_name, x_train, y_train, x_test, y_test, n_leaf_min, n_leaf_max, n_estimator, n_depth, n_split):
train_score = []; test_score = []
para_leaf = [n_leaf*2 for n_leaf in range(n_leaf_min, n_leaf_max)]
for v_min_samples_leaf in para_leaf:
model = algorithm(min_samples_leaf = v_min_samples_leaf,
n_estimators = n_estimator,
max_depth = n_depth,
min_samples_split = n_split,
random_state=1234)
model.fit(x_train, y_train)
train_score.append(model.score(x_train, y_train))
test_score.append(model.score(x_test, y_test))
n_leaf_min = 1
n_leaf_max = 51
optimi_minleaf(algorithm, algorithm_name,
x_train, y_train, x_test, y_test,
n_leaf_min, n_leaf_max, n_estimator, n_depth, n_split)

잎사귀 노드의 최소 자료 수는 많을수록 과적합 방지에 유리하다. 잎사귀 노드가 많으면서 학습데이터와 test 데이터 간의 결과가 적은 값으로 선정한다.
- 결과적으로 regression 의 경우에는min_samples_split 와 min_samples_leaf 는 높은값을 취할수록 Classifier 와 같은 거동을 보이고, 정확도가 떨어지는 것을 알 수 있었다.
따라서 기본 default 값을 쓴 결과보다 부정확한 모델이 형성되었다.
위와 같은 방법이 있는 것만 참고하고 비교하면서 사용토록 하자.
참고자료 : [Python] Random Forest 알고리즘 정의, 장단점, 최적화 방법 (tistory.com)
'Python' 카테고리의 다른 글
[Python] GridSearchCV 를 이용한 하이퍼파라미터 최적값 찾기 (0) | 2023.03.19 |
---|---|
[Python] 데이터 전처리 - 스케일링 (0) | 2023.03.18 |
머신 러닝 알고리즘 : 선형 데이터 (Regression) - 뉴럴네트워크(MLP) (0) | 2023.03.09 |
머신 러닝 알고리즘 : (Regression) - 랜덤포레스트 (0) | 2023.03.09 |
머신 러닝 알고리즘 : 선형 데이터 (Regression) (0) | 2023.03.06 |