robustsignalmaker 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- robustsignalmaker/__init__.py +188 -0
- robustsignalmaker/config.py +91 -0
- robustsignalmaker/masking.py +518 -0
- robustsignalmaker/metrics.py +193 -0
- robustsignalmaker/models.py +309 -0
- robustsignalmaker/nested_cv.py +527 -0
- robustsignalmaker/py.typed +0 -0
- robustsignalmaker/representations.py +226 -0
- robustsignalmaker/reproducibility.py +96 -0
- robustsignalmaker/results.py +177 -0
- robustsignalmaker/segments.py +116 -0
- robustsignalmaker/selection.py +559 -0
- robustsignalmaker/synthetic.py +244 -0
- robustsignalmaker/tuning.py +142 -0
- robustsignalmaker/validity.py +625 -0
- robustsignalmaker-0.2.0.dist-info/METADATA +356 -0
- robustsignalmaker-0.2.0.dist-info/RECORD +20 -0
- robustsignalmaker-0.2.0.dist-info/WHEEL +5 -0
- robustsignalmaker-0.2.0.dist-info/licenses/LICENSE +21 -0
- robustsignalmaker-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"""RobustSignalMaker: NaN-aware, leakage-free stability selection for signals.
|
|
2
|
+
|
|
3
|
+
Third sibling of RobustModelMaker (tabular columns) and RobustPixelMaker
|
|
4
|
+
(image patches): RSM identifies the important parts of scientific signals and
|
|
5
|
+
spectra (time-, space-, mass-series) to retain and removes the rest, with
|
|
6
|
+
missing data treated as absent evidence rather than something to fabricate.
|
|
7
|
+
See RSM_PLAN.md for the design and build order.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from .config import RSMConfig, fit_count
|
|
12
|
+
from .metrics import (
|
|
13
|
+
BaselineComparison,
|
|
14
|
+
adjusted_jaccard,
|
|
15
|
+
expected_jaccard,
|
|
16
|
+
jaccard,
|
|
17
|
+
mean_pairwise_jaccard,
|
|
18
|
+
paired_comparison,
|
|
19
|
+
rmse_from_score,
|
|
20
|
+
score_predictions,
|
|
21
|
+
)
|
|
22
|
+
from .masking import (
|
|
23
|
+
SoftMaskSelector,
|
|
24
|
+
loss_and_dz,
|
|
25
|
+
mask_data_gradient,
|
|
26
|
+
renormalised_gated_forward,
|
|
27
|
+
)
|
|
28
|
+
from .nested_cv import (
|
|
29
|
+
BootstrapMaskFoldEstimator,
|
|
30
|
+
EnsembleMaskFoldEstimator,
|
|
31
|
+
FoldEstimator,
|
|
32
|
+
FullSignalFoldEstimator,
|
|
33
|
+
NestedCV,
|
|
34
|
+
SoftMaskFoldEstimator,
|
|
35
|
+
infer_task,
|
|
36
|
+
make_inner_splitter,
|
|
37
|
+
make_outer_splitter,
|
|
38
|
+
)
|
|
39
|
+
from .representations import (
|
|
40
|
+
GaussianScale1D,
|
|
41
|
+
RandomConv1D,
|
|
42
|
+
SavGolDerivative,
|
|
43
|
+
SegmentMean,
|
|
44
|
+
SegmentStats,
|
|
45
|
+
default_ensemble,
|
|
46
|
+
)
|
|
47
|
+
from .reproducibility import (
|
|
48
|
+
BOOTSTRAP_OFFSET,
|
|
49
|
+
INNER_OFFSET,
|
|
50
|
+
REPEAT_STRIDE,
|
|
51
|
+
REPRESENTATION_OFFSET,
|
|
52
|
+
Seeds,
|
|
53
|
+
set_global_seed,
|
|
54
|
+
)
|
|
55
|
+
from .models import (
|
|
56
|
+
ALGORITHMS,
|
|
57
|
+
ExternalRefit,
|
|
58
|
+
PLSDA,
|
|
59
|
+
make_refit_model,
|
|
60
|
+
refit_features,
|
|
61
|
+
)
|
|
62
|
+
from .results import RSMResult
|
|
63
|
+
from .segments import SegmentGrid
|
|
64
|
+
from .selection import (
|
|
65
|
+
BootstrapMaskSelector,
|
|
66
|
+
RepresentationEnsembleSelector,
|
|
67
|
+
complementary_pair,
|
|
68
|
+
observation_groups,
|
|
69
|
+
resample_indices,
|
|
70
|
+
)
|
|
71
|
+
from .tuning import lam_for_coverage, lam_frontier
|
|
72
|
+
from .synthetic import (
|
|
73
|
+
SignalControl,
|
|
74
|
+
drop_labels,
|
|
75
|
+
make_signal_control,
|
|
76
|
+
mask_band_by_group,
|
|
77
|
+
mask_dropout_stretches,
|
|
78
|
+
mask_saturation_censor,
|
|
79
|
+
mask_scattered,
|
|
80
|
+
)
|
|
81
|
+
from .validity import (
|
|
82
|
+
InsufficientEvidenceError,
|
|
83
|
+
MissingnessInformativeWarning,
|
|
84
|
+
StandardisationStats,
|
|
85
|
+
as_validity,
|
|
86
|
+
fabricated_edge,
|
|
87
|
+
fill_mean,
|
|
88
|
+
fill_zero,
|
|
89
|
+
is_contrast_filter,
|
|
90
|
+
masked_mean,
|
|
91
|
+
masked_standardise,
|
|
92
|
+
masked_standardise_fit,
|
|
93
|
+
masked_std,
|
|
94
|
+
missingness_association,
|
|
95
|
+
observation_support,
|
|
96
|
+
renormalised_convolve1d,
|
|
97
|
+
renormalised_dot,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
__version__ = "0.2.0"
|
|
101
|
+
|
|
102
|
+
__all__ = [
|
|
103
|
+
"__version__",
|
|
104
|
+
# config
|
|
105
|
+
"RSMConfig",
|
|
106
|
+
"fit_count",
|
|
107
|
+
# reproducibility
|
|
108
|
+
"Seeds",
|
|
109
|
+
"set_global_seed",
|
|
110
|
+
"BOOTSTRAP_OFFSET",
|
|
111
|
+
"REPRESENTATION_OFFSET",
|
|
112
|
+
"INNER_OFFSET",
|
|
113
|
+
"REPEAT_STRIDE",
|
|
114
|
+
# validity
|
|
115
|
+
"InsufficientEvidenceError",
|
|
116
|
+
"MissingnessInformativeWarning",
|
|
117
|
+
"StandardisationStats",
|
|
118
|
+
"as_validity",
|
|
119
|
+
"masked_mean",
|
|
120
|
+
"masked_std",
|
|
121
|
+
"masked_standardise_fit",
|
|
122
|
+
"masked_standardise",
|
|
123
|
+
"renormalised_convolve1d",
|
|
124
|
+
"renormalised_dot",
|
|
125
|
+
"is_contrast_filter",
|
|
126
|
+
"observation_support",
|
|
127
|
+
"missingness_association",
|
|
128
|
+
"fill_zero",
|
|
129
|
+
"fill_mean",
|
|
130
|
+
"fabricated_edge",
|
|
131
|
+
# segments
|
|
132
|
+
"SegmentGrid",
|
|
133
|
+
# masking
|
|
134
|
+
"SoftMaskSelector",
|
|
135
|
+
"renormalised_gated_forward",
|
|
136
|
+
"mask_data_gradient",
|
|
137
|
+
"loss_and_dz",
|
|
138
|
+
# representations
|
|
139
|
+
"SegmentMean",
|
|
140
|
+
"SegmentStats",
|
|
141
|
+
"SavGolDerivative",
|
|
142
|
+
"GaussianScale1D",
|
|
143
|
+
"RandomConv1D",
|
|
144
|
+
"default_ensemble",
|
|
145
|
+
# nested CV and results
|
|
146
|
+
"NestedCV",
|
|
147
|
+
"FoldEstimator",
|
|
148
|
+
"SoftMaskFoldEstimator",
|
|
149
|
+
"BootstrapMaskFoldEstimator",
|
|
150
|
+
"FullSignalFoldEstimator",
|
|
151
|
+
"infer_task",
|
|
152
|
+
"make_outer_splitter",
|
|
153
|
+
"make_inner_splitter",
|
|
154
|
+
"RSMResult",
|
|
155
|
+
# refit model zoo
|
|
156
|
+
"ALGORITHMS",
|
|
157
|
+
"make_refit_model",
|
|
158
|
+
"PLSDA",
|
|
159
|
+
"ExternalRefit",
|
|
160
|
+
"refit_features",
|
|
161
|
+
# selection
|
|
162
|
+
"BootstrapMaskSelector",
|
|
163
|
+
"RepresentationEnsembleSelector",
|
|
164
|
+
"EnsembleMaskFoldEstimator",
|
|
165
|
+
"resample_indices",
|
|
166
|
+
"complementary_pair",
|
|
167
|
+
"observation_groups",
|
|
168
|
+
# tuning
|
|
169
|
+
"lam_frontier",
|
|
170
|
+
"lam_for_coverage",
|
|
171
|
+
# synthetic
|
|
172
|
+
"SignalControl",
|
|
173
|
+
"make_signal_control",
|
|
174
|
+
"mask_scattered",
|
|
175
|
+
"mask_dropout_stretches",
|
|
176
|
+
"mask_band_by_group",
|
|
177
|
+
"mask_saturation_censor",
|
|
178
|
+
"drop_labels",
|
|
179
|
+
# metrics
|
|
180
|
+
"score_predictions",
|
|
181
|
+
"rmse_from_score",
|
|
182
|
+
"jaccard",
|
|
183
|
+
"expected_jaccard",
|
|
184
|
+
"adjusted_jaccard",
|
|
185
|
+
"mean_pairwise_jaccard",
|
|
186
|
+
"BaselineComparison",
|
|
187
|
+
"paired_comparison",
|
|
188
|
+
]
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""Configuration: user-facing knobs with robust defaults, and the fit-cost model.
|
|
2
|
+
|
|
3
|
+
Design constraints (RSM_PLAN.md sec.6):
|
|
4
|
+
* numpy-only: no torch, no device management. RPM's device detection is
|
|
5
|
+
deliberately not ported; every fit is a hand-derived-gradient numpy loop.
|
|
6
|
+
* User-defined where possible with robust defaults: every knob here has a
|
|
7
|
+
sane default. The evidence thresholds are scientific choices adopted with
|
|
8
|
+
the user (RSM_PLAN.md sec.11) and are scheduled for a sensitivity sweep in
|
|
9
|
+
Milestone 8 before being considered final.
|
|
10
|
+
"""
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from dataclasses import dataclass, asdict
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class RSMConfig:
|
|
18
|
+
"""All user-facing knobs with robust defaults.
|
|
19
|
+
|
|
20
|
+
Fields beyond the Milestone-1 scaffold are declared here so the config
|
|
21
|
+
surface is stable as later milestones land (RPM convention).
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
# --- selection unit (sec.2) ---
|
|
25
|
+
segment: int = 16 # points per segment; 1 gives exact point-wise mode
|
|
26
|
+
channel_mode: str = "joint" # joint | per_channel (per_channel is a later extension)
|
|
27
|
+
|
|
28
|
+
# --- cross-validation ---
|
|
29
|
+
k_outer: int = 5
|
|
30
|
+
l_inner: int = 5
|
|
31
|
+
repeated_outer_cv: int = 1
|
|
32
|
+
n_iter: int = 20 # randomized hyperparameter configurations per inner CV
|
|
33
|
+
|
|
34
|
+
# --- stability selection ---
|
|
35
|
+
n_bootstrap: int = 20
|
|
36
|
+
n_representations: int = 4
|
|
37
|
+
tau: float = 0.7 # stability threshold (RMM default)
|
|
38
|
+
lam: float = 0.03 # mask sparsity strength
|
|
39
|
+
subsample: str = "bootstrap" # bootstrap | half | complementary
|
|
40
|
+
|
|
41
|
+
# --- masking / gates ---
|
|
42
|
+
gate: str = "hardconcrete" # hardconcrete | sigmoid
|
|
43
|
+
tv: float = 0.0 # 1D total-variation prior strength (contiguous bands)
|
|
44
|
+
|
|
45
|
+
# --- evidence thresholds (adopted defaults; M8 sensitivity sweep) ---
|
|
46
|
+
min_valid_frac: float = 0.5 # segment observation fraction below which a
|
|
47
|
+
# (sample, segment) feature is ineligible
|
|
48
|
+
rho_min: float = 0.1 # per-sample observed-evidence floor; below it a
|
|
49
|
+
# prediction is nan, never an amplified guess
|
|
50
|
+
o_min: float = 0.1 # per-resample segment support floor for assessability
|
|
51
|
+
a_min: float = 0.5 # fraction of resamples that must assess a segment
|
|
52
|
+
# before pi is reported as a number rather than nan.
|
|
53
|
+
# Measured (FINDINGS sec.10): this binds only when
|
|
54
|
+
# the observation patterns are too varied to group.
|
|
55
|
+
# With groups detected, resampling draws a fixed
|
|
56
|
+
# count per stratum, support is deterministic, and
|
|
57
|
+
# a_min cannot act.
|
|
58
|
+
o_floor: float = 0.2 # floor for observation-scaled sparsity penalty
|
|
59
|
+
n_min_hard: int = 8 # effective sample size below which a segment-channel
|
|
60
|
+
# is unassessable (excluded, reported)
|
|
61
|
+
n_min_warn: int = 30 # effective sample size below which it is flagged
|
|
62
|
+
|
|
63
|
+
# --- missing y ---
|
|
64
|
+
use_unlabelled_stats: bool = False # opt-in: unlabelled TRAINING rows may
|
|
65
|
+
# contribute to X-only statistics
|
|
66
|
+
|
|
67
|
+
# --- execution ---
|
|
68
|
+
n_jobs: int = 1
|
|
69
|
+
random_state: int = 0
|
|
70
|
+
|
|
71
|
+
def to_dict(self) -> dict:
|
|
72
|
+
return asdict(self)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def fit_count(
|
|
76
|
+
k_outer: int,
|
|
77
|
+
repeated_outer_cv: int,
|
|
78
|
+
n_representations: int,
|
|
79
|
+
n_bootstrap: int,
|
|
80
|
+
n_iter: int,
|
|
81
|
+
l_inner: int,
|
|
82
|
+
) -> int:
|
|
83
|
+
"""Total model-fit count (RPM's extension of RMM Eq.3, unchanged for 1D).
|
|
84
|
+
|
|
85
|
+
F = K * R_out * (R_rep * B + n_iter * L + 1) + (R_rep * B + n_iter * L + 1)
|
|
86
|
+
|
|
87
|
+
The trailing term is the final selection + final inner search + final
|
|
88
|
+
refit on all training data. Use this to size runs before launching.
|
|
89
|
+
"""
|
|
90
|
+
per = n_representations * n_bootstrap + n_iter * l_inner + 1
|
|
91
|
+
return k_outer * repeated_outer_cv * per + per
|