SOL CoD 시뮬레이션 정확도 산정 가이드
본 문서는 SOL 예측 시뮬레이션(Chain of Debate 기반)의 정확도 산정 방식, 저장 구조, CQRS 흐름, API 사용법을 정리합니다.
개요
- 목표: 특정 치료 일차(dayIndex) D의 SOL을 예측하고, 이후 실제 SOL과 비교하여 정확도를 관리합니다.
- 데이터 사용 규칙: D일차 예측은 D−1일까지의 데이터(수면 로그/설문/학습/CRM 등)만 사용합니다.
- 기본 범위: 기본 시뮬레이션은 8일차부터 시작(1–7일의 기록으로 8일차 예측)하며, 필요 시
metadata.simulationRange로 조정합니다.
데이터 저장 구조(Prisma, private 스키마)
-
simulation_sessions- 세션 메타/진행 상태/집계 메트릭(정확도/합의/성능) 저장
- 주요 필드:
status,totalPredictions,completedPredictions,accuracyMae,accuracyRmse,accuracyMape,accuracyWithin15min,averageDebateRounds,averageConsensusScore,totalExecutionTime등
-
simulation_predictions- 일차별 예측 결과 저장(예측 점수 및 신뢰도/합의/토론 지표 포함)
- 주요 필드:
dayIndex,predictedSOL,actualSOL?,confidenceScore,absoluteError?,percentageError?,squaredError?,isWithinThreshold?,participantAgents[],consensusScore,debateRounds,executionTimeMs,dataQualityScore,agentPredictions{},analysisEvidence{}
-
simulation_comparisons- 예측 vs 실제 비교 행 단위 저장(예측별 1행, upsert)
- 주요 필드:
simulationPredictionId(unique),comparisonDate,predictedSOL,actualSOL,absoluteError,relativeError(%),isWithinThreshold,thresholdMinutes
-
simulation_debate_session/simulation_debate_round/simulation_expert_opinion- CoD 토론 이력(세션/라운드/전문가 의견) 저장
예측 단위 정확도 산정(단일 dayIndex)
SimulationPrediction 도메인 엔티티가 실제값을 설정하면 정확도 지표를 계산합니다.
-
실제값 설정:
prediction.setActualSOL(actualSOL) -
계산 지표
- 절대오차(Absolute Error):
|predictedSOL − actualSOL|(분) - 백분율오차(Percentage Error):
absoluteError / actualSOL × 100(actual=0 특례 처리) - 제곱오차(Squared Error):
(predictedSOL − actualSOL)^2 - 임계 내 정확도:
absoluteError ≤ 15분 →isWithinThreshold = true
- 절대오차(Absolute Error):
-
예측 품질/등급
getPredictionQuality()가 종합 점수와 등급을 산출합니다.- 구성(가중치): 정확도 40% + 신뢰도(confidence) 30% + 데이터품질 20% + 토론품질 10%
- 결과:
qualityScore(0–100),accuracyGrade(A/B/C/D/F)
참고: 임계 15분은 기본값이며, 비교 커맨드 옵션으로 다른 임계 구성을 적용할 수 있습니다.
세션 단위 정확도 산정(집계)
예측들이 생성된 후, CompareSimulationResultsCommand로 실제값을 주입해 비교/집계를 수행합니다.
- 입력:
comparisonData[] = [{ simulationDate: 'YYYY-MM-DD', actualSOL: number, ... }] - 처리: 각 예측에 실제값을 반영하고, 오차 지표를 계산하여
simulation_comparisons에 upsert 저장 - 집계 지표(세션 업데이트)
- MAE(Mean Absolute Error)
- RMSE(Root Mean Square Error)
- MAPE(Mean Absolute Percentage Error)
- ±15분 이내 비율(
withinThresholdRate) - 등급 분포(A/B/C/D/F)
비교 결과는 GetSimulationResultsQuery로 조회 시 summary 및 comparisons에 포함됩니다.
처리 흐름(요약)
RunSequentialSimulationCommand실행
- dayIndex 범위(기본 8–42)를 순차 실행
- D일차 예측은 D−1일까지의 데이터로 수행
simulation_predictions에 예측 저장(신뢰도/합의/토론 지표 포함)
- 실제값 비교:
CompareSimulationResultsCommand
- 예측 대상 날짜별 실제 SOL을 입력
- 각 예측에
actualSOL설정 → 오차 계산 →simulation_comparisonsupsert - 세션 메트릭(MAE/RMSE/MAPE/±15분)을 업데이트
- 결과 조회:
GetSimulationResultsQuery
- 세션 메타/메트릭 + 예측 목록 + 비교 목록을 옵션에 따라 반환
CQRS/명령·쿼리 예시
RunSequentialSimulationCommand
new RunSequentialSimulationCommand(
userId,
'My SOL Backtest',
userCycleId, // 미지정 시 최신 사이클
SimulationType.BACKTESTING,
{
simulationRange: { startDayIndex: 8, endDayIndex: 42 },
description: 'Backtesting with CoD'
}
)
CompareSimulationResultsCommand
new CompareSimulationResultsCommand(
sessionId,
userId,
[
{ simulationDate: '2024-07-10', actualSOL: 28 },
{ simulationDate: '2024-07-11', actualSOL: 35 },
// ...
],
{
accuracyThresholds: { excellent: 5, good: 10, acceptable: 15 },
updateSessionMetrics: true,
overwriteExisting: false
}
)
API 엔드포인트(Universal API)
-
POST /simulation/start- 본문 DTO:
userId,sessionName,userCycleId?,description? - 내부적으로
RunSequentialSimulationCommand실행
- 본문 DTO:
-
GET /simulation/results/:sessionId?userId=...&includePredictions=true&includeComparisons=true&includeMetrics=true- 내부적으로
GetSimulationResultsQuery실행 - 세션 메타/예측/비교/요약 메트릭 반환
- 내부적으로
비교 실행용 API는 별도 공개되지 않았으며, 내부 작업 또는 배치에서 CQRS로 호출합니다(필요 시 노출 가능).
임계값/등급 규칙
- 기본 임계: ±15분(개별 예측
isWithinThreshold산정에 사용) - 비교 등급(A–F, 리포트용): 기본값은 다음 기준(옵션으로 조정 가능)
- A ≤ 5분, B ≤ 10분, C ≤ 15분, D ≤ 30분, F > 30분
날짜 매핑(dayIndex → date)
- 예측 생성 시에는 실제 치료 시작일/타임존을 반영해
dayIndex와simulationDate를 일관되게 관리합니다. - 비교 시 입력되는
simulationDate는 해당 예측의 대상 날짜와 매칭되어야 합니다. - 향후 모든 비교 경로가
DayIndexConversionService를 통해 확정적인 매핑을 사용하도록 점진 개선 중입니다.
참고 구현 위치
-
Handlers
- 순차 시뮬레이션:
RunSequentialSimulationHandler - 비교/집계:
CompareSimulationResultsHandler - 결과 조회:
GetSimulationResultsHandler
- 순차 시뮬레이션:
-
Repository(Prisma)
PrismaSimulationRepository.savePrediction/.saveComparison/.findComparisonsBySessionId- 세션 메트릭 업데이트:
.saveSession
예시: simulation_comparisons 레코드
{
"simulationSessionId": "<session-uuid>",
"simulationPredictionId": "<prediction-uuid>",
"comparisonDate": "2024-07-10",
"predictedSOL": 31,
"actualSOL": 28,
"absoluteError": 3,
"relativeError": 10.71,
"isWithinThreshold": true,
"thresholdMinutes": 15,
"createdAt": "2024-07-10T10:00:00.000Z"
}
요약
- 개별 예측은
absoluteError/percentageError/isWithinThreshold로 정확도를 표시하고,getPredictionQuality()로 종합 등급을 부여합니다. - 세션 단위로 MAE/RMSE/MAPE/±15분 비율 및 등급 분포를 집계하여 정확도 트렌드와 성능을 추적합니다.
- 비교 데이터는
simulation_comparisons에 영구 저장되어 재현성과 감사 가능성을 보장합니다.