Skip to content

Performance Profile

Greg Wilkins edited this page Oct 10, 2026 · 4 revisions

Boat Performance Profile

Overview

In addition to the PF value itself, the PF analysis produces enough information to characterise how a boat is being sailed, not just how fast it is. This is captured as a Performance Profile — a set of five measures derived from the per-race residuals produced by the PF optimisation, presented as a radar (pentagon) chart.

The profile is a companion to the PF value, not a replacement for it. PF answers "how fast is this boat on average". The performance profile answers "how actively, reliably, and consistently is this boat sailed relative to that average".


Residuals

All profile measures are derived from the per-race log-residuals computed by the PF optimisation:

residual_i = log(elapsedTime_i × PF_boat) − log(T_race_i)

A negative residual means the boat was faster than its PF predicts in that race. A positive residual means it was slower.


Fleet-Relative Scoring

All five spokes are fleet-relative percentile scores: each boat is ranked within the active fleet (boats with at least 3 distinct races in the last 12 months) and the score is the percentile rank, mapped to [0, 1]. A score of 1.0 means best in fleet on that spoke; 0.0 means worst.

This approach makes the chart immediately legible — an average boat in every dimension scores 0.5 on every spoke — and means scores are self-calibrating as the fleet grows.

All measures use the last 12 months of race data only.


The Five Spokes

1. Frequency

What it measures: how much time the boat spends racing, and how broadly that participation is spread across the year.

Derivation: percentile rank of a duration-weighted race count, multiplied by a small year-spread bonus.

  • Each distinct race contributes (race duration / fleet-median duration)^α where α ≈ 0.26 (a race twice as long counts approximately 1.2× more).

  • The total is then multiplied by a spread factor derived from the number of distinct calendar months in which the boat raced inside the 12-month window:

    spread_factor = 0.85 + 0.15 × min(months_active, 12) / 12
    

    A boat racing in a single month gets ≈ 0.86; a boat racing every month of the year gets 1.0. The bonus is deliberately small — duration-weighted race count remains the dominant contribution.

Interpretation: a high frequency score means the boat is an active participant in the fleet over the whole year, not just a short season. This spoke is included because a boat with rich, well-spread race data is more useful to handicappers than an occasionally- or seasonally-racing boat with the same PF. It is not a measure of sailing quality, but it does underpin the reliability of the other spokes.


2. Consistency

What it measures: how tightly the boat's results cluster around its PF, with extra weight on "fast" surprises that hint at untapped potential.

Derivation: percentile rank of the asymmetrically weighted mean squared residual across recent race entries (lower = better = higher percentile). Every race counts equally regardless of whether it was down-weighted in the PF optimiser, so a boat with occasional large residuals is correctly penalised.

Asymmetric weighting: negative residuals (boat faster than its PF predicted) are weighted 1.5× more than positive residuals (slower) of the same magnitude:

contribution = r²    if r ≥ 0   (slow surprise)
             = 1.5×r² if r < 0   (fast surprise)

A fast surprise suggests the boat has more potential than its current PF reflects — likely a sign of a genuinely inconsistent boat, where a single big result distorts the average. A slow surprise is more easily explained by a bad start, a gear failure, or a tactical error and is therefore weighted less harshly.

Discards: a configurable number of the most-divergent results (by absolute residual) are excluded before computing the mean, similar to series scoring. One discard is allowed per N distinct races sailed (default N = 11): 1 discard at 11 races, 2 at 22, and so on. This rewards boats with long track records by forgiving occasional bad days.

Interpretation: a high consistency score means the boat produces similar results race after race, and does not occasionally surprise the fleet with unexpectedly fast times. This reflects stable crew, preparation, and boat reliability. It does not by itself say whether those results are fast or slow — that relationship is captured by the PF value itself.


3. Diversity

What it measures: how broadly the boat races, weighted by racing variant and by how often it meets each opponent.

Derivation: percentile rank of a variant-weighted √-encounters score. For each distinct (opponent, variant) pair encountered in recent races, the contribution is

contribution = variant_weight × √(encounters with that opponent in that variant)

with variant weights:

Variant Weight
Non-spinnaker 0.8
Spinnaker 1.0
Two-handed 1.2

The same opponent met in two different variants counts as two pairs. The square root damps repeats, so distinct opposition still dominates the score, but a boat that frequently races a diverse field scores higher than a boat with the same breadth of opposition met only once or twice.

For example, with default weights, ten spinnaker encounters against five distinct opponents (5 × √10 ≈ 15.8) outscores one spinnaker encounter against the same five opponents (5 × √1 = 5).

Interpretation: a high diversity score means the boat's PF is grounded in repeated competitive exposure to a varied field — multiple fleets, different course types, different race lengths, often. This makes the PF more reliable as a cross-context descriptor of performance.


4. Chaotic

