Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/platform/learn/survival.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | internal/platform/learn/survival.go |
| Original SHA-256 | 1ff30da0f0a6806e18436f5d3b5fde7b315be83340175295c8e8204500f5480e |
| Git blob SHA | 97d97e65c9dbd7f59e58b8befece358600a8d77b |
| Reading-copy SHA-256 | 1ff30da0f0a6806e18436f5d3b5fde7b315be83340175295c8e8204500f5480e |
Every recorded occurrence
These 8 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/missionmatch / internal/platform/learn/survival.go | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / internal/platform/learn/survival.go | collision-deconfliction | 4ee5a09972608ed89f8377c6665542d5f450f0a6 | Open original |
| Janady13/missionmatch / internal/platform/learn/survival.go | master | 1e9249840a4302ec82e123b9c9cb6f75badea3e4 | Open original |
| Janady13/missionmatch / internal/platform/learn/survival.go | time-to-fill-survival | b66e1e505863d4f17741a4b9ede73509e45bd6c6 | Open original |
| Janady13/missionmatch / internal/platform/learn/survival.go | presentation-readiness | eb574acaa29d71ce4d0f852572e87c275c79fdb7 | Open original |
| Janady13/missionmatch / internal/platform/learn/survival.go | vendor-intelligence | fe9796a19c261951d3f2565206c0c1b5ac294465 | Open original |
| Janady13/missionmatch / internal/platform/learn/survival.go | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
| Janady13/missionmatch / internal/platform/learn/survival.go | capture-readiness | bae6af7cb2997e819174a9e9cfff5e16067a1975 | Open original |
Recovered source transcript
Download complete source text ↓100 lines · 3.7 KB
package learn
// Discrete time survival for the time to fill forecast: how long a staffing requirement stays open before it is
// filled. It is a Kaplan Meier style discrete hazard, fully interpretable and pure: a per period (month) hazard
// is estimated from right censored durations, the cumulative survival is the running product of one minus the
// hazard, and the probability of filling within a horizon is one minus the survival at that horizon. A still
// open requirement is right censored: it is known to have survived to its observed period without filling, but
// not when it will fill, so it counts in the at risk denominator through its observed periods and never in the
// event numerator. No database, no Python; float lives only in this offline estimator and the caller quantizes
// every stored and surfaced number to decimal.
// Duration is one requirement's time to fill observation: the whole periods (months) observed, and whether the
// fill event occurred at the last observed period (Filled true) or the observation is right censored, still open
// at the last period (Filled false). Periods is at least 1.
type Duration struct {
Periods int
Filled bool
}
// EmpiricalHazard estimates the discrete time hazard per period from right censored durations. For each period m
// (1 based, index m-1 in the returned vector), hazard[m] = events at m / at risk at m, where at risk at m counts
// every observation whose Periods is at least m (it reached period m still open at the start of it), and events
// at m counts the observations that Filled exactly at period m. A still open (censored) observation contributes
// to every at risk denominator through its observed periods but to no event numerator. The returned vector has
// length maxPeriod; a period with no one at risk has hazard 0 (no evidence of filling then). maxPeriod at most 1
// returns a single period.
func EmpiricalHazard(durations []Duration, maxPeriod int) []float64 {
if maxPeriod < 1 {
maxPeriod = 1
}
events := make([]float64, maxPeriod)
atRisk := make([]float64, maxPeriod)
for _, d := range durations {
p := d.Periods
if p < 1 {
p = 1
}
if p > maxPeriod {
p = maxPeriod
}
// At risk in every period up to and including its observed period.
for m := 0; m < p; m++ {
atRisk[m]++
}
// The event (a fill) lands in the observed period only when it filled, not when it is censored.
if d.Filled {
events[p-1]++
}
}
hazard := make([]float64, maxPeriod)
for m := 0; m < maxPeriod; m++ {
if atRisk[m] > 0 {
hazard[m] = events[m] / atRisk[m]
}
}
return hazard
}
// Survival returns the cumulative survival curve from a per period hazard vector: S[t] = product over i in 0..t
// of (1 - hazard[i]). S has the same length as hazards; S[t] is the probability of still being open (not yet
// filled) at the end of period t+1. A hazard clamped outside [0,1] is treated as its nearest bound so the
// survival stays a valid probability.
func Survival(hazards []float64) []float64 {
s := make([]float64, len(hazards))
running := 1.0
for t, h := range hazards {
if h < 0 {
h = 0
}
if h > 1 {
h = 1
}
running *= (1 - h)
s[t] = running
}
return s
}
// FillWithin returns the probability the requirement is filled within `horizon` periods: 1 - S(horizon). A
// horizon at or below zero is 0 (nothing fills in no time); a horizon beyond the hazard vector uses the full
// vector (the survival cannot fall further with no more hazard evidence). The result is a probability in [0, 1].
func FillWithin(hazards []float64, horizon int) float64 {
if horizon <= 0 || len(hazards) == 0 {
return 0
}
s := Survival(hazards)
idx := horizon - 1
if idx >= len(s) {
idx = len(s) - 1
}
p := 1 - s[idx]
if p < 0 {
return 0
}
if p > 1 {
return 1
}
return p
}
Mathematical records from this source
0102
survival · (1 based, index m-1 in the returned vector), hazard[m]
This relation defines (1 based, index m-1 in the returned vector), hazard[m] in the source section “survival · (1 based, index m-1 in the returned vector), hazard[m]”. It…
Survival probability from conditional hazards
Each hazard is the conditional probability of an event in that period given survival up to that period. Multiplying successive complements yields the probability of remaining…