1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//! Model-evaluation metrics for classification, clustering, and regression
//!
//! Each metric lives in a category submodule and the module root re-exports it. You can reach a
//! metric by category (`metrics::regression::mean_squared_error`) or by the flat path
//! (`metrics::mean_squared_error`). The crate and its prelude use the flat paths.
//!
//! # Regression metrics
//! - **mean_squared_error** / **root_mean_squared_error**: average squared error and its root
//! - **mean_absolute_error** / **median_absolute_error**: mean and (outlier-robust) median
//! absolute error
//! - **mean_absolute_percentage_error**: mean error relative to the true values
//! - **r2_score**: coefficient of determination (R^2)
//! - **explained_variance_score**: residual variance relative to the data variance (ignores
//! constant bias)
//!
//! # Classification metrics
//! - [`ConfusionMatrix`](crate::metrics::ConfusionMatrix): binary TP/FP/TN/FN with derived
//! accuracy, precision, recall, specificity, F1, error rate, balanced accuracy, and MCC
//! - [`MulticlassConfusionMatrix`](crate::metrics::MulticlassConfusionMatrix): KxK matrix with
//! per-class precision/recall/F1/support and macro/micro/weighted aggregation via
//! [`Average`](crate::metrics::Average)
//! - **accuracy**, **roc_auc**, **log_loss**, **cohen_kappa**, **top_k_accuracy**,
//! **average_precision**, and the **roc_curve** / **precision_recall_curve** threshold sweeps
//!
//! # Clustering metrics
//! - **adjusted_rand_index**, **normalized_mutual_info**, **adjusted_mutual_info**
//! - **homogeneity_score** / **completeness_score** / **v_measure_score**,
//! **fowlkes_mallows_score**
//! - **silhouette_score**, **davies_bouldin_score**, **calinski_harabasz_score** (internal
//! indices, no ground truth needed)
//!
//! # Conventions
//!
//! - **Panics instead of returning `Result`.** The functions in `metrics` panic on a precondition
//! violation, such as mismatched lengths or empty input. This follows `ndarray` on a dimension
//! mismatch, rather than returning the crate's `Error`. The panic messages mirror that type's
//! wording (`dimension mismatch: ...`, `input is empty: ...`).
//! - **2 argument conventions.** A hard-label function takes `(y_true, y_pred)`, ground truth
//! first. This mirrors the clustering metrics' `(labels_true, labels_pred)`. Order does not
//! affect the symmetric metrics (MSE, MAE, `accuracy`), but it does affect `r2_score` and the
//! confusion matrix types. A threshold-based function instead takes `(labels, scores)`: `bool`
//! ground truth first, then `f64` scores. `roc_auc`, `roc_curve`, `precision_recall_curve`, and
//! `average_precision` use this second convention.
//!
//! # Examples
//!
//! ```rust
//! use rustyml::metrics::*;
//! use ndarray::array;
//!
//! // Regression evaluation. Arguments are (y_true, y_pred).
//! let y_true = array![2.8, 2.1, 3.3, 4.2];
//! let y_pred = array![3.0, 2.0, 3.5, 4.1];
//! let mse = mean_squared_error(&y_true.view(), &y_pred.view());
//! let r2 = r2_score(&y_true.view(), &y_pred.view());
//!
//! // Classification evaluation with a confusion matrix.
//! let y_true = array![1.0, 0.0, 0.0, 1.0, 1.0];
//! let y_pred = array![1.0, 0.0, 1.0, 1.0, 0.0];
//! let cm = ConfusionMatrix::new(&y_true.view(), &y_pred.view());
//! println!("F1 Score: {:.3}", cm.f1_score());
//!
//! // ROC AUC for binary classification.
//! let labels = array![false, true, false, true];
//! let scores = array![0.1, 0.4, 0.35, 0.8];
//! let auc = roc_auc(&labels.view(), &scores.view());
//! ```
/// Classification metrics: confusion matrices, accuracy, ROC/PR curves, log loss,
/// and Cohen's kappa.
/// Clustering metrics: mutual information (NMI/AMI), adjusted Rand index, and silhouette.
/// Regression metrics: MSE, RMSE, MAE, R^2, explained variance, and MAPE.
pub use ;
pub use ;
pub use ;
/// Checks a `(y_true, y_pred)`-style pair of inputs for equal length and non-empty content.
///
/// The length check runs first, so a length mismatch is reported even when one input is empty.
/// The panic messages mirror [`crate::error::Error::DimensionMismatch`] and
/// [`crate::error::Error::EmptyInput`]. This keeps the lightweight `metrics` tier consistent with
/// the rest of the crate, without depending on the `error` module.
///
/// # Parameters
///
/// - `expected` - the expected length, taken from the first input
/// - `found` - the actual length of the second input
/// - `what` - names the inputs for the empty-input message, for example `"y_true and y_pred"`
///
/// # Panics
///
/// - Panics if `expected` does not equal `found`.
/// - Panics if `expected` is 0 (empty input).
/// Out-of-line panic path for [`validate_pair`], marked `#[cold]` so the caller's hot path stays
/// down to 2 comparisons. Re-checks the length condition once, only to pick the right message.
!