Bias tied template analytics by confidence lane
This commit is contained in:
parent
961386af73
commit
3325dc40b9
2 changed files with 186 additions and 0 deletions
|
|
@ -160,6 +160,14 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
int32* OutPeerNoEvidenceOutcomeRuns = nullptr
|
||||
);
|
||||
|
||||
bool HasTemplateLaunchTemplateSignalConfidenceSnapshotBias(
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats,
|
||||
int32* OutConfidenceEligibleOutcomeRuns = nullptr,
|
||||
int32* OutTemplateSignalOutcomeRuns = nullptr,
|
||||
float* OutConfidenceEligibleOutcomeShare = nullptr,
|
||||
int32* OutSuppressedOutcomeRuns = nullptr
|
||||
);
|
||||
|
||||
int32 BuildTemplateLaunchAnalyticsTieBreakConfidenceBonus(
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats
|
||||
);
|
||||
|
|
@ -570,6 +578,25 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
NoRetainedLaneStats,
|
||||
TEXT("no-retained-lane"))
|
||||
);
|
||||
int32 ConfidenceEligibleOutcomeRuns = 0;
|
||||
int32 TemplateSignalOutcomeRuns = 0;
|
||||
int32 SuppressedOutcomeRuns = 0;
|
||||
float ConfidenceEligibleOutcomeShare = 0.0f;
|
||||
const bool bBiasEarned = HasTemplateLaunchTemplateSignalConfidenceSnapshotBias(
|
||||
TemplateStats,
|
||||
&ConfidenceEligibleOutcomeRuns,
|
||||
&TemplateSignalOutcomeRuns,
|
||||
&ConfidenceEligibleOutcomeShare,
|
||||
&SuppressedOutcomeRuns
|
||||
);
|
||||
Fragment += FString::Printf(
|
||||
TEXT(" | bias %s eligible %d/%d outcomes share %.2f | suppressed outcomes %d"),
|
||||
bBiasEarned ? TEXT("earned") : TEXT("suppressed"),
|
||||
ConfidenceEligibleOutcomeRuns,
|
||||
TemplateSignalOutcomeRuns,
|
||||
ConfidenceEligibleOutcomeShare,
|
||||
SuppressedOutcomeRuns
|
||||
);
|
||||
if (ConfidenceEligibleStats.IsStructurallyValid()
|
||||
&& SuppressedStats.IsStructurallyValid()
|
||||
&& ConfidenceEligibleStats.GetOutcomeRunCount() > 0
|
||||
|
|
@ -1335,6 +1362,11 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
constexpr float TemplateLaunchSelectionTieBreakConfidenceMinimumMistakeImprovement = 0.5f;
|
||||
constexpr int32 TemplateLaunchSelectionTieBreakConfidenceMinimumComparablePeerOutcomeRuns = 2;
|
||||
constexpr float TemplateLaunchSelectionTieBreakConfidenceMinimumComparablePeerOutcomeShare = 0.40f;
|
||||
constexpr int32 TemplateLaunchTemplateSignalConfidenceMinimumEligibleOutcomeRuns = 2;
|
||||
constexpr float TemplateLaunchTemplateSignalConfidenceMinimumEligibleOutcomeShare = 0.50f;
|
||||
constexpr int32 TemplateLaunchTemplateSignalConfidenceMinimumScoreDelta = 1;
|
||||
constexpr float TemplateLaunchTemplateSignalConfidenceMinimumSuccessDelta = 0.05f;
|
||||
constexpr float TemplateLaunchTemplateSignalConfidenceMinimumMistakeImprovement = 0.5f;
|
||||
|
||||
int32 CountTemplateLaunchOutcomeRuns(const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats)
|
||||
{
|
||||
|
|
@ -1479,6 +1511,95 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
>= TemplateLaunchSelectionTieBreakConfidenceMinimumComparablePeerOutcomeShare;
|
||||
}
|
||||
|
||||
bool HasTemplateLaunchTemplateSignalConfidenceSnapshotBias(
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats,
|
||||
int32* OutConfidenceEligibleOutcomeRuns,
|
||||
int32* OutTemplateSignalOutcomeRuns,
|
||||
float* OutConfidenceEligibleOutcomeShare,
|
||||
int32* OutSuppressedOutcomeRuns
|
||||
)
|
||||
{
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats* TemplateSignalStats = nullptr;
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats* ConfidenceEligibleStats =
|
||||
nullptr;
|
||||
const FHyperTwistTrainingTemplateLaunchSelectionScopedStats* SuppressedStats = nullptr;
|
||||
if (TemplateStats != nullptr && TemplateStats->IsStructurallyValid())
|
||||
{
|
||||
TemplateSignalStats =
|
||||
&TemplateStats->DashboardAnalyticsTieBreakTemplateScopedSignalStats;
|
||||
ConfidenceEligibleStats =
|
||||
&TemplateStats
|
||||
->DashboardAnalyticsTieBreakTemplateScopedSignalConfidenceEligibleStats;
|
||||
SuppressedStats =
|
||||
&TemplateStats
|
||||
->DashboardAnalyticsTieBreakTemplateScopedSignalSuppressedPeerNoEvidenceHeavyStats;
|
||||
}
|
||||
|
||||
const int32 ConfidenceEligibleOutcomeRuns =
|
||||
CountTemplateLaunchSelectionOutcomeRuns(ConfidenceEligibleStats);
|
||||
const int32 TemplateSignalOutcomeRuns =
|
||||
CountTemplateLaunchSelectionOutcomeRuns(TemplateSignalStats);
|
||||
const int32 SuppressedOutcomeRuns =
|
||||
CountTemplateLaunchSelectionOutcomeRuns(SuppressedStats);
|
||||
const float ConfidenceEligibleOutcomeShare = TemplateSignalOutcomeRuns > 0
|
||||
? static_cast<float>(ConfidenceEligibleOutcomeRuns)
|
||||
/ static_cast<float>(TemplateSignalOutcomeRuns)
|
||||
: 0.0f;
|
||||
|
||||
if (OutConfidenceEligibleOutcomeRuns != nullptr)
|
||||
{
|
||||
*OutConfidenceEligibleOutcomeRuns = ConfidenceEligibleOutcomeRuns;
|
||||
}
|
||||
if (OutTemplateSignalOutcomeRuns != nullptr)
|
||||
{
|
||||
*OutTemplateSignalOutcomeRuns = TemplateSignalOutcomeRuns;
|
||||
}
|
||||
if (OutConfidenceEligibleOutcomeShare != nullptr)
|
||||
{
|
||||
*OutConfidenceEligibleOutcomeShare = ConfidenceEligibleOutcomeShare;
|
||||
}
|
||||
if (OutSuppressedOutcomeRuns != nullptr)
|
||||
{
|
||||
*OutSuppressedOutcomeRuns = SuppressedOutcomeRuns;
|
||||
}
|
||||
|
||||
if (ConfidenceEligibleOutcomeRuns
|
||||
< TemplateLaunchTemplateSignalConfidenceMinimumEligibleOutcomeRuns
|
||||
|| ConfidenceEligibleOutcomeShare
|
||||
< TemplateLaunchTemplateSignalConfidenceMinimumEligibleOutcomeShare)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (SuppressedOutcomeRuns <= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const int32 ConfidenceEligibleScore =
|
||||
BuildTemplateLaunchSelectionLaneAnalyticsScore(ConfidenceEligibleStats);
|
||||
const int32 SuppressedScore =
|
||||
BuildTemplateLaunchSelectionLaneAnalyticsScore(SuppressedStats);
|
||||
const int32 ScoreDelta = ConfidenceEligibleScore - SuppressedScore;
|
||||
const float SuccessDelta =
|
||||
(ConfidenceEligibleStats != nullptr && ConfidenceEligibleStats->IsStructurallyValid()
|
||||
? ConfidenceEligibleStats->OverallSuccessRate
|
||||
: 0.0f)
|
||||
- (SuppressedStats != nullptr && SuppressedStats->IsStructurallyValid()
|
||||
? SuppressedStats->OverallSuccessRate
|
||||
: 0.0f);
|
||||
const float MistakeImprovement =
|
||||
(SuppressedStats != nullptr && SuppressedStats->IsStructurallyValid()
|
||||
? SuppressedStats->AverageMistakesPerOutcomeRun
|
||||
: 0.0f)
|
||||
- (ConfidenceEligibleStats != nullptr && ConfidenceEligibleStats->IsStructurallyValid()
|
||||
? ConfidenceEligibleStats->AverageMistakesPerOutcomeRun
|
||||
: 0.0f);
|
||||
return ScoreDelta >= TemplateLaunchTemplateSignalConfidenceMinimumScoreDelta
|
||||
|| SuccessDelta >= TemplateLaunchTemplateSignalConfidenceMinimumSuccessDelta
|
||||
|| MistakeImprovement
|
||||
>= TemplateLaunchTemplateSignalConfidenceMinimumMistakeImprovement;
|
||||
}
|
||||
|
||||
int32 BuildTemplateLaunchAnalyticsTieBreakConfidenceBonus(
|
||||
const FHyperTwistTrainingTemplateLaunchScopedStats* TemplateStats
|
||||
)
|
||||
|
|
@ -1736,6 +1857,24 @@ namespace HyperTwistCoachDashboardWidgetInternal
|
|||
}
|
||||
return Decision;
|
||||
}
|
||||
const int32 CandidateTemplateSignalConfidenceSnapshotBonus =
|
||||
HasTemplateLaunchTemplateSignalConfidenceSnapshotBias(CandidateStats) ? 1 : 0;
|
||||
const int32 IncumbentTemplateSignalConfidenceSnapshotBonus =
|
||||
HasTemplateLaunchTemplateSignalConfidenceSnapshotBias(IncumbentStats) ? 1 : 0;
|
||||
if (CandidateTemplateSignalConfidenceSnapshotBonus
|
||||
!= IncumbentTemplateSignalConfidenceSnapshotBonus)
|
||||
{
|
||||
Decision.bPreferCandidate =
|
||||
CandidateTemplateSignalConfidenceSnapshotBonus
|
||||
> IncumbentTemplateSignalConfidenceSnapshotBonus;
|
||||
if (Decision.bPreferCandidate)
|
||||
{
|
||||
Decision.CandidateAnalyticsSupportKind =
|
||||
EHyperTwistTrainingTemplateLaunchSelectionAnalyticsSupportKind::
|
||||
TemplateScopedOutcomeSignal;
|
||||
}
|
||||
return Decision;
|
||||
}
|
||||
if (CandidateOutcomeRuns != IncumbentOutcomeRuns)
|
||||
{
|
||||
Decision.bPreferCandidate = CandidateOutcomeRuns > IncumbentOutcomeRuns;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
# HyperTwist Phase 4 template-signal confidence scoring bias packet
|
||||
|
||||
## Purpose
|
||||
|
||||
This packet feeds the new broader `TemplateScopedOutcomeSignal` confidence-snapshot split back into actual dashboard analytics tie-break selection. When the existing analytics score already ties, the selector can now conservatively prefer a template whose broader analytics wins are already landing in the `confidence-eligible` lane instead of a competing template whose broader wins still cluster in the `suppressed` lane.
|
||||
|
||||
## Scope
|
||||
|
||||
- add a conservative template-signal confidence-snapshot bias helper in dashboard selection logic
|
||||
- require minimum `confidence-eligible` outcome count and share before the bias can exist
|
||||
- if the template still has suppressed broader-history outcomes, require the eligible lane to beat or clearly improve on the suppressed lane before the bias is awarded
|
||||
- apply that bias only after the existing analytics score ties
|
||||
- surface the same bias-earned / bias-suppressed state in shared template analytics detail
|
||||
|
||||
## What landed
|
||||
|
||||
- `HyperTwistCoachDashboardWidget.cpp`
|
||||
- added `HasTemplateLaunchTemplateSignalConfidenceSnapshotBias(...)`
|
||||
- new guard requirements:
|
||||
- at least `2` `confidence-eligible` outcome runs
|
||||
- at least `0.50` eligible share within broader template-signal outcomes
|
||||
- if suppressed broader-history exists, eligible outcomes must beat it on lane score or show meaningful success / mistake improvement
|
||||
- `ResolveTemplateAnalyticsPreferenceDecision(...)` now consults this bias only after the existing analytics score already ties
|
||||
- shared template analytics detail now appends:
|
||||
- `bias earned` or `bias suppressed`
|
||||
- eligible outcome count/share
|
||||
- suppressed outcome count
|
||||
|
||||
## Product effect
|
||||
|
||||
- broader template-signal confidence history no longer just sits in analytics detail; it can now break otherwise tied analytics choices
|
||||
- the bias stays conservative because it does not override the main analytics score and it requires both sample depth and lane-share support
|
||||
- live `[Template Launch]` detail, template launch history, and run recap now expose whether the broader template-signal bias is currently earned or suppressed for the displayed template
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- the new broader template-signal confidence bias only applies after the current analytics score ties
|
||||
- the bias requires minimum eligible outcome count and share
|
||||
- suppressed broader-history prevents the bias unless the eligible lane meaningfully beats or improves on it
|
||||
- shared analytics detail shows whether the broader template-signal bias is earned or suppressed
|
||||
|
||||
## Validation checklist
|
||||
|
||||
1. full `Development Editor|Win64` build succeeds
|
||||
2. confirm `ResolveTemplateAnalyticsPreferenceDecision(...)` checks the new bias only after score equality
|
||||
3. confirm the bias requires minimum eligible outcome count/share
|
||||
4. confirm shared analytics detail reports `bias earned` or `bias suppressed` with eligible count/share and suppressed count
|
||||
Loading…
Add table
Reference in a new issue