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

Function silhouette_samples

crates/openquant/src/onc.rs:404–467  ·  view source on GitHub ↗
(data: &DMatrix<f64>, labels: &[usize])

Source from the content-addressed store, hash-verified

402}
403
404fn silhouette_samples(data: &DMatrix<f64>, labels: &[usize]) -> Vec<f64> {
405 let n = data.nrows();
406 let mut by_cluster: BTreeMap<usize, Vec<usize>> = BTreeMap::new();
407 for (i, lbl) in labels.iter().copied().enumerate() {
408 by_cluster.entry(lbl).or_default().push(i);
409 }
410
411 let mut pairwise = DMatrix::zeros(n, n);
412 for i in 0..n {
413 for j in i..n {
414 let mut s = 0.0;
415 for c in 0..data.ncols() {
416 let diff = data[(i, c)] - data[(j, c)];
417 s += diff * diff;
418 }
419 let d = s.sqrt();
420 pairwise[(i, j)] = d;
421 pairwise[(j, i)] = d;
422 }
423 }
424
425 let mut scores = vec![0.0; n];
426 for i in 0..n {
427 let own = labels[i];
428 let own_members = &by_cluster[&own];
429
430 let a = if own_members.len() <= 1 {
431 0.0
432 } else {
433 let mut s = 0.0;
434 let mut cnt = 0usize;
435 for &j in own_members {
436 if j != i {
437 s += pairwise[(i, j)];
438 cnt += 1;
439 }
440 }
441 if cnt == 0 {
442 0.0
443 } else {
444 s / cnt as f64
445 }
446 };
447
448 let mut b = f64::INFINITY;
449 for (cluster, members) in &by_cluster {
450 if *cluster == own || members.is_empty() {
451 continue;
452 }
453 let mut s = 0.0;
454 for &j in members {
455 s += pairwise[(i, j)];
456 }
457 let mean = s / members.len() as f64;
458 if mean < b {
459 b = mean;
460 }
461 }

Callers 2

improve_clustersFunction · 0.85
cluster_kmeans_baseFunction · 0.85

Calls 2

lenMethod · 0.80
is_emptyMethod · 0.80

Tested by

no test coverage detected