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
use Array1;
use crateOlsFit;
/// Standardized (beta) coefficients — the linear model's version of feature
/// importance.
///
/// Each raw coefficient is rescaled to the units it would take on a z-scored
/// design and z-scored response:
///
/// `βⱼ* = βⱼ · (sⱼ / s_y)`
///
/// where `sⱼ` is the standard deviation of predictor `j` and `s_y` that of the
/// response. Because the predictors are put on a common (unit-variance) scale,
/// the **relative magnitudes** of the standardized coefficients are comparable
/// across predictors in a way the raw coefficients — each in its own units — are
/// not.
///
/// This rescales the existing fit's coefficients rather than refitting; the two
/// are algebraically identical for OLS. Sample standard deviations use the `n − 1`
/// (unbiased) denominator.
///
/// # Return layout
///
/// Aligned to the design columns: entry `j` is the standardized coefficient of
/// column `j`. The **intercept column's entry is [`f64::NAN`]** — a standardized
/// intercept is not meaningful (it is zero by construction on centered data).
///
/// # Example
///
/// ```
/// use ndarray::array;
/// use regression_diagnostics::{OlsFit, coefficients::standardized_coefficients};
///
/// // x1 drives y an order of magnitude harder than x2 does.
/// let x = array![
/// [1.0, 1.0, 5.0],
/// [1.0, 2.0, 4.0],
/// [1.0, 3.0, 6.0],
/// [1.0, 4.0, 5.0],
/// [1.0, 5.0, 7.0],
/// ];
/// let y = array![10.0, 20.5, 29.5, 40.5, 50.0];
/// let fit = OlsFit::new(x, y).unwrap();
/// let b = standardized_coefficients(&fit);
/// assert!(b[0].is_nan()); // intercept
/// assert!(b[1].abs() > b[2].abs()); // x1 dominates
/// ```