cohort

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package cohort partitions a fleet into groups of clusters that look like each other. User-supplied tags win when present. Without tags, agglomerative clustering on a feature vector groups similar clusters so that drift detection can run within cohort instead of across the entire fleet.

Index

Constants

View Source
const DefaultTagKey = "cohort"

DefaultTagKey is the cluster-tag key that carries a cohort label.

Variables

This section is empty.

Functions

This section is empty.

Types

type ClusterProfile

type ClusterProfile struct {
	// Name is the cluster name.
	Name string
	// Features is the normalized feature vector. All profiles share the
	// same feature order.
	Features []float64
	// Tag is the user-supplied cohort label, "" when unset.
	Tag string
}

ClusterProfile is the per-cluster input to Assign. Features must be aligned across profiles, in the same order, and already normalized to roughly [0,1]. Tag is the user-supplied cohort label or "" if none was set.

func Profiles

func Profiles(clusters []string, sections SectionLookup, tags map[string]string) []ClusterProfile

Profiles builds normalized feature vectors for every cluster in the fleet. Each feature is min-max normalized across the fleet to [0,1] so dimensions with large absolute ranges do not dominate distance calculations. Missing values are imputed with the per-feature fleet median before normalization. tags maps cluster name to its user-supplied cohort label (empty string when none).

type Cohort

type Cohort struct {
	// Name is the cohort label. For tagged cohorts this is the tag value.
	// For auto-detected cohorts this is "auto-N" with a stable index.
	Name string `json:"name"`
	// Source identifies how this cohort was produced.
	Source Source `json:"source"`
	// Clusters lists the member cluster names, sorted for stable output.
	Clusters []string `json:"clusters"`
}

Cohort is a group of clusters that look similar enough to share a baseline.

func Assign

func Assign(profiles []ClusterProfile, opts Options) []Cohort

Assign partitions clusters into cohorts. Profiles carrying a non-empty Tag land in tagged cohorts named after the tag. Untagged profiles get auto-assigned via average-linkage agglomerative clustering on their feature vectors, with K chosen from the largest gap in the merge sequence. When the fleet is too small to subdivide, every cluster lands in a single "fleet" cohort.

type Options

type Options struct {
	// MinClusters is the fleet size below which auto-cohorting is skipped.
	// Zero means use the package default.
	MinClusters int
	// MinCohortSize is the smallest cohort the algorithm will keep.
	// Cohorts below this size are folded into their nearest neighbor.
	// Zero means use the package default.
	MinCohortSize int
	// MaxCohorts caps the number of auto-detected cohorts.
	// Zero means use the package default.
	MaxCohorts int
}

Options controls cohort assignment.

type SectionLookup

type SectionLookup interface {
	// PerCluster returns the raw per-cluster data for a scanner. The map key
	// is the cluster name. Returns nil when the scanner is absent.
	PerCluster(scanner string) map[string]any
}

SectionLookup is the minimal interface Profiles needs to walk a Report without depending on the report package. Callers wrap their Report.Sections in something that satisfies this.

type Source

type Source string

Source indicates how a cohort was determined.

const (
	// SourceTagged means the cohort came from a user-supplied cluster tag.
	SourceTagged Source = "tagged"
	// SourceAuto means the cohort was derived by clustering scanner data.
	SourceAuto Source = "auto"
	// SourceFleet means the fleet was too small or too uniform to subdivide.
	SourceFleet Source = "fleet"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL