Skip to content

Commit

Permalink
Patch to version 0.4.0 (#257)
Browse files Browse the repository at this point in the history
* uncomment test

* Add random test for logistic regression

* linting

* Bump version

* Add test for logistic regression

* linting

* initial commit

* final

* final-clean

* Bump to 0.4.0

* Fix linter

* cleanup

* Update CHANDELOG with breaking changes

* Update CHANDELOG date

* Add functional methods to DenseMatrix implementation

* linting

* add type declaration in test

* Fix Wasm tests failing

* linting

* fix tests

* linting

* Add type annotations on BBDTree constructor

* fix clippy

* fix clippy

* fix tests

* bump version

* run fmt. fix changelog

---------

Co-authored-by: Edmund Cape <edmund@Edmunds-MacBook-Pro.local>
  • Loading branch information
Mec-iS and Edmund Cape committed Mar 4, 2024
1 parent 80a93c1 commit 239c004
Show file tree
Hide file tree
Showing 45 changed files with 763 additions and 410 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.4.0] - 2023-04-05

## Added
- WARNING: Breaking changes!
- `DenseMatrix` constructor now returns `Result` to avoid user instantiating inconsistent rows/cols count. Their return values need to be unwrapped with `unwrap()`, see tests

## [0.3.0] - 2022-11-09

## Added
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "smartcore"
description = "Machine Learning in Rust."
homepage = "https://smartcorelib.org"
version = "0.3.2"
version = "0.4.0"
authors = ["smartcore Developers"]
edition = "2021"
license = "Apache-2.0"
Expand Down
7 changes: 4 additions & 3 deletions src/algorithm/neighbour/bbd_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ impl BBDTreeNode {

impl BBDTree {
pub fn new<T: Number, M: Array2<T>>(data: &M) -> BBDTree {
let nodes = Vec::new();
let nodes: Vec<BBDTreeNode> = Vec::new();

let (n, _) = data.shape();

let index = (0..n).collect::<Vec<_>>();
let index = (0..n).collect::<Vec<usize>>();

let mut tree = BBDTree {
nodes,
Expand Down Expand Up @@ -343,7 +343,8 @@ mod tests {
&[4.9, 2.4, 3.3, 1.0],
&[6.6, 2.9, 4.6, 1.3],
&[5.2, 2.7, 3.9, 1.4],
]);
])
.unwrap();

let tree = BBDTree::new(&data);

Expand Down
18 changes: 11 additions & 7 deletions src/algorithm/neighbour/fastpair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
/// &[4.6, 3.1, 1.5, 0.2],
/// &[5.0, 3.6, 1.4, 0.2],
/// &[5.4, 3.9, 1.7, 0.4],
/// ]);
/// ]).unwrap();
/// let fastpair = FastPair::new(&x);
/// let closest_pair: PairwiseDistance<f64> = fastpair.unwrap().closest_pair();
/// ```
Expand Down Expand Up @@ -271,7 +271,7 @@ mod tests_fastpair {
fn dataset_has_at_least_three_points() {
// Create a dataset which consists of only two points:
// A(0.0, 0.0) and B(1.0, 1.0).
let dataset = DenseMatrix::<f64>::from_2d_array(&[&[0.0, 0.0], &[1.0, 1.0]]);
let dataset = DenseMatrix::<f64>::from_2d_array(&[&[0.0, 0.0], &[1.0, 1.0]]).unwrap();

// We expect an error when we run `FastPair` on this dataset,
// becuase `FastPair` currently only works on a minimum of 3
Expand All @@ -288,7 +288,7 @@ mod tests_fastpair {

#[test]
fn one_dimensional_dataset_minimal() {
let dataset = DenseMatrix::<f64>::from_2d_array(&[&[0.0], &[2.0], &[9.0]]);
let dataset = DenseMatrix::<f64>::from_2d_array(&[&[0.0], &[2.0], &[9.0]]).unwrap();

let result = FastPair::new(&dataset);
assert!(result.is_ok());
Expand All @@ -308,7 +308,8 @@ mod tests_fastpair {

#[test]
fn one_dimensional_dataset_2() {
let dataset = DenseMatrix::<f64>::from_2d_array(&[&[27.0], &[0.0], &[9.0], &[2.0]]);
let dataset =
DenseMatrix::<f64>::from_2d_array(&[&[27.0], &[0.0], &[9.0], &[2.0]]).unwrap();

let result = FastPair::new(&dataset);
assert!(result.is_ok());
Expand Down Expand Up @@ -343,7 +344,8 @@ mod tests_fastpair {
&[6.9, 3.1, 4.9, 1.5],
&[5.5, 2.3, 4.0, 1.3],
&[6.5, 2.8, 4.6, 1.5],
]);
])
.unwrap();
let fastpair = FastPair::new(&x);
assert!(fastpair.is_ok());

Expand Down Expand Up @@ -516,7 +518,8 @@ mod tests_fastpair {
&[6.9, 3.1, 4.9, 1.5],
&[5.5, 2.3, 4.0, 1.3],
&[6.5, 2.8, 4.6, 1.5],
]);
])
.unwrap();
// compute
let fastpair = FastPair::new(&x);
assert!(fastpair.is_ok());
Expand Down Expand Up @@ -564,7 +567,8 @@ mod tests_fastpair {
&[6.9, 3.1, 4.9, 1.5],
&[5.5, 2.3, 4.0, 1.3],
&[6.5, 2.8, 4.6, 1.5],
]);
])
.unwrap();
// compute
let fastpair = FastPair::new(&x);
assert!(fastpair.is_ok());
Expand Down
6 changes: 4 additions & 2 deletions src/cluster/dbscan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,8 @@ mod tests {
&[2.2, 1.2],
&[1.8, 0.8],
&[3.0, 5.0],
]);
])
.unwrap();

