export type PredictionConfidence = 'HIGH' | 'MEDIUM' | 'LOW' export type ReliabilityLevel = PredictionConfidence | 'PENDING' | 'UNKNOWN' const confidenceRank: Record = { LOW: 0, MEDIUM: 1, HIGH: 2, } const confidenceByRank: Record = { 0: 'LOW', 1: 'MEDIUM', 2: 'HIGH', } export const confidenceColor: Record = { HIGH: 'text-green-400', MEDIUM: 'text-yellow-400', LOW: 'text-red-400', } export const confidenceZh: Record = { HIGH: '高信心', MEDIUM: '中信心', LOW: '低信心', } const reliabilityColor: Record = { HIGH: 'text-green-400', MEDIUM: 'text-yellow-400', LOW: 'text-red-400', PENDING: 'text-yellow-300', UNKNOWN: 'text-slate-300', } const reliabilityZh: Record = { HIGH: '高可靠度', MEDIUM: '中可靠度', LOW: '低可靠度', PENDING: '計算中', UNKNOWN: '尚無', } export interface PredictionReliabilitySummary { level: ReliabilityLevel levelText: string levelColor: string confidenceText: string confidenceColor: string accuracyText: string accuracyColor: string hasModelAccuracy: boolean warning?: string } function clampConfidence( confidence: PredictionConfidence, maxConfidence: PredictionConfidence ): PredictionConfidence { const rank = Math.min(confidenceRank[confidence], confidenceRank[maxConfidence]) return confidenceByRank[rank] } export function getPredictionReliabilitySummary({ confidence, trainingAccuracy, isQuick = false, }: { confidence: PredictionConfidence trainingAccuracy?: number | null isQuick?: boolean }): PredictionReliabilitySummary { const hasModelAccuracy = !isQuick && Number.isFinite(trainingAccuracy) && Number(trainingAccuracy) > 0 const accuracyText = hasModelAccuracy ? `${(Number(trainingAccuracy) * 100).toFixed(1)}%` : isQuick ? 'ML 計算中' : '尚無' const confidenceText = `${confidence} (${confidenceZh[confidence]})` if (!hasModelAccuracy) { const level: ReliabilityLevel = isQuick ? 'PENDING' : 'UNKNOWN' return { level, levelText: reliabilityZh[level], levelColor: reliabilityColor[level], confidenceText, confidenceColor: confidenceColor[confidence], accuracyText, accuracyColor: isQuick ? 'text-yellow-300' : 'text-slate-300', hasModelAccuracy, } } const accuracy = Number(trainingAccuracy) let level: PredictionConfidence = confidence let warning: string | undefined if (accuracy < 0.5) { level = 'LOW' warning = confidence === 'HIGH' ? '高信心但模型品質偏弱,請謹慎參考。' : '模型近期驗證準確率低於 50%,請謹慎參考。' } else if (accuracy < 0.6) { level = clampConfidence(confidence, 'MEDIUM') warning = confidence === 'HIGH' ? '模型近期驗證準確率未達 60%,高信心訊號降為中可靠度。' : undefined } return { level, levelText: `${level} (${reliabilityZh[level]})`, levelColor: reliabilityColor[level], confidenceText, confidenceColor: confidenceColor[confidence], accuracyText, accuracyColor: accuracy < 0.5 ? 'text-red-300' : accuracy < 0.6 ? 'text-yellow-300' : 'text-slate-200', hasModelAccuracy, warning, } }