rustlearn

repository·master·Indexed 20 days ago

https://github.com/maciejkula/rustlearn

A machine learning package for Rust (v0.5.0) providing implementations of common algorithms including logistic regression (via sgdclassifier), SVMs, decision trees, random forests, and factorization machines. It includes utilities for k-fold cross-validation, shuffle split, and various scoring metrics like accuracy_score and roc_auc_score. The library also features specialized sparse matrix storage (SparseRowArray and SparseColumnArray) and a set of traits (IndexableMatrix, RowIterable, ColumnIterable) for custom matrix implementations.

Tokens
11K
Snippets
38
Records
51
Agent score
70%

What's inside rustlearn

  1. Available Models in `rustlearn`

    master

    The library provides several machine learning models that support fitting and prediction on both dense and sparse data:

    • Logistic Regression: Using stochastic gradient descent (sgdclassifier).
    • Support Vector Machines (SVM): Using the libsvm library.
    • Decision Trees: Using the CART algorithm.
    • Random Forests: Using CART decision trees.
    • Factorization Machines.
  2. How to use `rustlearn` in your project

    master

    To use rustlearn, start by importing the prelude to access all linear algebra primitives and common traits. You can then import specific models and utilities from their respective submodules.

    Always use the prelude for core functionality and submodule imports for specific model configurations (like Hyperparameters).

    use rustlearn::prelude::*;
    
    use rustlearn::linear_models::sgdclassifier::Hyperparameters;
    // more imports
  3. Run tests and benchmarks

    master

    To verify your installation or contribute to the project, use the following commands:

    • Run basic tests: cargo test
    • Run all tests (including slow/generated tests): cargo test --features "all_tests" --release
    • Run benchmarks (requires nightly branch): cargo bench --features bench
    cargo test
    cargo test --features "all_tests" --release
    cargo bench --features bench
  4. Overview of rustlearn features

    master

    The rustlearn crate provides several machine learning primitives and models:

    Matrix Primitives

    • Dense matrices
    • Sparse matrices

    Available Models

    • Logistic Regression: Using stochastic gradient descent.
    • Support Vector Machines (SVM): Using the libsvm library.
    • Decision Trees: Using the CART algorithm.
    • Random Forests: Using CART decision trees.
    • Factorization Machines

    Note: All models support fitting and prediction on both dense and sparse data and support parallelization for fitting and prediction.

  5. How SGDClassifier handles regularization and learning rates

    master

    The SGDClassifier implements logistic regression using Stochastic Gradient Descent with an Adagrad adaptive per-parameter learning rate.

    • Adagrad: The learning rate for each parameter decreases based on the square root of the sum of its historical squared gradients. This allows for faster learning on rare features and more stable updates for common features.
    • L2 Regularization: Penalizes the magnitude of coefficients to prevent overfitting.
    • L1 Regularization: Promotes sparsity by truncating coefficients at zero whenever an update would cause a sign change.
    • Data Support: The implementation is optimized for both dense Array and SparseRowArray inputs.
  6. Getting started with rustlearn

    master

    To use rustlearn, start by importing the prelude to access all linear algebra primitives and common traits. Individual models and utilities should be imported from their specific submodules.

    Import Pattern

    use rustlearn::prelude::*;
    
    // Import specific models or hyperparameters
    use rustlearn::linear_models::sgdclassifier::Hyperparameters;
    use rustlearn::prelude::*;
    
    use rustlearn::linear_models::sgdclassifier::Hyperparameters;
  7. Convert between dense and sparse arrays

    master

    You can convert between dense Array types and sparse types using the From trait or the .todense() method:

    • Dense to Sparse: Use SparseRowArray::from(&dense_array) or SparseColumnArray::from(&dense_array).
    • Sparse to Dense: Use sparse_array.todense() to return a dense Array.
    use rustlearn::prelude::*;
    
    // Dense to Sparse
    let dense = Array::from(&vec![vec![1.0, 0.0], vec![0.0, 2.0]]);
    let sparse = SparseRowArray::from(&dense);
    
    // Sparse to Dense
    let back_to_dense = sparse.todense();
  8. Build and train a Factorization Machine model

    master

    To use a Factorization Machine, create a Hyperparameters instance, call .build() (or .one_vs_rest() for multiclass) to get a model, and then use .fit() to train it on your data.

    For faster training on large datasets, use .fit_parallel(X, y, num_threads) which implements multithreaded fitting via asynchronous stochastic gradient descent (Hogwild).

    use rustlearn::prelude::*;
    use rustlearn::factorization::factorization_machines::Hyperparameters;
    use rustlearn::datasets::iris;
    
    let (X, y) = iris::load_data();
    
    // Build a two-class model
    let mut model = Hyperparameters::new(X.cols(), 10).build();
    
    // Train the model
    model.fit(&X, &y).unwrap();
    
    // Predict
    let prediction = model.predict(&X).unwrap();
  9. Iterate over nonzero entries in a sparse matrix

    master

    To efficiently process only the data present in a sparse matrix, use the row or column iterators.

    For SparseRowArray, use .iter_rows() to get an iterator over rows. Each row can then be iterated using .iter_nonzero() to yield (index, value) pairs.

    For SparseColumnArray, use .iter_columns() to get an iterator over columns, followed by .iter_nonzero() on each column view.

    use rustlearn::prelude::*;
    
    // Assuming 'array' is a SparseRowArray
    for (row_idx, row) in array.iter_rows().enumerate() {
        for (column_idx, value) in row.iter_nonzero() {
            println!("Entry at ({}, {}) is {}", row_idx, column_idx, value);
        }
    }
  10. Train an SGDClassifier model

    master

    Training is performed using the fit method. The model supports both dense Array and SparseRowArray data types.

    Important: Epochs Calling fit once processes the provided dataset once. To perform multiple epochs of training (which is common for convergence), you must call fit repeatedly in a loop.

    fit returns a Result<(), &'static str> and will error if data dimensionality or labels are mismatched.

    // Single epoch
    model.fit(&X, &y).unwrap();
    
    // Multiple epochs
    let num_epochs = 20;
    for _ in 0..num_epochs {
        model.fit(&X, &y).unwrap();
    }
  11. Implement Logistic Regression with Stochastic Gradient Descent

    master

    You can implement logistic regression using the sgdclassifier. This involves loading data, setting up Hyperparameters, and performing cross-validation. The model supports fitting and prediction on both dense and sparse data.

    Note that for SGD-based models, you typically iterate over epochs to perform the fit operation.

    use rustlearn::prelude::*;
    use rustlearn::datasets::iris;
    use rustlearn::cross_validation::CrossValidation;
    use rustlearn::linear_models::sgdclassifier::Hyperparameters;
    use rustlearn::metrics::accuracy_score;
    
    let (X, y) = iris::load_data();
    
    let num_splits = 10;
    let num_epochs = 5;
    
    let mut accuracy = 0.0;
    
    for (train_idx, test_idx) in CrossValidation::new(X.rows(), num_splits) {
    
        let X_train = X.get_rows(&train_idx);
        let y_train = y.get_rows(&train_idx);
        let X_test = X.get_rows(&test_idx);
        let y_test = y.get_rows(&test_idx);
    
        let mut model = Hyperparameters::new(X.cols())
                                        .learning_rate(0.5)
                                        .l2_penalty(0.0)
                                        .l1_penalty(0.0)
                                        .one_vs_rest();
    
        for _ in 0..num_epochs {
            model.fit(&X_train, &y_train).unwrap();
        }
    
        let prediction = model.predict(&X_test).unwrap();
        accuracy += accuracy_score(&y_test, &prediction);
    }
    
    accuracy /= num_splits as f32;
  12. Implement Random Forest with Decision Trees

    master

    Random Forests in rustlearn are built using CART decision trees. You can configure the underlying decision tree using decision_tree::Hyperparameters (e.g., setting min_samples_split and max_features) and then pass those parameters into the random_forest::Hyperparameters constructor.

    use rustlearn::prelude::*;
    
    use rustlearn::ensemble::random_forest::Hyperparameters;
    use rustlearn::datasets::iris;
    use rustlearn::trees::decision_tree;
    
    let (data, target) = iris::load_data();
    
    let mut tree_params = decision_tree::Hyperparameters::new(data.cols());
    tree_params.min_samples_split(10)
        .max_features(4);
    
    let mut model = Hyperparameters::new(tree_params, 10)
        .one_vs_rest();
    
    model.fit(&data, &target).unwrap();
    
    // Optionally serialize and deserialize the model
    
    // let encoded = bincode::serialize(&model).unwrap();
    // let decoded: OneVsRestWrapper<RandomForest> = bincode::deserialize(&encoded).unwrap();
    
    let prediction = model.predict(&data).unwrap();