앞선 실습에서는 SageMaker를 이용해 기본 설정으로 모델을 학습하고 리포트를 분석해 보았다. 하지만 모델 성능은 하이퍼파라미터에 크게 좌우되기 때문에, 이를 효과적으로 조정하는 과정이 필요하다. 작은 데이터셋이나 간단한 실험은 로컬 코드에서 직접 빠르게 시도할 수 있지만, 데이터 규모와 시도 횟수가 커지고 결과를 다시 확인·재현해야 하는 단계부터는 한계가 생긴다.
이때 SageMaker 하이퍼파라미터 튜닝 기능을 활용하면 여러 대의 인스턴스에서 동시에 실험을 실행하고, 모든 결과를 자동으로 기록하며, 성능이 좋지 않은 시도는 일찍 멈춰 비용을 절감한다. 이를 통해 최적의 설정을 더 안정적이고 효율적으로 찾을 수 있다. 이번 글에서는 이러한 SageMaker의 튜닝 기능을 사용해 모델 성능을 개선하는 방법을 실습을 통해 알아보자!

전체적인 과정의 아키텍처는 위와 같다.
1) 라이브러리 임포트
import boto3, numpy as np, pandas as pd, sagemaker
from sagemaker import image_uris
from sagemaker.inputs import TrainingInput
from sagemaker.tuner import IntegerParameter, ContinuousParameter, HyperparameterTuner
from sagemaker.xgboost.estimator import XGBoost
from bokeh.plotting import figure, show
from bokeh.models import HoverTool
from bokeh.layouts import Column
from sagemaker.estimator import Estimator- boto3, sagemaker: AWS 리소스 제어(SageMaker, S3 등)에 사용한다.
- image_uris: 알고리즘/프레임워크 컨테이너 이미지 URI를 지역(region)에 맞게 가져온다.
- TrainingInput: S3의 데이터 경로를 SageMaker 채널(train/validation) 로 넘길 때 쓴다.
- IntegerParameter, ContinuousParameter, HyperparameterTuner: 튜닝 범위/전략과 Tuning Job을 정의한다.
- XGBoost/Estimator: 내장 XGBoost 또는 임의 컨테이너로 학습 잡 틀을 만든다.
- bokeh: 튜닝 결과를 시각화한다.
2) 세션/역할 및 클라이언트 설정
sagemaker_session = sagemaker.Session()
role = sagemaker.get_execution_role()
sm = boto3.client("sagemaker")
s3 = boto3.resource("s3")
region = boto3.Session().region_name
SageMaker 세션/실행 역할/IAM 권한/리전 정보를 잡는다. 이후 모든 학습/튜닝/결과 조회 호출은 이 설정을 바탕으로 동작한다.
3) S3 버킷 & 데이터 경로
bucket = [b.name for b in s3.buckets.all() if "labdatabucket" in b.name][0]
prefix = "scripts/data"
output_path = f"s3://{bucket}/{prefix}/output"
train_input = TrainingInput("s3://.../train.csv", content_type="text/csv")
val_input = TrainingInput("s3://.../validation.csv", content_type="text/csv")
사용할 데이터가 있는 버킷을 고르고, 학습 산출물이 저장될 output_path를 지정한다. 이후 TrainingInput으로 S3 파일을 train/validation 채널에 매핑한다.
4) 알고리즘 컨테이너 선택
container = image_uris.retrieve("xgboost", region=region, version="1.2-1")
리전에 맞는 XGBoost 내장 이미지 URI를 가져오면 SageMaker가 이 이미지를 EC2 인스턴스에 풀어 학습을 수행한다.
5) Estimator 생성 (학습 잡의 기본 틀)
xgb = Estimator(
image_uri=container,
role=role,
instance_count=1,
instance_type="ml.m5.xlarge",
output_path=output_path,
sagemaker_session=sagemaker_session
)
어떤 이미지/인스턴스/출력 경로로 학습을 진행할지 정의한다. 이후 튜닝 과정에서 튜너가 이 Estimator 틀을 복제해 여러 조합으로 학습 잡을 실행한다.
6) 하이퍼파라미터 탐색 범위 정의
hyper_ranges = {
"alpha": ContinuousParameter(0, 2),
"eta": ContinuousParameter(0, 1),
"max_depth": IntegerParameter(1, 10),
"min_child_weight": ContinuousParameter(1, 10),
"num_round": IntegerParameter(100, 1000),
}
모델의 성능은 하이퍼파라미터 설정에 크게 좌우되므로, 튜닝에서는 어떤 파라미터를 조정할지와 그 값의 범위를 먼저 정해야 한다. SageMaker에서는 ContinuousParameter와 IntegerParameter를 사용해 연속 값과 정수 값의 범위를 지정할 수 있다. 이렇게 정의된 범위 내에서 SageMaker는 다양한 조합을 실험해 지정된 목적 지표(이번에는 validation:auc)를 기준으로 최적의 하이퍼파라미터를 찾아낸다. 결국 이 단계는 튜닝의 탐색 공간(search space)을 설정하는 과정이며, 탐색 범위를 어떻게 두느냐가 최적화 효율과 결과에 직접적인 영향을 미친다.
| 하이퍼파라미터 | 의미 |
| eta (learning rate) | 학습률 : 각 단계에서 가중치를 얼마나 업데이트할지 결정 |
| max_depth | 개별 트리의 최대 깊이 |
| min_child_weight | 리프 노드에 필요한 최소 가중치 합 |
| alpha | L1 정규화 항 : 모델 파라미터의 가중치를 제약 (값이 클수록 가중치가 더 강하게 제한되어 단순한 모델을 만듦) |
| num_round | 부스팅 반복 횟수 (트리 개수) |
이외에도 모델별로 다양한 하이퍼파라미터가 있고 공식문서를 통해 확인할 수 있다.
7) 튜너(Tuner) 구성
tuner = HyperparameterTuner(
estimator=xgb,
objective_metric_name="validation:auc",
hyperparameter_ranges=hyper_ranges,
objective_type="Maximize",
max_jobs=12,
max_parallel_jobs=4,
early_stopping_type="Auto"
)튜너는 지정된 Estimator를 기반으로 여러 하이퍼파라미터 조합을 실험하고, 성능 지표를 기준으로 최적의 설정을 찾는다.
이번에는 검증 데이터의 AUC를 최대화하는 것을 목표로 했다.
estimator에는 학습할 모델을 지정하고, objective_metric_name에는 최적화할 지표를 설정한다. hyperparameter_ranges에는 탐색할 범위를 전달하며, objective_type은 최대화 또는 최소화 여부를 정한다. max_jobs는 총 실행할 학습 횟수, max_parallel_jobs는 동시에 실행할 학습 작업 수를 의미한다. 마지막으로 early_stopping_type을 Auto로 설정하면 성능이 낮은 실험은 자동으로 중단한다.
8) 튜닝 실행
job_name = "lab-3-job"
tuner.fit({"train": train_input, "validation": val_input}, job_name=job_name, wait=True)
fit()에 채널 매핑을 주면 튜닝 잡이 시작된다. SageMaker가 인프라 생성 > 여러 조합 학습 > 로깅/메트릭 수집 > 종료를 자동으로 처리한다. wait=True라 실행이 끝날 때까지 호출을 대기시키는 옵션이다.
9) 결과 집계
analytics = sagemaker.HyperparameterTuningJobAnalytics(job_name)
df = analytics.dataframe()
df = df[df["FinalObjectiveValue"] > -float("inf")].sort_values("TrainingStartTime")
튜닝 잡의 각 시도(job) 에 대한 하이퍼파라미터, 지표, 시간 등을 DataFrame으로 조회한다. 유효 값만 필터링하고(∞ 제거) 시간 순으로 정렬한다. 최고 성능 조합은 FinalObjectiveValue가 가장 큰 행(이번엔 AUC)이다.
10) 시각화(Bokeh)
for hp in hyper_ranges.keys():
sub_df = df[[hp, "FinalObjectiveValue"]].dropna()
...
slope, intercept = np.polyfit(x, y, 1)
...
fig.circle(...); fig.line(...); fig.add_tools(HoverTool(...))
show(Column(*plots))