let expected_labels = vec![1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0];

Expand Down Expand Up @@ -487,7 +488,8 @@ mod tests {
&[4.9, 2.4, 3.3, 1.0],
&[6.6, 2.9, 4.6, 1.3],
&[5.2, 2.7, 3.9, 1.4],
]);
])
.unwrap();

let dbscan = DBSCAN::fit(&x, Default::default()).unwrap();

Expand Down
12 changes: 7 additions & 5 deletions src/cluster/kmeans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
//! &[4.9, 2.4, 3.3, 1.0],
//! &[6.6, 2.9, 4.6, 1.3],
//! &[5.2, 2.7, 3.9, 1.4],
//! ]);
//! ]).unwrap();
//!
//! let kmeans = KMeans::fit(&x, KMeansParameters::default().with_k(2)).unwrap(); // Fit to data, 2 clusters
//! let y_hat: Vec<u8> = kmeans.predict(&x).unwrap(); // use the same points for prediction
Expand Down Expand Up @@ -249,7 +249,7 @@ impl<TX: Number, TY: Number, X: Array2<TX>, Y: Array1<TY>> Predictor<X, Y>

impl<TX: Number, TY: Number, X: Array2<TX>, Y: Array1<TY>> KMeans<TX, TY, X, Y> {
/// Fit algorithm to _NxM_ matrix where _N_ is number of samples and _M_ is number of features.
/// * `data` - training instances to cluster
/// * `data` - training instances to cluster
/// * `parameters` - cluster parameters
pub fn fit(data: &X, parameters: KMeansParameters) -> Result<KMeans<TX, TY, X, Y>, Failed> {
let bbd = BBDTree::new(data);
Expand Down Expand Up @@ -424,7 +424,7 @@ mod tests {
)]
#[test]
fn invalid_k() {
let x = DenseMatrix::from_2d_array(&[&[1, 2, 3], &[4, 5, 6]]);
let x = DenseMatrix::from_2d_array(&[&[1, 2, 3], &[4, 5, 6]]).unwrap();

assert!(KMeans::<i32, i32, DenseMatrix<i32>, Vec<i32>>::fit(
&x,
Expand Down Expand Up @@ -492,7 +492,8 @@ mod tests {
&[4.9, 2.4, 3.3, 1.0],
&[6.6, 2.9, 4.6, 1.3],
&[5.2, 2.7, 3.9, 1.4],
]);
])
.unwrap();

let kmeans = KMeans::fit(&x, Default::default()).unwrap();

Expand Down Expand Up @@ -531,7 +532,8 @@ mod tests {
&[4.9, 2.4, 3.3, 1.0],
&[6.6, 2.9, 4.6, 1.3],
&[5.2, 2.7, 3.9, 1.4],
]);
])
.unwrap();

