pub fn covariance<T, S, I>(
tensor: I,
feature_dimension: Dimension,
) -> Tensor<T, 2>Expand description
Computes the covariance matrix for a 2 dimensional Tensor feature matrix.
The feature_dimension specifies which dimension holds the features. The other dimension
is assumed to hold the samples. For a Tensor with a feature_dimension of length N, and
the other dimension of length M, returns an NxN covariance matrix with a shape of
[("i", N), ("j", N)].
Each element in the covariance matrix at (i, j) will be the variance of the ith and jth features from the feature matrix, defined as the zero meaned dot product of the two feature vectors divided by the number of samples (M).
If all the features in the input have a variance of one then the covariance matrix returned by this function will be equivalent to the correlation matrix of the input
This function does not perform Bessel’s correction
§Panics
- If the numeric type is unable to represent the number of samples for each feature
(ie if
T: i8and you have 1000 samples) - If the provided feature_dimension is not a dimension in the tensor
§Warning
With some uses of this function the Rust compiler gets confused about what type T
should be and you will get the error:
overflow evaluating the requirement
&'a _: easy_ml::numeric::NumericByValue<_, _>
In this case you need to manually specify the type of T by using the
turbofish syntax like:
linear_algebra::covariance::<f32, _, _>(&matrix)
Alternatively, the compiler doesn’t seem to run into this problem if you
use the equivalent methods on the matrix type like so:
tensor.covariance("features")
§Example
use easy_ml::tensors::Tensor;
let matrix = Tensor::from([("samples", 5), ("features", 3)], vec![
// X Y Z
1.0, 0.0, 0.5,
1.2, -1.0, 0.4,
1.8, -1.2, 0.7,
0.9, 0.1, 0.3,
0.7, 0.5, 0.6
]);
let covariance_matrix = matrix.covariance("features");
let (x, y, z) = (0, 1, 2);
let x_y_z = covariance_matrix.index();
// the variance of each feature with itself is positive
assert!(x_y_z.get([x, x]) > 0.0);
assert!(x_y_z.get([y, y]) > 0.0);
assert!(x_y_z.get([z, z]) > 0.0);
// first feature X and second feature Y have negative covariance (as X goes up Y goes down)
assert!(x_y_z.get([x, y]) < 0.0);
println!("{}", covariance_matrix);
// D = 2
// ("i", 3), ("j", 3)
// [ 0.142, -0.226, 0.026
// -0.226, 0.438, -0.022
// 0.026, -0.022, 0.020 ]