use super::automl_core::{AutoMLMethod, DataCharacteristics, TargetType};
use sklears_core::error::Result as SklResult;
type Result<T> = SklResult<T>;
#[derive(Debug, Clone)]
pub struct MethodSelector;
impl MethodSelector {
pub fn new() -> Self {
Self
}
pub fn select_methods(
&self,
characteristics: &DataCharacteristics,
) -> Result<Vec<AutoMLMethod>> {
let mut selected_methods = Vec::new();
match characteristics.target_type {
TargetType::BinaryClassification | TargetType::MultiClassification => {
selected_methods.push(AutoMLMethod::UnivariateFiltering);
if characteristics.n_features > 100 {
selected_methods.push(AutoMLMethod::LassoBased);
}
if characteristics.computational_budget.allow_complex_methods {
selected_methods.push(AutoMLMethod::TreeBased);
}
}
TargetType::Regression => {
selected_methods.push(AutoMLMethod::CorrelationBased);
if characteristics.n_features > 50 {
selected_methods.push(AutoMLMethod::LassoBased);
}
if characteristics.computational_budget.allow_complex_methods {
selected_methods.push(AutoMLMethod::WrapperBased);
}
}
TargetType::MultiLabel => {
selected_methods.push(AutoMLMethod::UnivariateFiltering);
selected_methods.push(AutoMLMethod::EnsembleBased);
}
TargetType::Survival => {
selected_methods.push(AutoMLMethod::UnivariateFiltering);
selected_methods.push(AutoMLMethod::CorrelationBased);
}
}
if characteristics.correlation_structure.high_correlation_pairs
> characteristics.n_features / 4
&& !selected_methods.contains(&AutoMLMethod::CorrelationBased)
{
selected_methods.push(AutoMLMethod::CorrelationBased);
}
if characteristics.feature_to_sample_ratio > 0.5
&& characteristics.computational_budget.allow_complex_methods
{
selected_methods.push(AutoMLMethod::EnsembleBased);
}
if characteristics.n_features > 1000 && characteristics.n_samples > 1000 {
selected_methods.push(AutoMLMethod::Hybrid);
}
if characteristics.feature_to_sample_ratio > 2.0
&& characteristics.computational_budget.allow_complex_methods
&& !characteristics.computational_budget.prefer_speed
{
selected_methods.push(AutoMLMethod::NeuralArchitectureSearch);
}
if characteristics.n_features > 100
&& characteristics.n_samples >= 500
&& characteristics.computational_budget.allow_complex_methods
{
selected_methods.push(AutoMLMethod::TransferLearning);
}
if characteristics.n_features > 50
&& characteristics.n_samples > 200
&& characteristics.computational_budget.allow_complex_methods
&& selected_methods.len() >= 2
{
selected_methods.push(AutoMLMethod::MetaLearningEnsemble);
}
if selected_methods.is_empty() {
selected_methods.push(AutoMLMethod::UnivariateFiltering);
}
Ok(selected_methods)
}
}
impl Default for MethodSelector {
fn default() -> Self {
Self::new()
}
}