let kmeans: KMeans<f32, f32, DenseMatrix<f32>, Vec<f32>> =
KMeans::fit(&x, Default::default()).unwrap();
Expand Down
20 changes: 13 additions & 7 deletions src/decomposition/pca.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
//! &[4.9, 2.4, 3.3, 1.0],
//! &[6.6, 2.9, 4.6, 1.3],
//! &[5.2, 2.7, 3.9, 1.4],
//! ]);
//! ]).unwrap();
//!
//! let pca = PCA::fit(&iris, PCAParameters::default().with_n_components(2)).unwrap(); // Reduce number of features to 2
//!
Expand Down Expand Up @@ -443,6 +443,7 @@ mod tests {
&[2.6, 53.0, 66.0, 10.8],
&[6.8, 161.0, 60.0, 15.6],
])
.unwrap()
}
#[cfg_attr(
all(target_arch = "wasm32", not(target_os = "wasi")),
Expand All @@ -457,7 +458,8 @@ mod tests {
&[0.9952, 0.0588],
&[0.0463, 0.9769],
&[0.0752, 0.2007],
]);
])
.unwrap();

let pca = PCA::fit(&us_arrests, Default::default()).unwrap();

Expand Down Expand Up @@ -500,7 +502,8 @@ mod tests {
-0.974080592182491,
0.0723250196376097,
],
]);
])
.unwrap();

let expected_projection = DenseMatrix::from_2d_array(&[
&[-64.8022, -11.448, 2.4949, -2.4079],
Expand Down Expand Up @@ -553,7 +556,8 @@ mod tests {
&[91.5446, -22.9529, 0.402, -0.7369],
&[118.1763, 5.5076, 2.7113, -0.205],
&[10.4345, -5.9245, 3.7944, 0.5179],
]);
])
.unwrap();

let expected_eigenvalues: Vec<f64> = vec![
343544.6277001563,
Expand Down Expand Up @@ -616,7 +620,8 @@ mod tests {
-0.0881962972508558,
-0.0096011588898465,
],
]);
])
.unwrap();

let expected_projection = DenseMatrix::from_2d_array(&[
&[0.9856, -1.1334, 0.4443, -0.1563],
Expand Down Expand Up @@ -669,7 +674,8 @@ mod tests {
&[-2.1086, -1.4248, -0.1048, -0.1319],
&[-2.0797, 0.6113, 0.1389, -0.1841],
&[-0.6294, -0.321, 0.2407, 0.1667],
]);
])
.unwrap();

let expected_eigenvalues: Vec<f64> = vec![
2.480241579149493,
Expand Down Expand Up @@ -732,7 +738,7 @@ mod tests {
// &[4.9, 2.4, 3.3, 1.0],
// &[6.6, 2.9, 4.6, 1.3],
// &[5.2, 2.7, 3.9, 1.4],
// ]);
// ]).unwrap();

// let pca = PCA::fit(&iris, Default::default()).unwrap();

Expand Down
10 changes: 6 additions & 4 deletions src/decomposition/svd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
//! &[4.9, 2.4, 3.3, 1.0],
//! &[6.6, 2.9, 4.6, 1.3],
//! &[5.2, 2.7, 3.9, 1.4],
//! ]);
//! ]).unwrap();
//!
//! let svd = SVD::fit(&iris, SVDParameters::default().
//! with_n_components(2)).unwrap(); // Reduce number of features to 2
Expand Down Expand Up @@ -292,15 +292,17 @@ mod tests {
&[5.7, 81.0, 39.0, 9.3],
&[2.6, 53.0, 66.0, 10.8],
&[6.8, 161.0, 60.0, 15.6],
]);
])
.unwrap();

let expected = DenseMatrix::from_2d_array(&[
&[243.54655757, -18.76673788],
&[268.36802004, -33.79304302],
&[305.93972467, -15.39087376],
&[197.28420365, -11.66808306],
&[293.43187394, 1.91163633],
]);
])
.unwrap();
let svd = SVD::fit(&x, Default::default()).unwrap();