What it measures: whether a boat's performance variations occur in disorderly races (excusable — the rest of the fleet also strayed from its handicaps, so the conditions explain it) or in orderly races (intrinsic boat/crew issues — the rest of the fleet finished close to its handicaps, in the expected order). It measures the pattern of the boat's errors, independent of how large they are; Consistency measures their size.

Derivation: percentile rank of the boat's orderly-race share of error (lower = better):

spread_i = IQR of the OTHER boats' residuals in race i's division
           (leave-one-out: a boat's own bad race never makes its division look disorderly)
orderly  = Σ (w_i / (spread_i + 0.01)) × r_i²  /  Σ (w_i / (spread_i + 0.01))
plain    = Σ w_i × r_i²  /  Σ w_i
ratio    = orderly / plain

orderly weights each race by how orderly the rest of the fleet was; plain weights them all alike. Their ratio is low when the boat's errors come in disorderly races, and high when they come in orderly ones. Because the size of the errors cancels out, the spoke is essentially independent of Consistency (correlation across the fleet ≈ 0, down from ≈ 0.9 when this spoke was a dispersion-weighted mean squared residual).

It also judges a very consistent boat on the little error it does have: if its one bad race was an orderly one, that race dominates its ratio, so a consistent boat is punished clearly for any chaos of its own.

Small samples are noisy, so the ratio is shrunk towards the fleet's median ratio: (n × ratio + 5 × median) / (n + 5) for a boat with n qualifying races. (The median rather than 1, because errors are naturally larger in disorderly races, so the typical ratio is below 1.)

A race counts only if at least 3 other boats in its division have residuals; boats with fewer than 5 such races receive a score of 0.

Interpretation: a high Chaotic score does not mean the boat is fast or consistent; it means that when the boat underperforms, there is usually a fleet-wide reason. Combined with high Consistency this is the ideal — the boat is reliable, and its rare off days happen in universally difficult races.


5. Stability

What it measures: whether the boat's performance trend is level or declining.

Derivation: percentile rank of an asymmetric slope penalty from a weighted linear regression of residuals against race date. The penalty is:

  • Level trend (slope ≈ 0): no penalty, ranks best
  • Improving trend (negative slope — boat getting faster relative to the fleet): half the penalty of an equivalent declining trend
  • Declining trend (positive slope — boat getting slower): penalised most heavily, as this suggests the current PF may already be stale

Interpretation: a high stability score means the boat's relationship to its PF is settled over the analysis horizon. A low score means the boat is in transition — new crew, new sails, ageing hull, or ownership change. An improving trend is scored leniently because a boat getting faster is usually good news; the PF will self-correct as more data accumulates.


Spoke Order

Spokes are arranged on the pentagon to place conceptually unrelated measures adjacent to each other, which prevents correlated measures from inflating the visible area:

Frequency — Consistency — Diversity — Chaotic — Stability

(Pentagon, equally spaced at 72°.)


Overall Score

The overall score is the normalised area of the radar polygon:

area     = (1/2) × sin(2π/n) × Σ(r_i × r_{i+1 mod n})

score    = area / area_max
         = area / ((n/2) × sin(2π/n))

A perfect pentagon (all spokes = 1) gives score = 1.0. Any spoke at zero collapses the two adjacent triangles, so a single persistent weakness loses disproportionately more area than the spoke value alone would suggest. This is intentional — a single persistent weakness is genuinely costly in racing.

The overall score is displayed as a secondary label beneath the chart. The shape is the primary insight; the number is a convenience summary for sorting and comparison.


Minimum Race Threshold

A boat must have at least 3 distinct races in the last 12 months to appear in the fleet ranking at all. Below this threshold no spoke scores are shown.

The Chaotic spoke additionally requires 5 races in divisions with at least 3 other boats (so the rest of the fleet's spread can be measured without the boat); below this it scores 0.


Presentation

Single Boat

Display the radar pentagon with each spoke labelled. Show the overall score below the chart. Raw values (MSR, slope, correlation, etc.) are available in a tooltip or expandable panel for users who want to understand the derivation.

Boat Comparison

Overlay two boats as two polygons in contrasting colours with transparency. The shape difference is immediately legible. The overall score for each is shown in the legend.

Series View Integration

The performance profile naturally extends the series view (PF per boat per race). A small radar thumbnail alongside each boat's PF row gives the handicapper an immediate read on whether the PF is backed by consistent, reliable evidence or is a noisy estimate from a variable or infrequently-racing boat.


Implementation Notes

  • All profile calculations are derived layer — pure functions of the per-race residuals and race dispersion metrics already produced by the PF optimisation. They belong in a PerformanceProfileBuilder service class, not in the optimisation layer.
  • The BoatHpf record (final output of the optimisation) already carries per-race residuals. The profile builder consumes those records plus the race dispersion metrics from RaceDispersion.
  • No new raw data is required. No new ingestion logic is required.
  • The radar chart is rendered client-side in Plotly.js using the scatterpolar trace type.

Clone this wiki locally