이 그래프는 하이퍼파라미터 값과 모델 검증 성능(AUC)의 관계를 나타낸 스캐터 플롯이다. 가로축에는 특정 하이퍼파라미터 값( eta, num_round..)이, 세로축에는 검증 성능(validation:auc)이 표시된다.
파란 점 하나는 개별 튜닝 시도를 의미하며, 초록색 직선은 단순 선형 추세선이다. 점이 위쪽에 위치할수록 성능이 좋은 것이고, 추세선이 위로 기울면 값이 커질수록 성능이 개선되는 경향, 평평하다면 현재 범위 내에서는 영향이 크지 않음을 뜻한다.
다만 이 그래프는 각 파라미터를 단일 축으로만 관찰하는 결과이므로, 실제 최적화는 다른 파라미터와의 상호작용까지 함께 고려해야 한다.
이번 학습의 결과를 보면, num_round는 반복 횟수를 크게 가져갈수록 검증 AUC가 떨어지는 경향을 보여, 과도한 반복은 오히려 비효율적이거나 과적합을 일으킬 수 있을 것으로 예측해볼 수 있다.
min_child_weight는 값이 커질수록 성능이 좋아지는 패턴이 나타나, 작은 리프의 과도한 분할을 억제하는 효과가 있었던 것으로 보인다.
max_depth는 1~10 범위에서 성능 변화가 거의 없고, 학습률 eta는 뚜렷한 상승 추세를 보여, 이 데이터에서는 비교적 큰 값을 사용하는 것이 유리할 것으로 보인다.
반대로 L1 규제 항인 alpha는 약한 하락 추세를 보여 성능 향상에는 큰 기여를 하지 못한것으로 보인다.
11) Best Hyperparameters & Score
best_job_desc = sm.describe_hyper_parameter_tuning_job(
HyperParameterTuningJobName=job_name
)
if "BestTrainingJob" in best_job_desc and best_job_desc["BestTrainingJob"]:
best_job = best_job_desc["BestTrainingJob"]
print("Best Training Job:", best_job["TrainingJobName"])
best_params = best_job["TunedHyperParameters"]
best_score = best_job["FinalHyperParameterTuningJobObjectiveMetric"]["Value"]
print("\nBest Hyperparameters:")
for k, v in best_params.items():
print(f" {k}: {v}")
print(f"\nBest Score (validation:auc): {best_score:.4f}")
else:
print("아직 Best Training Job 정보가 없습니다.")
Best Hyperparameters:
alpha: 0.12016791720660325
eta: 0.08475458118726253
max_depth: 4
min_child_weight: 6.973028196950103
num_round: 321
Best Score (validation:auc): 0.9200
튜닝이 완료되면 describe_hyper_parameter_tuning_job()을 통해 최적의 학습 잡과 그 설정을 확인할 수 있다. BestTrainingJob 항목에는 최고 성능을 낸 학습 작업 이름, 사용된 하이퍼파라미터 값, 그리고 최종 성능 지표가 담겨 있다.
12) 하이퍼파라미터–성능 상관 히트맵
hp_cols = list(hyper_ranges.keys())
corr_df = df[hp_cols + ["FinalObjectiveValue"]].dropna().astype(float)
plt.figure(figsize=(10, 8))
sns.heatmap(corr_df.corr(), annot=True, cmap="coolwarm", fmt=".2f")
plt.title("Hyperparameters & Objective Correlation", fontsize=14)
plt.show()
13) Pairplot
sns.pairplot(corr_df, vars=hp_cols, diag_kind="kde")
plt.suptitle("Pairwise Relationships of Hyperparameters", y=1.02, fontsize=14)
plt.show()

상관 히트맵은 하이퍼파라미터 값과 최종 성능(FinalObjectiveValue), 그리고 하이퍼파라미터들끼리의 선형 상관을 수치와 색으로 보여준다. 값이 +1이면 두 값이 함께 증가하는 양의 상관, −1이면 반대로 움직이는 음의 상관, 0이면 뚜렷한 선형 관계가 없음을 의미한다.
이번 결과에서는 성능과의 관계에서 eta(+0.62)가 가장 강한 양의 상관을 보여 학습률을 크게 두는 편이 유리했다. min_child_weight(+0.45)도 양의 상관으로 나타나 리프 분할을 억제할수록 성능이 개선되는 경향을 보였다.
반대로 num_round(−0.37)는 음의 상관을 보여 라운드를 과도하게 늘리면 성능이 떨어질 수 있었다. alpha(−0.08)와 max_depth(+0.02)는 거의 영향이 없었다.
eta–min_child_weight(+0.54)는 둘이 함께 커지는 경향을, min_child_weight–num_round(−0.53)와 eta–num_round(−0.34)는 값이 커질수록 라운드를 줄이는 경향을 보여준다. 즉, 학습률을 높이면 반복 횟수는 줄이고, 리프 최소 가중치를 크게 둘수록 반복 횟수도 낮게 잡는 조합이 성능에 잘 맞았다.
14) Tuning Job 요약 정보
tuning_job_result = sm.describe_hyper_parameter_tuning_job(
HyperParameterTuningJobName=job_name
)
status = tuning_job_result["HyperParameterTuningJobStatus"]
print(f"Tuning Job Status: {status}")
job_count = tuning_job_result["TrainingJobStatusCounters"]["Completed"]
print(f"Completed Training Jobs: {job_count}")
objective = tuning_job_result["HyperParameterTuningJobConfig"]["HyperParameterTuningJobObjective"]
objective_name = objective["MetricName"]
print(f"Objective Metric: {objective_name} ({objective['Type']})")Tuning Job Status: Completed
Completed Training Jobs: 6
Objective Metric: validation:auc (Maximize)
튜닝 잡이 정상적으로 완료되었고 총 6개의 학습 잡이 끝났으며 목표 지표는 검증 AUC 최대화했다는 내용이다.
15) Best Training Job
if tuning_job_result.get("BestTrainingJob", None):
best_job = tuning_job_result["BestTrainingJob"]
print("\nBest Training Job:")
print(" Name:", best_job["TrainingJobName"])
print(" Final Objective Value:",
best_job["FinalHyperParameterTuningJobObjectiveMetric"]["Value"])
print(" Tuned Hyperparameters:")
for k, v in best_job["TunedHyperParameters"].items():
print(f" {k}: {v}")
else:
print("아직 Best Training Job 결과가 없습니다.")Best Training Job:
Name: lab-3-job-001-26316c58
Final Objective Value: 0.9199600219726562
Tuned Hyperparameters:
alpha: 0.12016791720660325
eta: 0.08475458118726253
max_depth: 4
min_child_weight: 6.973028196950103
num_round: 321BestTrainingJob에서 뽑힌 결과도 확인할 수 있다.
16)Objective Metric
if len(df) > 0:
df_valid = df[df["FinalObjectiveValue"] > -float("inf")]
if len(df_valid) > 0:
print(f"\n유효한 Objective Metric을 보고한 Job 수: {len(df_valid)}")
print({
"lowest": min(df_valid["FinalObjectiveValue"]),
"highest": max(df_valid["FinalObjectiveValue"])
})
pd.set_option("display.max_colwidth", None)
display(df_valid.head(10)) # 상위 10개만 표시
else:
print("아직 유효한 Objective Metric을 보고한 Job이 없습니다.")
else:
print("튜닝 결과 데이터프레임이 비어있습니다.")
| alpha | eta | max_depth | min_child_weight | num_round | TrainingJobName | Status | FinalObjectiveValue |
| 0.120 | 0.084 | 4 | 6.9730 | 321 | lab-3-job-001-.. | Stopped | 0.91996 |
| 0.098 | 0.619 | 3 | 1.4092 | 761 | lab-3-job-004-.. | Completed | 0.91134 |
| 0.665 | 0.277 | 4 | 7.2713 | 194 | lab-3-job-008-.. | Completed | 0.91692 |
| ... | |||||||
모든 시도들의 조합과 성능을 학인할 수 있으며 이번 학습에서는 AUC 0.91996을 달성한 조합이 최적으로 확인됐다.
참고 자료:
https://docs.aws.amazon.com/ko_kr/sagemaker/latest/dg/automatic-model-tuning.html
SageMaker AI를 사용한 자동 모델 튜닝 - Amazon SageMaker AI
이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.
docs.aws.amazon.com
https://docs.aws.amazon.com/sagemaker/latest/dg/automatic-model-tuning.html
Automatic model tuning with SageMaker AI - Amazon SageMaker AI
Thanks for letting us know this page needs work. We're sorry we let you down. If you've got a moment, please tell us how we can make the documentation better.
docs.aws.amazon.com
https://docs.aws.amazon.com/sagemaker/latest/dg/xgboost_hyperparameters.html
XGBoost hyperparameters - Amazon SageMaker AI
XGBoost hyperparameters The following table contains the subset of hyperparameters that are required or most commonly used for the Amazon SageMaker AI XGBoost algorithm. These are parameters that are set by users to facilitate the estimation of model param
docs.aws.amazon.com
'AWS' 카테고리의 다른 글
| [AWS] AWS Certified Machine Learning – Specialty 취득 후기 (0) | 2025.10.21 |
|---|---|
| [AWS] SageMaker Studio사용해 모델 배포하기 (0) | 2025.08.25 |
| [AWS] Amazon SageMaker를 사용한 모델 학습 및 리포트 해석하기 (0) | 2025.08.24 |
| [AWS] SageMaker Data Wrangler를 사용해 데이터 처리하기 (0) | 2025.08.20 |
| [AWS] ML 수명 주기(ML Lifecycle)와 MLflow (0) | 2025.08.01 |