use super::{Accuracy, Case};
use ndarray::{ArrayView, Ix1, Zip};
pub fn interpret<'c, A: PartialEq, C>(
cases: &'c [Case<A, C>],
attribute_value: &A,
) -> Option<&'c C> {
cases
.iter()
.find(|case| &case.attribute_value == attribute_value)
.map(|case| &case.predicted_class)
}
pub fn evaluate<A: PartialEq, C: PartialEq>(
cases: &[Case<A, C>],
attribute_values: &ArrayView<A, Ix1>,
classes: &ArrayView<C, Ix1>,
) -> Accuracy {
let mut right_wrong: Vec<Option<bool>> = Vec::new();
Zip::from(attribute_values).and(classes).apply(|attribute_value, class| {
match interpret(cases, attribute_value) {
None => right_wrong.push(None),
Some(predicted) => right_wrong.push(Some(predicted == class)),
}
});
let num_examples = classes.len();
if num_examples == 0 {
Accuracy(0.0)
} else {
let num_correct = right_wrong.into_iter().filter(|&o| o == Some(true)).count();
Accuracy(num_correct as f64 / num_examples as f64)
}
}