sklears_ensemble/stacking/
config.rs

1//! Configuration types for stacking ensemble methods
2//!
3//! This module provides configuration structures and enums for all stacking
4//! ensemble variants including simple stacking, blending, and multi-layer stacking.
5
6use sklears_core::types::Float;
7
8/// Stacking Classifier Configuration
9#[derive(Debug, Clone)]
10pub struct StackingConfig {
11    /// Number of folds for cross-validation
12    pub cv: usize,
13    /// Whether to use cross-validation predictions as features
14    pub use_probabilities: bool,
15    /// Random seed for cross-validation
16    pub random_state: Option<u64>,
17    /// Whether to fit the base estimators on the full dataset
18    pub passthrough: bool,
19}
20
21impl Default for StackingConfig {
22    fn default() -> Self {
23        Self {
24            cv: 5,
25            use_probabilities: false,
26            random_state: None,
27            passthrough: false,
28        }
29    }
30}
31
32/// Meta-learning strategies for combining predictions
33#[derive(Debug, Clone, Copy, PartialEq)]
34pub enum MetaLearningStrategy {
35    /// Simple linear regression (default)
36    LinearRegression,
37    /// Ridge regression with L2 regularization
38    Ridge(Float),
39    /// Lasso regression with L1 regularization
40    Lasso(Float),
41    /// Elastic net with combined L1/L2 regularization
42    ElasticNet(Float, Float),
43    /// Logistic regression for classification
44    LogisticRegression,
45    /// Support Vector Machine
46    SVM,
47    /// Neural network meta-learner
48    NeuralNetwork,
49    /// Bayesian averaging
50    BayesianAveraging,
51}
52
53/// Advanced meta-feature engineering strategies
54#[derive(Debug, Clone, PartialEq)]
55pub enum MetaFeatureStrategy {
56    /// Raw predictions only (default)
57    Raw,
58    /// Include statistical transformations (mean, std, skew, etc.)
59    Statistical,
60    /// Include pairwise interactions between predictions
61    Interactions,
62    /// Include confidence-based features
63    ConfidenceBased,
64    /// Include diversity measures between base learners
65    DiversityBased,
66    /// Comprehensive feature engineering (all of the above)
67    Comprehensive,
68    /// Temporal features for time-series data
69    Temporal,
70    /// Spatial features for geographic data
71    Spatial,
72    /// Spectral features using FFT and wavelets
73    Spectral,
74    /// Information-theoretic features (mutual information, entropy)
75    InformationTheoretic,
76    /// Neural embedding features
77    NeuralEmbedding,
78    /// Kernel-based features
79    KernelBased,
80    /// Advanced polynomial and basis expansions
81    BasisExpansion,
82    /// Meta-learning features
83    MetaLearning,
84}
85
86impl Default for MetaFeatureStrategy {
87    fn default() -> Self {
88        Self::Raw
89    }
90}
91
92/// Configuration for a single stacking layer
93#[derive(Debug, Clone)]
94pub struct StackingLayerConfig {
95    /// Number of base estimators in this layer
96    pub n_estimators: usize,
97    /// Meta-learning strategy for this layer
98    pub meta_strategy: MetaLearningStrategy,
99    /// Whether to use probability outputs instead of predictions
100    pub use_probabilities: bool,
101    /// Cross-validation folds for this layer
102    pub cv_folds: usize,
103    /// Whether to include original features in meta-features
104    pub passthrough: bool,
105    /// L2 regularization strength for meta-learner
106    pub meta_regularization: Float,
107    /// Meta-feature engineering strategy
108    pub meta_feature_strategy: MetaFeatureStrategy,
109    /// Enable polynomial feature generation
110    pub polynomial_features: bool,
111    /// Polynomial degree for feature generation
112    pub polynomial_degree: usize,
113}
114
115impl Default for StackingLayerConfig {
116    fn default() -> Self {
117        Self {
118            n_estimators: 5,
119            meta_strategy: MetaLearningStrategy::LinearRegression,
120            use_probabilities: false,
121            cv_folds: 5,
122            passthrough: false,
123            meta_regularization: 0.1,
124            meta_feature_strategy: MetaFeatureStrategy::Raw,
125            polynomial_features: false,
126            polynomial_degree: 2,
127        }
128    }
129}
130
131/// Multi-layer stacking configuration
132#[derive(Debug, Clone)]
133pub struct MultiLayerStackingConfig {
134    /// Configuration for each stacking layer
135    pub layers: Vec<StackingLayerConfig>,
136    /// Random seed for reproducibility
137    pub random_state: Option<u64>,
138    /// Final meta-learner strategy
139    pub final_meta_strategy: MetaLearningStrategy,
140    /// Whether to use ensemble pruning
141    pub enable_pruning: bool,
142    /// Diversity threshold for ensemble pruning
143    pub diversity_threshold: Float,
144    /// Confidence-based weighting
145    pub confidence_weighting: bool,
146}
147
148impl MultiLayerStackingConfig {
149    pub fn new() -> Self {
150        Self {
151            layers: vec![StackingLayerConfig::default()],
152            random_state: None,
153            final_meta_strategy: MetaLearningStrategy::LogisticRegression,
154            enable_pruning: false,
155            diversity_threshold: 0.1,
156            confidence_weighting: false,
157        }
158    }
159
160    /// Add a layer to the configuration
161    pub fn add_layer(mut self, layer_config: StackingLayerConfig) -> Self {
162        self.layers.push(layer_config);
163        self
164    }
165
166    /// Set the final meta-learning strategy
167    pub fn final_meta_strategy(mut self, strategy: MetaLearningStrategy) -> Self {
168        self.final_meta_strategy = strategy;
169        self
170    }
171
172    /// Enable ensemble pruning
173    pub fn enable_pruning(mut self, enable: bool) -> Self {
174        self.enable_pruning = enable;
175        self
176    }
177
178    /// Set diversity threshold for pruning
179    pub fn diversity_threshold(mut self, threshold: Float) -> Self {
180        self.diversity_threshold = threshold;
181        self
182    }
183
184    /// Enable confidence-based weighting
185    pub fn confidence_weighting(mut self, enable: bool) -> Self {
186        self.confidence_weighting = enable;
187        self
188    }
189
190    /// Set random state for reproducibility
191    pub fn random_state(mut self, seed: u64) -> Self {
192        self.random_state = Some(seed);
193        self
194    }
195
196    /// Create a deep stacking configuration with multiple layers
197    pub fn deep_stacking(n_layers: usize, estimators_per_layer: usize) -> Self {
198        let mut config = Self::new();
199        config.layers.clear();
200
201        for i in 0..n_layers {
202            let layer_config = StackingLayerConfig {
203                n_estimators: estimators_per_layer,
204                meta_strategy: if i == 0 {
205                    MetaLearningStrategy::Ridge(0.1)
206                } else {
207                    MetaLearningStrategy::ElasticNet(0.1, 0.1)
208                },
209                use_probabilities: i > 0, // Use probabilities in higher layers
210                cv_folds: 5,
211                passthrough: i == 0, // Only pass through features in first layer
212                meta_regularization: 0.1 * (i + 1) as Float, // Increase regularization in higher layers
213                meta_feature_strategy: if i == 0 {
214                    MetaFeatureStrategy::Statistical
215                } else {
216                    MetaFeatureStrategy::Comprehensive
217                },
218                polynomial_features: i > 0, // Enable polynomial features in higher layers
219                polynomial_degree: 2,
220            };
221            config.layers.push(layer_config);
222        }
223
224        config.final_meta_strategy = MetaLearningStrategy::BayesianAveraging;
225        config.enable_pruning = true;
226        config.diversity_threshold = 0.15;
227        config.confidence_weighting = true;
228        config
229    }
230
231    /// Create a configuration with advanced meta-feature engineering
232    pub fn with_meta_feature_engineering() -> Self {
233        let mut config = Self::new();
234        config.layers[0].meta_feature_strategy = MetaFeatureStrategy::Comprehensive;
235        config.layers[0].polynomial_features = true;
236        config.layers[0].polynomial_degree = 2;
237        config
238    }
239
240    /// Create a configuration optimized for statistical meta-features
241    pub fn with_statistical_features() -> Self {
242        let mut config = Self::new();
243        config.layers[0].meta_feature_strategy = MetaFeatureStrategy::Statistical;
244        config.confidence_weighting = true;
245        config
246    }
247
248    /// Create a configuration with interaction-based meta-features
249    pub fn with_interaction_features() -> Self {
250        let mut config = Self::new();
251        config.layers[0].meta_feature_strategy = MetaFeatureStrategy::Interactions;
252        config.layers[0].polynomial_features = true;
253        config.layers[0].polynomial_degree = 3;
254        config
255    }
256
257    /// Create a configuration with diversity-based meta-features
258    pub fn with_diversity_features() -> Self {
259        let mut config = Self::new();
260        config.layers[0].meta_feature_strategy = MetaFeatureStrategy::DiversityBased;
261        config.enable_pruning = true;
262        config.diversity_threshold = 0.1;
263        config
264    }
265}
266
267impl Default for MultiLayerStackingConfig {
268    fn default() -> Self {
269        Self::new()
270    }
271}
272
273// Type aliases for the trait bounds (placeholder for now)
274pub trait BaseEstimator {}
275pub trait MetaEstimator {}