🦀

Rust初心者がMacに環境構築してクレート・モジュールを使い、簡単な機械学習を行うまでをまとめた

2022/03/15に公開

Mac前提ですが、Rust を導入してクレート・モジュールの追加と簡単な機械学習の実施までをやってみたのでまとめます。

もっといい方法がありそうなので順次更新していこうと思います。

コードはこちら

環境構築

下記コマンドをターミナルで実行して、Rust をインストールします。

curl https://sh.rustup.rs -sSf | sh

https://doc.rust-jp.rs/book-ja/ch01-01-installation.html

権限が通らない場合は下記コマンドを実施しましょう。

curl https://sh.rustup.rs -sSf | sh -s -- --no-modify-path

https://qiita.com/Kazuki-Komori/items/0497799295ec044494c6

下記コマンドを実行してパスを通します。

source $HOME/.cargo/env

cargo のバージョン確認をし、ちゃんとRustがインストールされているか確かめます。

cargo --version

バージョンが出力されればOK。

cargo 1.58.0  

プロジェクト作成

下記コマンドを実行して cargo でプロジェクトを作成します。

cargo new ml_sample

下記ファイルが作成されます。

|--ml_sample
    |-- src
    |    |-- main.rs
    |
    |-- Cargo.toml
    |-- .gitignore

作成したプロジェクトのフォルダに移動しましょう。

cd ml_sample 

外部クレートの追加

crate.io で クレートの名前とバージョンを確かめ、Cargo.toml ファイルに追記してみます。

実際に使うのは後になりますが、機械学習に使える smartcore をいれてみます。

https://crates.io/crates/smartcore

Cargo.toml
[package]
name = "ml_sample"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
# ここにインストールする crate を書いていく
smartcore  = "0.2.0"

自作モジュールを作成する

次に自作モジュールを追加すべく、新しいプロジェクト hello を作成します。

cargo new hello

ファイル構成が下記のようになります。

|--ml_sample
    |-- src
    |    |-- main.rs
    |
    |-- Cargo.toml
    |-- .gitignore
    |-- hello
         |-- src
         |    |-- main.rs
         |
         |-- Cargo.toml

hello/src フォルダ直下に lib.rs (ライブラリクレート) を作成します。

https://dackdive.hateblo.jp/entry/2020/12/09/103000

|--ml_sample
    |-- src
    |    |-- main.rs
    |
    |-- Cargo.toml
    |-- .gitignore
    |-- hello
         |-- src
         |    |-- main.rs
         |    |-- lib.rs
         |
         |-- Cargo.toml

lib.rs に下記コードを記載し、引数を読み取って Hello, World するだけの簡単なモジュールを作成します。

hello/src/lib.rs
pub fn hello_world(word: &str) -> String {
  let greeding :String = "Hello, ".to_owned() + word + "!";
  return greeding
}

mod の使い所がまだわからない。

https://dackdive.hateblo.jp/entry/2020/12/09/103000

Rust は return を明示しないときもあるようですが、この辺の扱いはもう少し学習する必要あり・・・。

https://doc.rust-jp.rs/rust-by-example-ja/fn.html

上記は外部クレート・モジュールを使わないので、hello/Cargo.toml ファイルは更新しません。

最初に作成した Cargo.toml ファイルに 自作モジュールの情報を追記します。

[dependencies.hello]
path = "./hello"

全体の記載は以下の通り。

Cargo.toml
[package]
name = "ml_sample"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
smartcore  = "0.2.0"

# 以下を追加
[dependencies.hello]
path = "./hello"

下記でもよいようですね。

[dependencies]
smartcore  = "0.2.0"
hello = {path = "./hello"} # 追加

ファイル実行

main.rs を更新します。

src/main.rs
extern crate hello;

fn main() {
  let word:&str = "World";
  println!("{:?}", hello::hello_world(word));
}

ターミナルで下記コマンドを入力してビルドします。

cargo build

ターミナルで下記コマンドを入力してビルドされた実行ファイルを実行します。

target/debug/ml_sample

以下が出力されれば成功です。

Hello, World!

機械学習

機械学習部分は下記サイトのコードを少し変えてます。

  • データセットを ボストン住宅価格(回帰)にした。
  • train_test_spilit のシャッフルを行わず再現性を担保した。

https://zenn.dev/mattn/articles/3290149a6fc18c

src/main.rs
// 機械学習用のクレート
use smartcore::dataset::boston;
use smartcore::linalg::naive::dense_matrix::DenseMatrix;
use smartcore::model_selection::train_test_split;
use smartcore::linear::linear_regression::{LinearRegression, LinearRegressionParameters, LinearRegressionSolverName};
use smartcore::metrics::mean_squared_error;

fn main() {
  // データセットのダウンロード
  let boston_data = boston::load_dataset();

  // 特徴量を arrayデータへ変換
  let x = DenseMatrix::from_array(
    boston_data.num_samples,
    boston_data.num_features,
    &boston_data.data,
  );

  // 目的変数
  let y = boston_data.target;

  // 評価データと訓練データに分割
  let (x_train, x_test, y_train, y_test) = train_test_split(
                                                    &x,    // training data
                                                    &y,    // target
                                                    0.2,   // test_size
                                                    false, // shuffle
                                                  );
  // 学習
  let model = LinearRegression::fit(
                            &x_train, 
                            &y_train,
                            LinearRegressionParameters::default().
                              with_solver(LinearRegressionSolverName::QR)
                            ).unwrap();

  // 推論
  let y_pred = model.predict(&x_test).unwrap();

  // 評価
  let metrics = mean_squared_error(&y_test, &y_pred);

  // 評価結果を出力
  println!("mse:{}", metrics);
}

出力:
mse:12.573088

次は csv でテーブルデータ取り込んで機械学習実行するところからやりたい。

以上になります、最後までお読みいただきありがとうございました。

参考サイト

https://doc.rust-jp.rs/book-ja/ch01-03-hello-cargo.html

https://qiita.com/AyachiGin/items/6d098d512e6766181a01

https://zenn.dev/mattn/articles/3290149a6fc18c

Discussion