ModaSensitivity

Asks how much a study's recommendation depends on the weights it was given.

A weight in an additive model is not a statement of how important something is in the abstract; it is a scaling constant tied to the range the metric was measured over. Decision makers rarely hold weights precisely, so the useful question is not what the recommendation is but how far a weight would have to move before the recommendation changed. A recommendation that survives large movements is worth acting on; one that turns on the third decimal place of a weight is really a tie being reported as a decision.

Varying one metric's weight means deciding what happens to the others. They are held in their existing proportions to one another and scaled to fill whatever is left, which keeps the weights summing to one while changing only the one thing being asked about. With that convention each alternative's overall value is a straight line in the weight, so the point where two alternatives change places is solved directly rather than searched for.

This reads a ModaSnapshot rather than a live model, so the answers cannot drift underneath the caller while it asks a series of questions.

Constructors

Link copied to clipboard
constructor(snapshot: ModaSnapshot)

Properties

Link copied to clipboard

The metrics of the study, in the order it declared them.

Functions

Link copied to clipboard
fun criticalWeight(metric: String, a: String, b: String): Double?

The weight on metric at which alternatives a and b change places, or null when they never do.

Link copied to clipboard

Every weight on metric at which the study's current recommendation would be displaced, nearest first, so the most fragile comparison is reported first. Ties are broken by the name of the displacing alternative so the order is the same every time.

Link copied to clipboard

The weight this study's recommendation is most fragile to, across every metric, or null when no weight within 0, 1 would change it. A null here is the strongest thing sensitivity can say for a recommendation: no single weight can be moved anywhere and displace it.

Link copied to clipboard
fun overallValuesAt(metric: String, weight: Double): Map<String, Double>

The overall value of every alternative if metric carried the given weight, with the other metrics held in their existing proportions and scaled to fill the remainder.

Link copied to clipboard
fun weightSweep(metric: String, steps: Int = 50): List<SweepPoint>

The study evaluated across the whole range of weights for metric, for plotting or for reporting where the recommendation changes hands.

Link copied to clipboard
fun winnerAt(metric: String, weight: Double): String

The alternative a study would recommend if metric carried the given weight. Alternatives that tie are resolved by name, the same way a snapshot resolves them, so asking twice gives the same answer.