# 4. 학습 스크립트 (Training Script) 가이드

이 문서는 `train/` 폴더 내의 학습 스크립트(`train_xgboost.py`, `train_lightgbm.py`)의 구조와 실행 과정을 설명합니다.

## 1. 실행 구조 및 파라미터

학습 스크립트는 명령행 인자(CLI Arguments)를 통해 제어됩니다.

### 실행 예시
```bash
python3 train/train_xgboost.py \
  --workingDir ./output/xgboost \
  --dataDir ./datas \
  --trainSize 1000 \
  --validSize 200
```

### 파라미터 상세
- `--workingDir`: 학습 결과물(`model.pkl`, `validate.json` 등)이 저장될 경로입니다.
- `--dataDir`: 정답 데이터(`measure.csv`)가 위치한 경로입니다.
- `--trainSize`: 전체 데이터셋 중 학습에 사용할 샘플 수입니다.
- `--validSize`: 학습에 참여하지 않고 모델 평가(검증)에만 사용할 샘플 수입니다.

## 2. 데이터 처리 및 학습 파이프라인

스크립트 내부의 `train_model` 함수는 다음 순서로 동작합니다.

### A. 데이터 로드 및 매칭
1. `workingDir`에서 `features.json`(전처리된 피처)을 읽어옵니다.
2. `dataDir`에서 `measure.csv`(정답 난이도)를 읽어옵니다.
3. `(songno, difficulty)`를 키로 사용하여 두 데이터를 매칭하고 하나의 데이터셋으로 결합합니다.

### B. 데이터셋 분리 (Train/Valid Split)
1. 결합된 데이터셋을 `RANDOM_STATE(42)`를 기반으로 무작위로 섞습니다(Shuffle).
2. 앞에서부터 `TRAIN_SIZE` 만큼을 학습 데이터로, 그 뒤의 `VALID_SIZE` 만큼을 검증 데이터로 엄격히 분리하여 모델의 일반화 성능을 보장합니다.

### C. 정규화 (Scaling)
1. `StandardScaler`를 사용하여 피처의 평균을 0, 분산을 1로 조정합니다.
2. `CONTINUE_TRAINING` 옵션이 켜져 있고 기존 `scaler.pkl`이 있다면 이를 로드하여 일관성을 유지합니다.

### D. 모델 학습 및 지속 학습 (Warm Start)
1. 모델 객체를 생성하거나, 기존 `model.pkl`이 있다면 이를 로드합니다.
2. 기존 모델이 있는 경우 이전 학습 상태를 유지한 채 새로운 데이터로 가중치를 미세 조정(Fine-tuning)합니다.

## 3. 검증 및 결과 시각화

학습 완료 직후, 모델이 학습 중에 보지 못한 검증 데이터셋(`X_valid`)을 사용하여 성능을 평가합니다.

1. **지표 계산**: MAE(Mean Absolute Error)와 오차 범위 ±0.1 이내의 정확도를 산출합니다.
2. **validate.json 저장**: 검증된 각 곡의 실제값, 예측값, 오차를 에러 절댓값 내림차순으로 저장합니다.
3. **validate.png 생성**: 에러의 분포를 한눈에 볼 수 있도록 산점도 그래프를 생성합니다. (X축: 에러 크기 순, Y축: 에러 절댓값)

## 4. 주요 산출물 (Outputs)

학습이 성공하면 `workingDir` 폴더에 다음 파일들이 생성/업데이트됩니다.

| 파일명 | 내용 |
| :--- | :--- |
| `model.pkl` | 학습된 모델 바이너리 |
| `scaler.pkl` | 피처 정규화를 위한 Scaler 객체 |
| `features.txt` | 학습에 사용된 피처 이름 목록 및 순서 |
| `validate.json` | 검증 데이터셋에 대한 상세 예측 결과 (JSON) |
| `validate.png` | 검증 에러 분포 시각화 그래프 (PNG) |

## 5. 주의사항
- `features.json`이 먼저 생성되어 있어야 학습이 가능합니다 (`preprocess.ts` 선행 필요).
- `TRAIN_SIZE + VALID_SIZE`가 전체 가용 데이터 수보다 크면 오류가 발생합니다.