let x_transformed = svd.transform(&x).unwrap();
Expand Down Expand Up @@ -341,7 +343,7 @@ mod tests {
// &[4.9, 2.4, 3.3, 1.0],
// &[6.6, 2.9, 4.6, 1.3],
// &[5.2, 2.7, 3.9, 1.4],
// ]);
// ]).unwrap();

// let svd = SVD::fit(&iris, Default::default()).unwrap();

Expand Down
11 changes: 7 additions & 4 deletions src/ensemble/random_forest_classifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
//! &[4.9, 2.4, 3.3, 1.0],
//! &[6.6, 2.9, 4.6, 1.3],
//! &[5.2, 2.7, 3.9, 1.4],
//! ]);
//! ]).unwrap();
//! let y = vec![
//! 0, 0, 0, 0, 0, 0, 0, 0,
//! 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
Expand Down Expand Up @@ -660,7 +660,8 @@ mod tests {
&[4.9, 2.4, 3.3, 1.0],
&[6.6, 2.9, 4.6, 1.3],
&[5.2, 2.7, 3.9, 1.4],
]);
])
.unwrap();
let y = vec![0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];

let classifier = RandomForestClassifier::fit(
Expand Down Expand Up @@ -733,7 +734,8 @@ mod tests {
&[4.9, 2.4, 3.3, 1.0],
&[6.6, 2.9, 4.6, 1.3],
&[5.2, 2.7, 3.9, 1.4],
]);
])
.unwrap();
let y = vec![0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];

let classifier = RandomForestClassifier::fit(
Expand Down Expand Up @@ -786,7 +788,8 @@ mod tests {
&[4.9, 2.4, 3.3, 1.0],
&[6.6, 2.9, 4.6, 1.3],
&[5.2, 2.7, 3.9, 1.4],
]);
])
.unwrap();
let y = vec![0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];

let forest = RandomForestClassifier::fit(&x, &y, Default::default()).unwrap();
Expand Down
11 changes: 7 additions & 4 deletions src/ensemble/random_forest_regressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
//! &[502.601, 393.1, 251.4, 125.368, 1960., 69.564],
//! &[518.173, 480.6, 257.2, 127.852, 1961., 69.331],
//! &[554.894, 400.7, 282.7, 130.081, 1962., 70.551],
//! ]);
//! ]).unwrap();
//! let y = vec![
//! 83.0, 88.5, 88.2, 89.5, 96.2, 98.1, 99.0, 100.0, 101.2,
//! 104.6, 108.4, 110.8, 112.6, 114.2, 115.7, 116.9
Expand Down Expand Up @@ -574,7 +574,8 @@ mod tests {
&[502.601, 393.1, 251.4, 125.368, 1960., 69.564],
&[518.173, 480.6, 257.2, 127.852, 1961., 69.331],
&[554.894, 400.7, 282.7, 130.081, 1962., 70.551],
]);
])
.unwrap();
let y = vec![
83.0, 88.5, 88.2, 89.5, 96.2, 98.1, 99.0, 100.0, 101.2, 104.6, 108.4, 110.8, 112.6,
114.2, 115.7, 116.9,
Expand Down Expand Up @@ -648,7 +649,8 @@ mod tests {
&[502.601, 393.1, 251.4, 125.368, 1960., 69.564],
&[518.173, 480.6, 257.2, 127.852, 1961., 69.331],
&[554.894, 400.7, 282.7, 130.081, 1962., 70.551],
]);
])
.unwrap();
let y = vec![
83.0, 88.5, 88.2, 89.5, 96.2, 98.1, 99.0, 100.0, 101.2, 104.6, 108.4, 110.8, 112.6,
114.2, 115.7, 116.9,
Expand Down Expand Up @@ -702,7 +704,8 @@ mod tests {
&[502.601, 393.1, 251.4, 125.368, 1960., 69.564],
&[518.173, 480.6, 257.2, 127.852, 1961., 69.331],
&[554.894, 400.7, 282.7, 130.081, 1962., 70.551],
]);
])
.unwrap();
let y = vec![
83.0, 88.5, 88.2, 89.5, 96.2, 98.1, 99.0, 100.0, 101.2, 104.6, 108.4, 110.8, 112.6,
114.2, 115.7, 116.9,
Expand Down
Loading

0 comments on commit 239c004

Please sign in to comment.