Selection recipes¶
kuration.selection ships three general-purpose dataset-curation recipes — no gameplay or video
assumptions — plus a small config-driven runner for chaining them (or your own) from a dict, YAML,
or JSON config instead of hand-written Python. Importing the module registers all three as
Pipeline methods; see Operators §5 for the catalog
entry and the inventory for exact parameter tables.
Every recipe compiles to ordinary core primitives (.measure(), .bin(), .filter(),
.sample()) and exposes .describe() to show that exact chain — there is no hidden behavior a
user couldn't reproduce by hand.
BalancedSelector — cover the whole range of a signal¶
Registered as the operator kuration/balanced-selector.
Most naturally-occurring signals are middle-heavy: measuring and sampling by natural distribution
under-represents the tails. BalancedSelector measures a per-window feature, quantile-bins it
across the observed range, and samples an equal count from every bin, so a training set covers the
whole spread instead of the mode.
Compiles to .measure(feature, kind, of=of).bin(feature, bins=bins).sample("equal", n=count).
RareEventCoverage — don't let rare events get diluted¶
Registered as the operator kuration/rare-event-coverage.
A rare failure or contact event living inside a much larger stream of healthy telemetry gets
dropped by ordinary distribution matching. RareEventCoverage measures the per-window rate of a
boolean/0-1 event field, then weighted-samples so windows containing more of the event are favored
proportional to occupancy.
Compiles to .measure(feature, "rate", of=of).sample("weighted", n=count, weights={feature: weight}).
DiverseSubset — compress without losing coverage¶
Registered as the operator kuration/diverse-subset.
Given a set of already-measured features, DiverseSubset optionally drops near-duplicates by
cosine similarity, then samples equally from k-means clusters over the joint feature space.
Requires kuration-sdk[methods] (scikit-learn) at execution time, and expects features to
already be present on the pipeline via .measure(...).
pipeline.diverse_subset(features=("act", "temp_mean"), count=100, n_clusters=32, dedup_threshold=None)
Compiles to an optional .filter("dedup", feature_space=features, threshold=dedup_threshold)
followed by .sample("cluster-balanced", n=count, feature_space=features, clusters=n_clusters).
Direct dataclass use¶
Each recipe is also a plain, frozen dataclass with the same fields as its operator-method form, an
.apply(pipeline) -> pipeline method, and a .describe() -> str method:
from kuration.selection import BalancedSelector
op = BalancedSelector(feature="activity", of="signal", bins=4, count=20)
result = op.apply(pipeline).options(seed=1).collect()
print(op.describe())
# BalancedSelector: .measure('activity', 'std', of='signal') -> .bin('activity', bins=4) -> .sample('equal', n=20)
Constructor validation is fail-fast (ValueError at construction, before the pipeline is
touched) and names the invalid field.
Config-driven chaining¶
kuration.selection.run/plan/describe accept a list of Operation instances, {"type": ...}
config dicts, or a mix of both — all three call styles (operator method, direct dataclass, config
dict) produce identical results.
from kuration.selection import run
result = run(pipeline, [
{"type": "BalancedSelector", "feature": "activity", "of": "signal", "bins": 4, "count": 20},
]).options(seed=1).collect()
plan(operations)resolves dicts into instances without applying them, for inspection or logging before running.describe(operations)returns a multi-line human summary naming each operation's compiled SDK chain.- Unresolvable config entries raise a
ValueErrornaming the offending index and, for close misspellings of atypeor keyword, a "did you mean" hint.
Register your own .apply(pipeline) -> pipeline class for config-dict use with
register_operation_type:
from dataclasses import dataclass
from kuration.selection import register_operation_type
@dataclass(frozen=True)
class OnlyActiveWindows:
threshold: float = 0.1
def apply(self, pipeline):
return pipeline.measure("act", "std", of="signal").filter("act", ">", self.threshold)
register_operation_type("OnlyActiveWindows", OnlyActiveWindows)
run(pipeline, [{"type": "OnlyActiveWindows", "threshold": 0.15}])
This registry is independent of the SDK's operator Registry — it only affects how
dict-shaped entries resolve inside run/plan/describe, not what's callable as
pipeline.<name>(...).