【Rust】nalgebraを使って簡単な線形回帰問題を解く

今回は久しぶりにRustの記事で、nalgebraを使って簡単な線形回帰問題を解いてみることにします。

nalgebraの使い方については以前記事で書きました。

enu23456.hatenablog.com

今回はnalgebraを用いて、単回帰分析を行列計算により行います。

ただし、、、毎度のごとくコードを書くだけであまり解説はしません(笑)

Rustのnalgebraをによる行列計算のコード例、または回帰分析の実装を行う時のコード例として参考にしていただければと思います。

//! nalgebraを用いて簡単な線形回帰問題を解く
//!
//! # dependencies
//! nalgebra = "0.31.1"

extern crate nalgebra as na;
use na::{Matrix5x2, RowVector2};

fn main() {
    // (x, y)の集合を宣言する
    // この(x, y)の集合は、回帰問題として解くと y = 1.5 * x + 2.5 となる
    let data = Matrix5x2::from_rows(&[
        RowVector2::new(4.0, 10.0),
        RowVector2::new(5.0, 12.0),
        RowVector2::new(8.0, 14.0),
        RowVector2::new(2.0, 4.0),
        RowVector2::new(6.0, 10.0),
    ]);

    println!("data:\n{}", data);

    // 方針
    // 回帰直線を Y = X * b + e (Y: 観測ベクトル, X: 説明変数行列, b: 係数ベクトル, e: 誤差ベクトル)と置いた場合
    // X.T * Y = X.T * X * b を満たす b を求めればよく、式を変形すると
    // b = (X.T * X)^-1 * X.T * Y を計算すれば良いことが分かる
    // 詳細はWeb上の他の資料を参照すること

    // 説明変数行列を作成する
    let features = data.column(0);
    let regressor = features.insert_column(0, 1.0);

    // 観測ベクトルを作成する
    let target = data.column(1);

    // 方針で書いたようにパラメータベクトル`b`を求める
    let parameter =
        (regressor.transpose() * regressor).try_inverse().unwrap() * regressor.transpose() * target;

    // 計算結果を表示する
    println!("y = {:.1} * x + {:.1}", parameter[1], parameter[0]); // true: 1.5 * x + 2.5
}

以上で今回は終わりです。