하이퍼파라미터 위젯으로 실험 제어
ML 실험은 파라미터 탐색입니다. n_estimators를 50으로 줄 때와 200으로 줄 때 정확도가 어떻게 달라지는지, 커널을 rbf로 쓸 때와 linear로 쓸 때 결과가 어떻게 차이 나는지를 직접 바꿔가며 확인합니다. marimo에서는 이 파라미터를 위젯으로 만들어두면, 값을 조작할 때마다 아래에 연결된 셀들이 자동으로 재실행됩니다.
이 챕터에서는 프로젝트 파일 ml_experiment.py를 시작합니다. 데이터를 준비하고, 모델 선택 드롭다운과 하이퍼파라미터 슬라이더로 구성된 위젯 패널을 만듭니다.
데이터 준비
외부 파일 없이 scikit-learn 내장 데이터셋을 사용합니다. 와인 분류 데이터셋(load_wine)을 씁니다. 클래스가 세 개이고 특성이 13개인 중간 난이도 분류 문제입니다.
import marimo as moimport numpy as npimport pandas as pdimport plotly.express as pxfrom sklearn.datasets import load_winefrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScaler# 데이터 로드wine = load_wine()X, y = wine.data, wine.targetfeature_names = wine.feature_names# 훈련·테스트 분할 — random_state 고정으로 재현성 보장X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y)# 스케일링 (SVC가 포함될 경우를 위해 전처리 파이프라인 준비)scaler = StandardScaler()X_train_scaled = scaler.fit_transform(X_train)X_test_scaled = scaler.transform(X_test)
random_state=42를 지정한 것은 중요한 선택입니다. 이 값이 고정되어 있어야 같은 코드를 언제 실행해도 같은 분할이 일어나고, 같은 모델 파라미터에서 같은 결과가 재현됩니다. 재현성에 대해서는 Ch 03에서 더 자세히 다룹니다.
와인 데이터셋 기본 정보를 확인합니다.
dataset_summary = mo.md(f"""### 데이터셋: Wine Classification- 전체 샘플: **{X.shape[0]}개**- 특성 수: **{X.shape[1]}개**- 클래스: **{len(np.unique(y))}개** (와인 품종 0, 1, 2)- 훈련 샘플: **{X_train.shape[0]}개** / 테스트 샘플: **{X_test.shape[0]}개**""")dataset_summary
모델 선택 드롭다운
실험할 모델 세 가지를 드롭다운으로 선택할 수 있게 합니다.
model_selector = mo.ui.dropdown( options=["Random Forest", "Gradient Boosting", "SVC"], value="Random Forest", label="모델 선택",)model_selector
드롭다운 선택값은 model_selector.value로 읽습니다. 이 값에 따라 파라미터 위젯 구성이 달라져야 합니다. RandomForestClassifier와 GradientBoostingClassifier는 비슷한 파라미터를 공유하지만, SVC는 전혀 다른 파라미터를 씁니다.
모델별 하이퍼파라미터 위젯
모델마다 의미 있는 하이퍼파라미터가 다릅니다. 각 추정기가 실제로 받는 인자에 맞게 위젯을 구성합니다.
Random Forest와 Gradient Boosting 공통 파라미터
두 모델 모두 n_estimators(트리 수)와 max_depth(트리 최대 깊이)를 받습니다. Gradient Boosting에는 learning_rate가 추가됩니다.
# 트리 계열 공통 파라미터n_estimators_slider = mo.ui.slider( 10, 300, step=10, value=100, label="n_estimators (트리 수)",)max_depth_slider = mo.ui.slider( 1, 15, step=1, value=5, label="max_depth (트리 최대 깊이)",)# Gradient Boosting 전용 파라미터learning_rate_slider = mo.ui.slider( 0.01, 0.5, step=0.01, value=0.1, label="learning_rate (학습률)",)# SVC 전용 파라미터C_slider = mo.ui.slider( 0.1, 10.0, step=0.1, value=1.0, label="C (정규화 강도)",)kernel_selector = mo.ui.dropdown( options=["rbf", "linear", "poly"], value="rbf", label="kernel",)
모델 선택에 따른 위젯 패널 동적 구성
선택한 모델에 맞는 위젯만 화면에 보여줍니다.
def build_param_panel(selected_model: str): if selected_model == "Random Forest": return mo.vstack([ n_estimators_slider, max_depth_slider, ]) elif selected_model == "Gradient Boosting": return mo.vstack([ n_estimators_slider, max_depth_slider, learning_rate_slider, ]) else: return mo.vstack([ C_slider, kernel_selector, ])param_panel = build_param_panel(model_selector.value)param_panel
model_selector.value가 바뀌면 이 셀이 재실행되어 param_panel이 새로 구성됩니다. Random Forest를 선택하면 n_estimators와 max_depth만 보이고, SVC를 선택하면 C와 kernel이 나타납니다.
전체 위젯 패널 배치
모델 선택기와 파라미터 패널을 하나의 컨트롤 패널로 묶습니다.
control_panel = mo.vstack([ mo.md("### 실험 파라미터"), model_selector, mo.md("---"), param_panel,])control_panel
셀 구성 전체 그림
Ch 02~04에서 셀을 계속 추가합니다. 전체 구조를 미리 확인합니다.
셀 1: 라이브러리 임포트 + 데이터 로드 + 분할 + 스케일링셀 2: dataset_summary (데이터셋 정보 출력)셀 3: model_selector (드롭다운)셀 4: 파라미터 위젯 정의 (슬라이더들, kernel 드롭다운)셀 5: param_panel (선택 모델에 따라 동적 구성)셀 6: control_panel (모델 선택기 + 파라미터 패널 묶음)셀 7: build_estimator 함수 정의 (Ch 02에서 추가)셀 8: train_and_evaluate 함수 (@mo.cache, Ch 02에서 추가)셀 9: 학습·평가 실행 (trained_model, test_accuracy, Ch 02에서 추가)셀 10: 현재 실험 결과 출력 (Ch 02에서 추가)셀 11: get_history, set_history (mo.state, Ch 03에서 추가)셀 12: log_button_with_action (Ch 03에서 추가)셀 13: history_display — 기록 테이블 (Ch 03에서 추가)셀 14: comparison_chart — 비교 차트 (Ch 03에서 추가)셀 15: results_panel — 레이아웃 (Ch 03에서 추가)셀 16: save_button (Ch 04에서 추가)셀 17: mo.stop + joblib.dump (Ch 04에서 추가)
Ch 01에서는 셀 1~6까지 완성했습니다.
정리
load_wine()으로 데이터를 준비하고train_test_split에random_state=42를 고정해 재현 가능한 분할을 만들었습니다.mo.ui.dropdown으로 모델을 선택하고, 모델별로 다른 파라미터 위젯(n_estimators,max_depth,learning_rate,C,kernel)을 구성했습니다.- 추정기마다 받는 인자가 다릅니다.
RandomForestClassifier에는learning_rate를 넘기지 않고,SVC에는n_estimators를 넘기지 않습니다. model_selector.value를 참조하는 셀은 드롭다운 선택이 바뀔 때마다 자동으로 재실행됩니다. 파라미터 패널이 선택된 모델에 맞게 자동으로 전환됩니다.