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
use super::stats;
pub fn fit(x: &[f64], y: &[f64]) -> [f64; 2] {
let slope = stats::covariance(x, y) / stats::variance(x);
let intercept = stats::mean(y) - slope * stats::mean(x);
[slope, intercept]
}
pub fn predict(x: &f64, model: &[f64; 2]) -> f64 {
x * model[0] + model[1]
}
fn root_mean_squared_error(actual: &[f64], predicted: &[f64]) -> f64 {
let length = actual.len();
let sum_error_iter: f64 = predicted
.iter()
.zip(actual.iter())
.map(|(x, y)| (x - y).powi(2))
.sum();
let mse = (sum_error_iter / length as f64).sqrt();
mse
}
fn rsquared(y: &[f64], rms: &f64) -> f64 {
1.0 - (rms / stats::variance(y))
}
pub fn evaluate(x: &[f64], y: &[f64], model: &[f64; 2]) -> [f64; 2] {
let y_predicted: Vec<f64> = x.iter().map(|y| predict(y, model)).collect();
let rms = root_mean_squared_error(y, &y_predicted);
[rms, rsquared(y, &rms)]
}