MCPcopy Create free account
hub / github.com/Open-Quant/openquant / mean_decrease_impurity

Function mean_decrease_impurity

crates/openquant/src/feature_importance.rs:21–56  ·  view source on GitHub ↗
(
    per_tree_importances: &[Vec<f64>],
    feature_names: &[String],
)

Source from the content-addressed store, hash-verified

19}
20
21pub fn mean_decrease_impurity(
22 per_tree_importances: &[Vec<f64>],
23 feature_names: &[String],
24) -> Result<BTreeMap<String, ImportanceStats>, String> {
25 if per_tree_importances.is_empty() {
26 return Err("per_tree_importances cannot be empty".to_string());
27 }
28 let n_features = feature_names.len();
29 if n_features == 0 {
30 return Err("feature_names cannot be empty".to_string());
31 }
32 if per_tree_importances.iter().any(|r| r.len() != n_features) {
33 return Err("importance row length mismatch".to_string());
34 }
35
36 let mut means = vec![0.0; n_features];
37 let mut stderrs = vec![0.0; n_features];
38 for j in 0..n_features {
39 let col: Vec<f64> = per_tree_importances
40 .iter()
41 .map(|r| if r[j] == 0.0 { f64::NAN } else { r[j] })
42 .collect();
43 let (m, s) = nan_mean_std(&col);
44 means[j] = m;
45 stderrs[j] = s * (per_tree_importances.len() as f64).powf(-0.5);
46 }
47
48 let denom: f64 = means.iter().filter(|v| v.is_finite()).sum();
49 let mut out = BTreeMap::new();
50 for (j, name) in feature_names.iter().enumerate() {
51 let mean = if denom > 0.0 && means[j].is_finite() { means[j] / denom } else { 0.0 };
52 let std = if denom > 0.0 && stderrs[j].is_finite() { stderrs[j] / denom } else { 0.0 };
53 out.insert(name.clone(), ImportanceStats { mean, std });
54 }
55 Ok(out)
56}
57
58pub fn mean_decrease_accuracy<C: SimpleClassifier>(
59 model: &mut C,

Calls 3

nan_mean_stdFunction · 0.85
is_emptyMethod · 0.80
lenMethod · 0.80