Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [0.6.12]
### Fixed
- `xgboost/xgb_regressor.rs`: `XGRegressor::fit` no longer panics with `attempt to subtract with overflow` when `subsample` is less than 1.0 on a small dataset (#444). `floor(n_samples * subsample)` truncates to 0 rows. This occurs with 3 rows at a ratio of 0.3, or with 1 row at any ratio below 1.0. The tree fit then read `sorted_idxs.len() - 1` on an empty index set. The sample size now keeps a minimum of one row, as scikit-learn does for its own `subsample` parameter. Sample sizes of one row or more are unchanged.
- `xgboost/xgb_regressor.rs`: `XGRegressor::fit` no longer panics when `subsample` is less than 1.0 on a small dataset (#444). The sample for each tree now keeps a minimum of one row, as scikit-learn does for its own `subsample` parameter. Sample sizes of one row or more are unchanged.

## [0.6.11]
### Fixed
Expand Down
3 changes: 3 additions & 0 deletions src/algorithm/neighbour/cosinepair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use crate::numbers::realnum::RealNumber;

/// Parameters for CosinePair construction
#[derive(Debug, Clone)]
#[must_use]
pub struct CosinePairParameters {
/// Maximum number of neighbours returned by
/// [`CosinePair::query_row_top_k`] (default: all points). The build stays
Expand Down Expand Up @@ -395,6 +396,7 @@ impl<'a, T: RealNumber + FloatNumber + FloatCore, M: Array2<T>> CosinePair<'a, T

/// Find closest pair by scanning list of nearest neighbors.
#[allow(dead_code)]
#[must_use]
pub fn closest_pair(&self) -> PairwiseDistance<T> {
let mut a = self.neighbours[0]; // Start with first point
let mut d = self.distances[&a].distance;
Expand All @@ -416,6 +418,7 @@ impl<'a, T: RealNumber + FloatNumber + FloatCore, M: Array2<T>> CosinePair<'a, T
/// Return order dissimilarities from closest to furthest
///
#[allow(dead_code)]
#[must_use]
pub fn ordered_pairs(&self) -> std::vec::IntoIter<&PairwiseDistance<T>> {
// improvement: implement this to return `impl Iterator<Item = &PairwiseDistance<T>>`
// need to implement trait `Iterator` for `Vec<&PairwiseDistance<T>>`
Expand Down
2 changes: 2 additions & 0 deletions src/algorithm/neighbour/fastpair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ impl<'a, T: RealNumber + FloatNumber, M: Array2<T>> FastPair<'a, T, M> {

/// Find closest pair by scanning list of nearest neighbors.
#[allow(dead_code)]
#[must_use]
pub fn closest_pair(&self) -> PairwiseDistance<T> {
let mut a = self.neighbours[0]; // Start with first point
let mut d = self.distances[&a].distance;
Expand All @@ -177,6 +178,7 @@ impl<'a, T: RealNumber + FloatNumber, M: Array2<T>> FastPair<'a, T, M> {
/// Return order dissimilarities from closest to furthest
///
#[allow(dead_code)]
#[must_use]
pub fn ordered_pairs(&self) -> std::vec::IntoIter<&PairwiseDistance<T>> {
// improvement: implement this to return `impl Iterator<Item = &PairwiseDistance<T>>`
// need to implement trait `Iterator` for `Vec<&PairwiseDistance<T>>`
Expand Down
1 change: 1 addition & 0 deletions src/cluster/agglomerative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use crate::numbers::basenum::Number;

/// Parameters for the Agglomerative Clustering algorithm.
#[derive(Debug, Clone, Copy)]
#[must_use]
pub struct AgglomerativeClusteringParameters {
/// The number of clusters to find.
pub n_clusters: usize,
Expand Down
2 changes: 2 additions & 0 deletions src/cluster/dbscan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ pub struct DBSCAN<TX: Number, TY: Number, X: Array2<TX>, Y: Array1<TY>, D: Dista
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
/// DBSCAN clustering algorithm parameters
#[must_use]
pub struct DBSCANParameters<T: Number, D: Distance<Vec<T>>> {
#[cfg_attr(feature = "serde", serde(default))]
/// a function that defines a distance between each pair of point in training data.
Expand Down Expand Up @@ -124,6 +125,7 @@ impl<T: Number, D: Distance<Vec<T>>> DBSCANParameters<T, D> {
/// DBSCAN grid search parameters
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
#[must_use]
pub struct DBSCANSearchParameters<T: Number, D: Distance<Vec<T>>> {
#[cfg_attr(feature = "serde", serde(default))]
/// a function that defines a distance between each pair of point in training data.
Expand Down
2 changes: 2 additions & 0 deletions src/cluster/kmeans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ impl<TX: Number, TY: Number, X: Array2<TX>, Y: Array1<TY>> PartialEq for KMeans<
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
/// K-Means clustering algorithm parameters
#[must_use]
pub struct KMeansParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Number of clusters.
Expand Down Expand Up @@ -148,6 +149,7 @@ impl Default for KMeansParameters {
/// KMeans grid search parameters
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
#[must_use]
pub struct KMeansSearchParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Number of clusters.
Expand Down
1 change: 1 addition & 0 deletions src/dataset/boston.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use crate::dataset::Dataset;
use crate::dataset::deserialize_data;

/// Get dataset
#[must_use]
pub fn load_dataset() -> Dataset<f32, f32> {
let (x, y, num_samples, num_features) = match deserialize_data(std::include_bytes!("boston.xy"))
{
Expand Down
1 change: 1 addition & 0 deletions src/dataset/breast_cancer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use crate::dataset::Dataset;
use crate::dataset::deserialize_data;

/// Get dataset
#[must_use]
pub fn load_dataset() -> Dataset<f32, u32> {
let (x, y, num_samples, num_features) =
match deserialize_data(std::include_bytes!("breast_cancer.xy")) {
Expand Down
1 change: 1 addition & 0 deletions src/dataset/diabetes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use crate::dataset::Dataset;
use crate::dataset::deserialize_data;

/// Get dataset
#[must_use]
pub fn load_dataset() -> Dataset<f32, u32> {
let (x, y, num_samples, num_features) =
match deserialize_data(std::include_bytes!("diabetes.xy")) {
Expand Down
1 change: 1 addition & 0 deletions src/dataset/digits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::dataset::Dataset;
use crate::dataset::deserialize_data;

/// Get dataset
#[must_use]
pub fn load_dataset() -> Dataset<f32, f32> {
let (x, y, num_samples, num_features) = match deserialize_data(std::include_bytes!("digits.xy"))
{
Expand Down
3 changes: 3 additions & 0 deletions src/dataset/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ fn sample_normal(mean: f32, std: f32, rng: &mut impl rand::Rng) -> f32 {
}

/// Generate `num_centers` clusters of normally distributed points
#[must_use]
pub fn make_blobs(
num_samples: usize,
num_features: usize,
Expand Down Expand Up @@ -57,6 +58,7 @@ pub fn make_blobs(
}

/// Make a large circle containing a smaller circle in 2d.
#[must_use]
pub fn make_circles(num_samples: usize, factor: f32, noise: f32) -> Dataset<f32, u32> {
if !(0.0..1.0).contains(&factor) {
panic!("'factor' has to be between 0 and 1.");
Expand Down Expand Up @@ -97,6 +99,7 @@ pub fn make_circles(num_samples: usize, factor: f32, noise: f32) -> Dataset<f32,
}

/// Make two interleaving half circles in 2d
#[must_use]
pub fn make_moons(num_samples: usize, noise: f32) -> Dataset<f32, u32> {
let num_samples_out = num_samples / 2;
let num_samples_in = num_samples - num_samples_out;
Expand Down
1 change: 1 addition & 0 deletions src/dataset/iris.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::dataset::Dataset;
use crate::dataset::deserialize_data;

/// Get dataset
#[must_use]
pub fn load_dataset() -> Dataset<f32, u32> {
let (x, y, num_samples, num_features): (Vec<f32>, Vec<u32>, usize, usize) =
match deserialize_data(std::include_bytes!("iris.xy")) {
Expand Down
1 change: 1 addition & 0 deletions src/dataset/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub struct Dataset<X, Y> {

impl<X, Y> Dataset<X, Y> {
/// Reshape data into a two-dimensional matrix
#[must_use]
pub fn as_matrix(&self) -> Vec<Vec<&X>> {
let mut result: Vec<Vec<&X>> = Vec::with_capacity(self.num_samples);

Expand Down
2 changes: 2 additions & 0 deletions src/decomposition/pca.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ impl<T: Number + RealNumber, X: Array2<T> + SVDDecomposable<T> + EVDDecomposable
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
/// PCA parameters
#[must_use]
pub struct PCAParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Number of components to keep.
Expand Down Expand Up @@ -131,6 +132,7 @@ impl Default for PCAParameters {
/// PCA grid search parameters
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
#[must_use]
pub struct PCASearchParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Number of components to keep.
Expand Down
2 changes: 2 additions & 0 deletions src/decomposition/svd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ impl<T: Number + RealNumber, X: Array2<T> + SVDDecomposable<T> + EVDDecomposable
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
/// SVD parameters
#[must_use]
pub struct SVDParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Number of components to keep.
Expand All @@ -102,6 +103,7 @@ impl SVDParameters {
/// SVD grid search parameters
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
#[must_use]
pub struct SVDSearchParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Maximum number of iterations of the k-means algorithm for a single run.
Expand Down
1 change: 1 addition & 0 deletions src/ensemble/base_forest_regressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::tree::base_tree_regressor::{BaseTreeRegressor, BaseTreeRegressorParam
#[derive(Debug, Clone)]
/// Parameters of the Forest Regressor
/// Some parameters here are passed directly into base estimator.
#[must_use]
pub struct BaseForestRegressorParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Tree max depth. See [Decision Tree Regressor](../../tree/decision_tree_regressor/index.html)
Expand Down
1 change: 1 addition & 0 deletions src/ensemble/extra_trees_regressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ use crate::tree::base_tree_regressor::Splitter;
#[derive(Debug, Clone)]
/// Parameters of the Extra Trees Regressor
/// Some parameters here are passed directly into base estimator.
#[must_use]
pub struct ExtraTreesRegressorParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Tree max depth. See [Decision Tree Regressor](../../tree/decision_tree_regressor/index.html)
Expand Down
2 changes: 2 additions & 0 deletions src/ensemble/random_forest_classifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ use crate::tree::decision_tree_classifier::{
/// Some parameters here are passed directly into base estimator.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
#[must_use]
pub struct RandomForestClassifierParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Split criteria to use when building a tree. See [Decision Tree Classifier](../../tree/decision_tree_classifier/index.html)
Expand Down Expand Up @@ -218,6 +219,7 @@ impl<TX: Number + FloatNumber + PartialOrd, TY: Number + Ord, X: Array2<TX>, Y:
/// RandomForestClassifier grid search parameters
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
#[must_use]
pub struct RandomForestClassifierSearchParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Split criteria to use when building a tree. See [Decision Tree Classifier](../../tree/decision_tree_classifier/index.html)
Expand Down
2 changes: 2 additions & 0 deletions src/ensemble/random_forest_regressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ use crate::tree::base_tree_regressor::Splitter;
#[derive(Debug, Clone)]
/// Parameters of the Random Forest Regressor
/// Some parameters here are passed directly into base estimator.
#[must_use]
pub struct RandomForestRegressorParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Tree max depth. See [Decision Tree Regressor](../../tree/decision_tree_regressor/index.html)
Expand Down Expand Up @@ -184,6 +185,7 @@ impl<TX: Number + FloatNumber + PartialOrd, TY: Number, X: Array2<TX>, Y: Array1
/// RandomForestRegressor grid search parameters
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
#[must_use]
pub struct RandomForestRegressorSearchParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Tree max depth. See [Decision Tree Classifier](../../tree/decision_tree_classifier/index.html)
Expand Down
7 changes: 7 additions & 0 deletions src/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,21 @@ pub enum FailedError {
impl Failed {
///get type of error
#[inline]
#[must_use]
pub fn error(&self) -> FailedError {
self.err
}

/// new instance of `FailedError::FitError`
#[must_use]
pub fn fit(msg: &str) -> Self {
Failed {
err: FailedError::FitFailed,
msg: msg.to_string(),
}
}
/// new instance of `FailedError::PredictFailed`
#[must_use]
pub fn predict(msg: &str) -> Self {
Failed {
err: FailedError::PredictFailed,
Expand All @@ -59,6 +62,7 @@ impl Failed {
}

/// new instance of `FailedError::TransformFailed`
#[must_use]
pub fn transform(msg: &str) -> Self {
Failed {
err: FailedError::TransformFailed,
Expand All @@ -67,6 +71,7 @@ impl Failed {
}

/// new instance of `FailedError::ParametersError`
#[must_use]
pub fn input(msg: &str) -> Self {
Failed {
err: FailedError::ParametersError,
Expand All @@ -75,6 +80,7 @@ impl Failed {
}

/// new instance of `FailedError::InvalidStateError`
#[must_use]
pub fn invalid_state(msg: &str) -> Self {
Failed {
err: FailedError::InvalidStateError,
Expand All @@ -83,6 +89,7 @@ impl Failed {
}

/// new instance of `err`
#[must_use]
pub fn because(err: FailedError, msg: &str) -> Self {
Failed {
err,
Expand Down
7 changes: 7 additions & 0 deletions src/linalg/basic/arrays.rs
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,7 @@ pub trait Array1<T: Debug + Display + Copy + Sized>: MutArrayView1<T> + Sized +
where
Self: Sized;
/// create a zero array
#[must_use]
fn zeros(len: usize) -> Self
where
T: Number,
Expand All @@ -813,6 +814,7 @@ pub trait Array1<T: Debug + Display + Copy + Sized>: MutArrayView1<T> + Sized +
Self::fill(len, T::zero())
}
/// create an array of ones
#[must_use]
fn ones(len: usize) -> Self
where
T: Number,
Expand All @@ -821,6 +823,7 @@ pub trait Array1<T: Debug + Display + Copy + Sized>: MutArrayView1<T> + Sized +
Self::fill(len, T::one())
}
/// create an array of random values
#[must_use]
fn rand(len: usize) -> Self
where
T: RealNumber,
Expand Down Expand Up @@ -1043,20 +1046,23 @@ pub trait Array2<T: Debug + Display + Copy + Sized>: MutArrayView2<T> + Sized +
where
Self: Sized;
/// create a zero 2d array
#[must_use]
fn zeros(nrows: usize, ncols: usize) -> Self
where
T: Number,
{
Self::fill(nrows, ncols, T::zero())
}
/// create a 2d array of ones
#[must_use]
fn ones(nrows: usize, ncols: usize) -> Self
where
T: Number,
{
Self::fill(nrows, ncols, T::one())
}
/// create an identity matrix
#[must_use]
fn eye(size: usize) -> Self
where
T: Number,
Expand All @@ -1070,6 +1076,7 @@ pub trait Array2<T: Debug + Display + Copy + Sized>: MutArrayView2<T> + Sized +
matrix
}
/// create a 2d array of random values
#[must_use]
fn rand(nrows: usize, ncols: usize) -> Self
where
T: RealNumber,
Expand Down
1 change: 1 addition & 0 deletions src/linalg/ndarray/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ impl<T: Debug + Display + Copy> DenseMatrix<T> {
/// assert_eq!(matrix.shape(), (3, 4));
/// assert_eq!(*matrix.get((1, 2)), 6.0);
/// ```
#[must_use]
pub fn from_ndarray2(a: &ndarray::Array2<T>) -> Self {
// iter() yields logical row-major order regardless of memory layout.
Self::from_iterator(a.iter().copied(), a.nrows(), a.ncols(), ROW_MAJOR_AXIS)
Expand Down
2 changes: 2 additions & 0 deletions src/linear/elastic_net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ use crate::linear::lasso_optimizer::InteriorPointOptimizer;
/// Elastic net parameters
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
#[must_use]
pub struct ElasticNetParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Regularization parameter.
Expand Down Expand Up @@ -147,6 +148,7 @@ impl Default for ElasticNetParameters {
/// ElasticNet grid search parameters
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
#[must_use]
pub struct ElasticNetSearchParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Regularization parameter.
Expand Down
2 changes: 2 additions & 0 deletions src/linear/lasso.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use crate::numbers::realnum::RealNumber;
/// Lasso regression parameters
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
#[must_use]
pub struct LassoParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Controls the strength of the penalty to the loss function.
Expand Down Expand Up @@ -151,6 +152,7 @@ impl<TX: FloatNumber + RealNumber, TY: Number, X: Array2<TX>, Y: Array1<TY>> Pre
/// Lasso grid search parameters
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, Clone)]
#[must_use]
pub struct LassoSearchParameters {
#[cfg_attr(feature = "serde", serde(default))]
/// Controls the strength of the penalty to the loss function.
Expand Down
Loading
Loading