bead 0.1.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.
- bead/__init__.py +11 -0
- bead/__main__.py +11 -0
- bead/active_learning/__init__.py +15 -0
- bead/active_learning/config.py +231 -0
- bead/active_learning/loop.py +566 -0
- bead/active_learning/models/__init__.py +24 -0
- bead/active_learning/models/base.py +852 -0
- bead/active_learning/models/binary.py +910 -0
- bead/active_learning/models/categorical.py +943 -0
- bead/active_learning/models/cloze.py +862 -0
- bead/active_learning/models/forced_choice.py +956 -0
- bead/active_learning/models/free_text.py +773 -0
- bead/active_learning/models/lora.py +365 -0
- bead/active_learning/models/magnitude.py +835 -0
- bead/active_learning/models/multi_select.py +795 -0
- bead/active_learning/models/ordinal_scale.py +811 -0
- bead/active_learning/models/peft_adapter.py +155 -0
- bead/active_learning/models/random_effects.py +639 -0
- bead/active_learning/selection.py +354 -0
- bead/active_learning/strategies.py +391 -0
- bead/active_learning/trainers/__init__.py +26 -0
- bead/active_learning/trainers/base.py +210 -0
- bead/active_learning/trainers/data_collator.py +172 -0
- bead/active_learning/trainers/dataset_utils.py +261 -0
- bead/active_learning/trainers/huggingface.py +304 -0
- bead/active_learning/trainers/lightning.py +324 -0
- bead/active_learning/trainers/metrics.py +424 -0
- bead/active_learning/trainers/mixed_effects.py +551 -0
- bead/active_learning/trainers/model_wrapper.py +509 -0
- bead/active_learning/trainers/registry.py +104 -0
- bead/adapters/__init__.py +11 -0
- bead/adapters/huggingface.py +61 -0
- bead/behavioral/__init__.py +116 -0
- bead/behavioral/analytics.py +646 -0
- bead/behavioral/extraction.py +343 -0
- bead/behavioral/merging.py +343 -0
- bead/cli/__init__.py +11 -0
- bead/cli/active_learning.py +513 -0
- bead/cli/active_learning_commands.py +779 -0
- bead/cli/completion.py +359 -0
- bead/cli/config.py +624 -0
- bead/cli/constraint_builders.py +286 -0
- bead/cli/deployment.py +859 -0
- bead/cli/deployment_trials.py +493 -0
- bead/cli/deployment_ui.py +332 -0
- bead/cli/display.py +378 -0
- bead/cli/items.py +960 -0
- bead/cli/items_factories.py +776 -0
- bead/cli/list_constraints.py +714 -0
- bead/cli/lists.py +490 -0
- bead/cli/main.py +430 -0
- bead/cli/models.py +877 -0
- bead/cli/resource_loaders.py +621 -0
- bead/cli/resources.py +1036 -0
- bead/cli/shell.py +356 -0
- bead/cli/simulate.py +840 -0
- bead/cli/templates.py +1158 -0
- bead/cli/training.py +1080 -0
- bead/cli/utils.py +614 -0
- bead/cli/workflow.py +1273 -0
- bead/config/__init__.py +68 -0
- bead/config/active_learning.py +1009 -0
- bead/config/config.py +192 -0
- bead/config/defaults.py +118 -0
- bead/config/deployment.py +217 -0
- bead/config/env.py +147 -0
- bead/config/item.py +45 -0
- bead/config/list.py +193 -0
- bead/config/loader.py +149 -0
- bead/config/logging.py +42 -0
- bead/config/model.py +49 -0
- bead/config/paths.py +46 -0
- bead/config/profiles.py +320 -0
- bead/config/resources.py +47 -0
- bead/config/serialization.py +210 -0
- bead/config/simulation.py +206 -0
- bead/config/template.py +238 -0
- bead/config/validation.py +267 -0
- bead/data/__init__.py +65 -0
- bead/data/base.py +87 -0
- bead/data/identifiers.py +97 -0
- bead/data/language_codes.py +61 -0
- bead/data/metadata.py +270 -0
- bead/data/range.py +123 -0
- bead/data/repository.py +358 -0
- bead/data/serialization.py +249 -0
- bead/data/timestamps.py +89 -0
- bead/data/validation.py +349 -0
- bead/data_collection/__init__.py +11 -0
- bead/data_collection/jatos.py +223 -0
- bead/data_collection/merger.py +154 -0
- bead/data_collection/prolific.py +198 -0
- bead/deployment/__init__.py +5 -0
- bead/deployment/distribution.py +402 -0
- bead/deployment/jatos/__init__.py +1 -0
- bead/deployment/jatos/api.py +200 -0
- bead/deployment/jatos/exporter.py +210 -0
- bead/deployment/jspsych/__init__.py +9 -0
- bead/deployment/jspsych/biome.json +44 -0
- bead/deployment/jspsych/config.py +411 -0
- bead/deployment/jspsych/generator.py +598 -0
- bead/deployment/jspsych/package.json +51 -0
- bead/deployment/jspsych/pnpm-lock.yaml +2141 -0
- bead/deployment/jspsych/randomizer.py +299 -0
- bead/deployment/jspsych/src/lib/list-distributor.test.ts +327 -0
- bead/deployment/jspsych/src/lib/list-distributor.ts +1282 -0
- bead/deployment/jspsych/src/lib/randomizer.test.ts +232 -0
- bead/deployment/jspsych/src/lib/randomizer.ts +367 -0
- bead/deployment/jspsych/src/plugins/cloze-dropdown.ts +252 -0
- bead/deployment/jspsych/src/plugins/forced-choice.ts +265 -0
- bead/deployment/jspsych/src/plugins/plugins.test.ts +141 -0
- bead/deployment/jspsych/src/plugins/rating.ts +248 -0
- bead/deployment/jspsych/src/slopit/index.ts +9 -0
- bead/deployment/jspsych/src/types/jatos.d.ts +256 -0
- bead/deployment/jspsych/src/types/jspsych.d.ts +228 -0
- bead/deployment/jspsych/templates/experiment.css +1 -0
- bead/deployment/jspsych/templates/experiment.js.template +289 -0
- bead/deployment/jspsych/templates/index.html +51 -0
- bead/deployment/jspsych/templates/randomizer.js +241 -0
- bead/deployment/jspsych/templates/randomizer.js.template +313 -0
- bead/deployment/jspsych/trials.py +723 -0
- bead/deployment/jspsych/tsconfig.json +23 -0
- bead/deployment/jspsych/tsup.config.ts +30 -0
- bead/deployment/jspsych/ui/__init__.py +1 -0
- bead/deployment/jspsych/ui/components.py +383 -0
- bead/deployment/jspsych/ui/styles.py +411 -0
- bead/dsl/__init__.py +80 -0
- bead/dsl/ast.py +168 -0
- bead/dsl/context.py +178 -0
- bead/dsl/errors.py +71 -0
- bead/dsl/evaluator.py +570 -0
- bead/dsl/grammar.lark +81 -0
- bead/dsl/parser.py +231 -0
- bead/dsl/stdlib.py +929 -0
- bead/evaluation/__init__.py +13 -0
- bead/evaluation/convergence.py +485 -0
- bead/evaluation/interannotator.py +398 -0
- bead/items/__init__.py +40 -0
- bead/items/adapters/__init__.py +70 -0
- bead/items/adapters/anthropic.py +224 -0
- bead/items/adapters/api_utils.py +167 -0
- bead/items/adapters/base.py +216 -0
- bead/items/adapters/google.py +259 -0
- bead/items/adapters/huggingface.py +1074 -0
- bead/items/adapters/openai.py +323 -0
- bead/items/adapters/registry.py +202 -0
- bead/items/adapters/sentence_transformers.py +224 -0
- bead/items/adapters/togetherai.py +309 -0
- bead/items/binary.py +515 -0
- bead/items/cache.py +558 -0
- bead/items/categorical.py +593 -0
- bead/items/cloze.py +757 -0
- bead/items/constructor.py +784 -0
- bead/items/forced_choice.py +413 -0
- bead/items/free_text.py +681 -0
- bead/items/generation.py +432 -0
- bead/items/item.py +396 -0
- bead/items/item_template.py +787 -0
- bead/items/magnitude.py +573 -0
- bead/items/multi_select.py +621 -0
- bead/items/ordinal_scale.py +569 -0
- bead/items/scoring.py +448 -0
- bead/items/validation.py +723 -0
- bead/lists/__init__.py +30 -0
- bead/lists/balancer.py +263 -0
- bead/lists/constraints.py +1067 -0
- bead/lists/experiment_list.py +286 -0
- bead/lists/list_collection.py +378 -0
- bead/lists/partitioner.py +1141 -0
- bead/lists/stratification.py +254 -0
- bead/participants/__init__.py +73 -0
- bead/participants/collection.py +699 -0
- bead/participants/merging.py +312 -0
- bead/participants/metadata_spec.py +491 -0
- bead/participants/models.py +276 -0
- bead/resources/__init__.py +29 -0
- bead/resources/adapters/__init__.py +19 -0
- bead/resources/adapters/base.py +104 -0
- bead/resources/adapters/cache.py +128 -0
- bead/resources/adapters/glazing.py +508 -0
- bead/resources/adapters/registry.py +117 -0
- bead/resources/adapters/unimorph.py +796 -0
- bead/resources/classification.py +856 -0
- bead/resources/constraint_builders.py +329 -0
- bead/resources/constraints.py +165 -0
- bead/resources/lexical_item.py +223 -0
- bead/resources/lexicon.py +744 -0
- bead/resources/loaders.py +209 -0
- bead/resources/template.py +441 -0
- bead/resources/template_collection.py +707 -0
- bead/resources/template_generation.py +349 -0
- bead/simulation/__init__.py +29 -0
- bead/simulation/annotators/__init__.py +15 -0
- bead/simulation/annotators/base.py +175 -0
- bead/simulation/annotators/distance_based.py +135 -0
- bead/simulation/annotators/lm_based.py +114 -0
- bead/simulation/annotators/oracle.py +182 -0
- bead/simulation/annotators/random.py +181 -0
- bead/simulation/dsl_extension/__init__.py +3 -0
- bead/simulation/noise_models/__init__.py +13 -0
- bead/simulation/noise_models/base.py +42 -0
- bead/simulation/noise_models/random_noise.py +82 -0
- bead/simulation/noise_models/systematic.py +132 -0
- bead/simulation/noise_models/temperature.py +86 -0
- bead/simulation/runner.py +144 -0
- bead/simulation/strategies/__init__.py +23 -0
- bead/simulation/strategies/base.py +123 -0
- bead/simulation/strategies/binary.py +103 -0
- bead/simulation/strategies/categorical.py +123 -0
- bead/simulation/strategies/cloze.py +224 -0
- bead/simulation/strategies/forced_choice.py +127 -0
- bead/simulation/strategies/free_text.py +105 -0
- bead/simulation/strategies/magnitude.py +116 -0
- bead/simulation/strategies/multi_select.py +129 -0
- bead/simulation/strategies/ordinal_scale.py +131 -0
- bead/templates/__init__.py +27 -0
- bead/templates/adapters/__init__.py +17 -0
- bead/templates/adapters/base.py +128 -0
- bead/templates/adapters/cache.py +178 -0
- bead/templates/adapters/huggingface.py +312 -0
- bead/templates/combinatorics.py +103 -0
- bead/templates/filler.py +605 -0
- bead/templates/renderers.py +177 -0
- bead/templates/resolver.py +178 -0
- bead/templates/strategies.py +1806 -0
- bead/templates/streaming.py +195 -0
- bead-0.1.0.dist-info/METADATA +212 -0
- bead-0.1.0.dist-info/RECORD +231 -0
- bead-0.1.0.dist-info/WHEEL +4 -0
- bead-0.1.0.dist-info/entry_points.txt +2 -0
- bead-0.1.0.dist-info/licenses/LICENSE +21 -0
bead/__init__.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Python framework for constructing, deploying, and analyzing large-scale experiments.
|
|
2
|
+
|
|
3
|
+
This framework implements a 6-stage pipeline with active learning support for
|
|
4
|
+
designing and deploying linguistic judgment experiments at scale.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
__version__ = "0.1.0"
|
|
10
|
+
__author__ = "Aaron Steven White"
|
|
11
|
+
__email__ = "aaron.white@rochester.edu"
|
bead/__main__.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""Active learning infrastructure for model training and item selection."""
|
|
2
|
+
|
|
3
|
+
from bead.active_learning.loop import ActiveLearningLoop
|
|
4
|
+
from bead.active_learning.selection import (
|
|
5
|
+
ItemSelector,
|
|
6
|
+
RandomSelector,
|
|
7
|
+
UncertaintySampler,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"ActiveLearningLoop",
|
|
12
|
+
"ItemSelector",
|
|
13
|
+
"RandomSelector",
|
|
14
|
+
"UncertaintySampler",
|
|
15
|
+
]
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"""Configuration models for mixed effects active learning.
|
|
2
|
+
|
|
3
|
+
Separated from base.py to avoid circular imports.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from typing import Literal
|
|
9
|
+
|
|
10
|
+
from pydantic import BaseModel, Field
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"VarianceComponents",
|
|
14
|
+
"RandomEffectsSpec",
|
|
15
|
+
"MixedEffectsConfig",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class VarianceComponents(BaseModel):
|
|
20
|
+
"""Variance-covariance structure for random effects (G matrix in GLMM theory).
|
|
21
|
+
|
|
22
|
+
Tracks estimated variances for random effects, enabling:
|
|
23
|
+
- Shrinkage estimation (groups with few samples → prior mean)
|
|
24
|
+
- Model diagnostics (proportion of variance explained by random effects)
|
|
25
|
+
- Uncertainty quantification
|
|
26
|
+
|
|
27
|
+
In GLMM notation: u ~ N(0, G), where G is the variance-covariance matrix.
|
|
28
|
+
For random intercepts, G is diagonal with entries σ²_u.
|
|
29
|
+
For random slopes, G can be full (correlated) or diagonal (independent).
|
|
30
|
+
|
|
31
|
+
Attributes
|
|
32
|
+
----------
|
|
33
|
+
grouping_factor : str
|
|
34
|
+
Name of grouping factor (e.g., "participant", "item", "lab").
|
|
35
|
+
effect_type : Literal["intercept", "slope"]
|
|
36
|
+
Type of random effect.
|
|
37
|
+
variance : float
|
|
38
|
+
Estimated variance σ² for this random effect.
|
|
39
|
+
Higher values indicate more heterogeneity across groups.
|
|
40
|
+
n_groups : int
|
|
41
|
+
Number of groups (e.g., 50 participants).
|
|
42
|
+
n_observations_per_group : dict[str, int]
|
|
43
|
+
Number of observations per group.
|
|
44
|
+
Used for adaptive regularization and shrinkage.
|
|
45
|
+
|
|
46
|
+
Examples
|
|
47
|
+
--------
|
|
48
|
+
>>> vc = VarianceComponents(
|
|
49
|
+
... grouping_factor="participant",
|
|
50
|
+
... effect_type="intercept",
|
|
51
|
+
... variance=0.25,
|
|
52
|
+
... n_groups=50,
|
|
53
|
+
... n_observations_per_group={"p1": 10, "p2": 15}
|
|
54
|
+
... )
|
|
55
|
+
>>> vc.variance
|
|
56
|
+
0.25
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
grouping_factor: str = Field(description="Grouping factor name")
|
|
60
|
+
effect_type: Literal["intercept", "slope"] = Field(
|
|
61
|
+
description="Type of random effect"
|
|
62
|
+
)
|
|
63
|
+
variance: float = Field(
|
|
64
|
+
ge=0.0, description="Estimated variance for this random effect"
|
|
65
|
+
)
|
|
66
|
+
n_groups: int = Field(ge=1, description="Number of groups")
|
|
67
|
+
n_observations_per_group: dict[str, int] = Field(
|
|
68
|
+
description="Observations per group"
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class RandomEffectsSpec(BaseModel):
|
|
73
|
+
"""Specification of random effects structure.
|
|
74
|
+
|
|
75
|
+
Inspired by lme4 formula notation: (expr | factor).
|
|
76
|
+
|
|
77
|
+
Phase 5 (current): Supports single grouping factor (participant).
|
|
78
|
+
Future phases: Multiple factors, crossed/nested structure.
|
|
79
|
+
|
|
80
|
+
Attributes
|
|
81
|
+
----------
|
|
82
|
+
grouping_factors : dict[str, Literal["intercept", "slope", "both"]]
|
|
83
|
+
Mapping from grouping factor name to effect type.
|
|
84
|
+
Phase 5: {"participant": "intercept"} or {"participant": "slope"}
|
|
85
|
+
Future: {"participant": "intercept", "item": "intercept"}
|
|
86
|
+
correlation_structure : Literal["independent", "correlated"]
|
|
87
|
+
If "both" specified: whether intercept and slope are correlated.
|
|
88
|
+
Independent: G is diagonal.
|
|
89
|
+
Correlated: G has off-diagonal covariances.
|
|
90
|
+
|
|
91
|
+
Examples
|
|
92
|
+
--------
|
|
93
|
+
>>> # Random intercepts for participants
|
|
94
|
+
>>> spec = RandomEffectsSpec(
|
|
95
|
+
... grouping_factors={"participant": "intercept"}
|
|
96
|
+
... )
|
|
97
|
+
|
|
98
|
+
>>> # Random slopes for participants
|
|
99
|
+
>>> spec = RandomEffectsSpec(
|
|
100
|
+
... grouping_factors={"participant": "slope"}
|
|
101
|
+
... )
|
|
102
|
+
|
|
103
|
+
>>> # Future: Multiple grouping factors
|
|
104
|
+
>>> spec = RandomEffectsSpec(
|
|
105
|
+
... grouping_factors={"participant": "intercept", "item": "intercept"}
|
|
106
|
+
... )
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
grouping_factors: dict[str, Literal["intercept", "slope", "both"]] = Field(
|
|
110
|
+
description="Grouping factors and their random effect types"
|
|
111
|
+
)
|
|
112
|
+
correlation_structure: Literal["independent", "correlated"] = Field(
|
|
113
|
+
default="independent",
|
|
114
|
+
description="Correlation structure for 'both' case",
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class MixedEffectsConfig(BaseModel):
|
|
119
|
+
"""Configuration for mixed effects modeling in active learning.
|
|
120
|
+
|
|
121
|
+
Based on GLMM theory: y = Xβ + Zu + ε
|
|
122
|
+
|
|
123
|
+
Where:
|
|
124
|
+
- Xβ: Fixed effects (population-level parameters, shared across all groups)
|
|
125
|
+
- Zu: Random effects (group-specific parameters, e.g., per-participant)
|
|
126
|
+
- u ~ N(0, G): Random effects with variance-covariance matrix G
|
|
127
|
+
- ε ~ N(0, σ²): Residuals
|
|
128
|
+
|
|
129
|
+
Attributes
|
|
130
|
+
----------
|
|
131
|
+
mode : Literal['fixed', 'random_intercepts', 'random_slopes']
|
|
132
|
+
Modeling mode:
|
|
133
|
+
- 'fixed': Standard model, no group-specific parameters (Z = 0)
|
|
134
|
+
- 'random_intercepts': Per-group biases (Z = I, u = bias vectors)
|
|
135
|
+
- 'random_slopes': Per-group model parameters (Z = I, u = full model heads)
|
|
136
|
+
prior_mean : float
|
|
137
|
+
Mean μ₀ of Gaussian prior for random effects initialization.
|
|
138
|
+
Random effects initialized from N(μ₀, σ²₀).
|
|
139
|
+
prior_variance : float
|
|
140
|
+
Variance σ²₀ of Gaussian prior for random effects initialization.
|
|
141
|
+
Controls initial spread of random effects.
|
|
142
|
+
estimate_variance_components : bool
|
|
143
|
+
Whether to estimate variance components (G matrix) during training.
|
|
144
|
+
If True, returns variance estimates in training metrics.
|
|
145
|
+
variance_estimation_method : Literal["mle", "reml"]
|
|
146
|
+
Method for variance component estimation:
|
|
147
|
+
- 'mle': Maximum Likelihood Estimation
|
|
148
|
+
- 'reml': Restricted Maximum Likelihood (adjusts for fixed effects)
|
|
149
|
+
regularization_strength : float
|
|
150
|
+
Strength λ of regularization pulling random effects toward prior.
|
|
151
|
+
Loss: L_total = L_data + λ * ||u - μ₀||²
|
|
152
|
+
adaptive_regularization : bool
|
|
153
|
+
If True, use stronger regularization for groups with fewer samples.
|
|
154
|
+
Weight: w_g = 1 / max(n_g, min_samples_for_random_effects)
|
|
155
|
+
min_samples_for_random_effects : int
|
|
156
|
+
Minimum samples before estimating group-specific random effects.
|
|
157
|
+
Below threshold: use prior mean for predictions (shrinkage).
|
|
158
|
+
random_effects_spec : RandomEffectsSpec | None
|
|
159
|
+
Advanced: Specification for multiple grouping factors.
|
|
160
|
+
If None: infer from mode (backward compatibility).
|
|
161
|
+
Future: Enable item random effects, crossed effects, etc.
|
|
162
|
+
|
|
163
|
+
Examples
|
|
164
|
+
--------
|
|
165
|
+
>>> # Fixed effects (standard model)
|
|
166
|
+
>>> config = MixedEffectsConfig(mode='fixed')
|
|
167
|
+
|
|
168
|
+
>>> # Random intercepts (participant biases)
|
|
169
|
+
>>> config = MixedEffectsConfig(
|
|
170
|
+
... mode='random_intercepts',
|
|
171
|
+
... prior_mean=0.0,
|
|
172
|
+
... prior_variance=1.0,
|
|
173
|
+
... regularization_strength=0.01
|
|
174
|
+
... )
|
|
175
|
+
|
|
176
|
+
>>> # Random slopes (participant-specific models)
|
|
177
|
+
>>> config = MixedEffectsConfig(
|
|
178
|
+
... mode='random_slopes',
|
|
179
|
+
... prior_variance=0.1,
|
|
180
|
+
... adaptive_regularization=True
|
|
181
|
+
... )
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
mode: Literal["fixed", "random_intercepts", "random_slopes"] = Field(
|
|
185
|
+
default="fixed",
|
|
186
|
+
description="Modeling mode: fixed, random_intercepts, or random_slopes",
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
# Prior hyperparameters (for initialization)
|
|
190
|
+
prior_mean: float = Field(
|
|
191
|
+
default=0.0, description="Mean of Gaussian prior for random effects"
|
|
192
|
+
)
|
|
193
|
+
prior_variance: float = Field(
|
|
194
|
+
default=1.0,
|
|
195
|
+
ge=0.0,
|
|
196
|
+
description="Variance of Gaussian prior for random effects (must be >= 0)",
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
# Variance component estimation
|
|
200
|
+
estimate_variance_components: bool = Field(
|
|
201
|
+
default=True,
|
|
202
|
+
description=(
|
|
203
|
+
"Whether to estimate variance components (G matrix) during training"
|
|
204
|
+
),
|
|
205
|
+
)
|
|
206
|
+
variance_estimation_method: Literal["mle", "reml"] = Field(
|
|
207
|
+
default="mle",
|
|
208
|
+
description="Method for variance component estimation: mle or reml",
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
# Regularization (pulls random effects toward prior)
|
|
212
|
+
regularization_strength: float = Field(
|
|
213
|
+
default=0.01,
|
|
214
|
+
ge=0.0,
|
|
215
|
+
description="Strength of regularization toward prior (must be >= 0)",
|
|
216
|
+
)
|
|
217
|
+
adaptive_regularization: bool = Field(
|
|
218
|
+
default=True,
|
|
219
|
+
description="Use stronger regularization for groups with fewer samples",
|
|
220
|
+
)
|
|
221
|
+
min_samples_for_random_effects: int = Field(
|
|
222
|
+
default=5,
|
|
223
|
+
ge=1,
|
|
224
|
+
description="Minimum samples before using random effects (must be >= 1)",
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
# Extensibility (Phase 6+)
|
|
228
|
+
random_effects_spec: RandomEffectsSpec | None = Field(
|
|
229
|
+
default=None,
|
|
230
|
+
description="Advanced: specification for multiple grouping factors (Phase 6+)",
|
|
231
|
+
)
|