Crates.io | friedrich |
lib.rs | friedrich |
version | 0.5.0 |
source | src |
created_at | 2019-11-01 22:10:02.365826 |
updated_at | 2022-12-06 20:56:53.446743 |
description | Gaussian Process Regression. |
homepage | |
repository | https://github.com/nestordemeure/friedrich |
max_upload_size | |
id | 177446 |
size | 138,125 |
This library implements Gaussian Process Regression, also known as Kriging, in Rust. Our goal is to provide a solid and well-featured building block for other algorithms (such as Bayesian Optimization).
Gaussian processes have both the ability to extract a lot of information from their training data and to return a prediction and an uncertainty value on their prediction. Furthermore, they can handle non-linear phenomena, take uncertainty on the inputs into account, and encode a prior on the output.
All of those properties make it an algorithm of choice to perform regression when data is scarce or when having uncertainty bars on the output is a desirable property.
However, the O(n^3)
complexity of the algorithm makes the classic implementations unsuitable for large datasets.
This implementation lets you:
cholesky_epsilon
to make the Cholesky decomposition infallible in case of badly conditioned problemsO(n^2)
) and refit the process(See the todo.md file to get up-to-date information on current developments.)
use friedrich::gaussian_process::GaussianProcess;
// trains a gaussian process on a dataset of one-dimensional vectors
let training_inputs = vec![vec![0.8], vec![1.2], vec![3.8], vec![4.2]];
let training_outputs = vec![3.0, 4.0, -2.0, -2.0];
let gp = GaussianProcess::default(training_inputs, training_outputs);
// predicts the mean and variance of a single point
let input = vec![1.];
let mean = gp.predict(&input);
let var = gp.predict_variance(&input);
println!("prediction: {} ± {}", mean, var.sqrt());
// makes several prediction
let inputs = vec![vec![1.0], vec![2.0], vec![3.0]];
let outputs = gp.predict(&inputs);
println!("predictions: {:?}", outputs);
// samples from the distribution
let new_inputs = vec![vec![1.0], vec![2.0]];
let sampler = gp.sample_at(&new_inputs);
let mut rng = rand::thread_rng();
println!("samples: {:?}", sampler.sample(&mut rng));
Most methods of this library can currently work with the following input -> output
pairs :
Vec<f64> -> f64
a single, multidimensional, sampleVec<Vec<f64>> -> Vec<f64>
each inner vector is a training sampleDMatrix<f64> -> DVector<f64>
using a nalgebra matrix with one row per sampleArrayBase<f64, Ix1> -> f64
a single sample stored in a ndarray array (using the friedrich_ndarray
feature)ArrayBase<f64, Ix2> -> Array1<f64>
each row is a sample (using the friedrich_ndarray
feature)The Input trait is provided to add your own pairs.
Gaussian Processes are named after the Gaussian distribution which is itself named after Carl Friedrich Gauss.