pub const MINIMUM_CONFIDENCE: f64 = 0.50;
pub const UTILITIES_THRESHOLD: f64 = 0.60;
pub const MODULE_SPLIT_CONFIDENCE: f64 = 0.65;
pub const MIN_METHODS_FOR_SPLIT: usize = 5;
#[derive(Debug, Clone, Default)]
pub struct ClassificationMetrics {
pub total_methods: usize,
pub classified_methods: usize,
pub unclassified_methods: usize,
pub utilities_count: usize,
}
impl ClassificationMetrics {
pub fn new() -> Self {
Self::default()
}
pub fn record_classification(&mut self, category: Option<&str>) {
self.total_methods += 1;
if let Some(cat) = category {
self.classified_methods += 1;
if cat == "utilities" {
self.utilities_count += 1;
}
} else {
self.unclassified_methods += 1;
}
}
pub fn utilities_rate(&self) -> f64 {
if self.total_methods == 0 {
0.0
} else {
self.utilities_count as f64 / self.total_methods as f64
}
}
pub fn classification_rate(&self) -> f64 {
if self.total_methods == 0 {
0.0
} else {
self.classified_methods as f64 / self.total_methods as f64
}
}
}
pub fn emit_classification_metrics(metrics: &ClassificationMetrics) {
log::info!(
"Classification metrics: total={}, classified={}, unclassified={}, utilities={} ({:.1}%)",
metrics.total_methods,
metrics.classified_methods,
metrics.unclassified_methods,
metrics.utilities_count,
metrics.utilities_rate() * 100.0
);
if metrics.utilities_rate() > 0.10 {
log::warn!(
"High utilities classification rate: {:.1}% (target: <10%)",
metrics.utilities_rate() * 100.0
);
}
if metrics.total_methods > 0 && metrics.classification_rate() < 0.50 {
log::warn!(
"Low classification rate: {:.1}% (may need to review thresholds)",
metrics.classification_rate() * 100.0
);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_threshold_values() {
let _min = MINIMUM_CONFIDENCE;
let _util = UTILITIES_THRESHOLD;
let _split = MODULE_SPLIT_CONFIDENCE;
let _methods = MIN_METHODS_FOR_SPLIT;
let test_confidence = 0.55;
assert!(test_confidence >= MINIMUM_CONFIDENCE);
assert!(test_confidence < UTILITIES_THRESHOLD);
}
}