Skip to main content

sklears_feature_selection/genetic_optimization/
costsensitiveobjective_traits.rs

1//! # CostSensitiveObjective - Trait Implementations
2//!
3//! This module contains trait implementations for `CostSensitiveObjective`.
4//!
5//! ## Implemented Traits
6//!
7//! - `ObjectiveFunction`
8//!
9//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
10
11use super::functions::*;
12use super::types::*;
13use scirs2_core::ndarray::{Array1, Array2};
14use sklears_core::error::{Result as SklResult, SklearsError};
15
16impl ObjectiveFunction for CostSensitiveObjective {
17    fn evaluate(
18        &self,
19        x: &Array2<f64>,
20        y_classif: Option<&Array1<i32>>,
21        y_regression: Option<&Array1<f64>>,
22        feature_mask: &[bool],
23    ) -> SklResult<f64> {
24        let selected_indices: Vec<usize> = feature_mask
25            .iter()
26            .enumerate()
27            .filter_map(|(i, &selected)| if selected { Some(i) } else { None })
28            .collect();
29        if selected_indices.is_empty() {
30            return Ok(0.0);
31        }
32        let total_cost: f64 = selected_indices
33            .iter()
34            .map(|&idx| self.feature_costs[idx])
35            .sum();
36        let max_cost: f64 = self.feature_costs.sum();
37        let normalized_cost = if max_cost > 0.0 {
38            total_cost / max_cost
39        } else {
40            0.0
41        };
42        let mut total_performance = 0.0;
43        if let Some(y) = y_classif {
44            for &idx in &selected_indices {
45                let feature = x.column(idx).to_owned();
46                let y_float = y.mapv(|v| v as f64);
47                let correlation = compute_pearson_correlation(&feature, &y_float).abs();
48                total_performance += correlation;
49            }
50        } else if let Some(y) = y_regression {
51            for &idx in &selected_indices {
52                let feature = x.column(idx).to_owned();
53                let correlation = compute_pearson_correlation(&feature, y).abs();
54                total_performance += correlation;
55            }
56        } else {
57            return Err(SklearsError::InvalidInput(
58                "Need either classification or regression target".to_string(),
59            ));
60        }
61        let avg_performance = total_performance / selected_indices.len() as f64;
62        let cost_sensitive_score =
63            (1.0 - self.cost_weight) * avg_performance + self.cost_weight * (1.0 - normalized_cost);
64        Ok(cost_sensitive_score)
65    }
66    fn name(&self) -> &str {
67        "cost_sensitive"
68    }
69    fn clone_box(&self) -> Box<dyn ObjectiveFunction> {
70        Box::new(self.clone())
71    }
72}