From 291b30ce48a074a84946ca7a5b351a50755006a1 Mon Sep 17 00:00:00 2001 From: Hubert Majewski <36614010+HubertMajewski@users.noreply.github.com> Date: Thu, 9 Jul 2026 03:58:52 +0000 Subject: [PATCH] Add getter for parameters in all model structs. --- src/cluster/agglomerative.rs | 11 +++++++++++ src/cluster/dbscan.rs | 13 ++++++++++++- src/cluster/kmeans.rs | 11 +++++++++++ src/decomposition/pca.rs | 11 +++++++++++ src/decomposition/svd.rs | 11 +++++++++++ src/ensemble/extra_trees_regressor.rs | 12 ++++++++++++ src/ensemble/random_forest_classifier.rs | 12 ++++++++++++ src/ensemble/random_forest_regressor.rs | 12 ++++++++++++ src/linear/elastic_net.rs | 12 ++++++++++++ src/linear/lasso.rs | 12 ++++++++++++ src/linear/linear_regression.rs | 12 ++++++++++++ src/linear/logistic_regression.rs | 13 +++++++++++++ src/linear/ridge_regression.rs | 12 ++++++++++++ src/naive_bayes/bernoulli.rs | 20 ++++++++++++++++---- src/naive_bayes/categorical.rs | 15 +++++++++++++-- src/naive_bayes/gaussian.rs | 17 ++++++++++++++--- src/naive_bayes/multinomial.rs | 17 ++++++++++++++--- src/neighbors/knn_classifier.rs | 18 +++++++++++++++--- src/neighbors/knn_regressor.rs | 18 +++++++++++++++--- src/svm/svc.rs | 11 ++++++++++- src/svm/svr.rs | 9 +++++++++ src/tree/base_tree_regressor.rs | 8 ++++++-- src/tree/decision_tree_classifier.rs | 10 +++++++--- src/tree/decision_tree_regressor.rs | 14 +++++++++++++- src/xgboost/xgb_regressor.rs | 9 +++++++++ 25 files changed, 294 insertions(+), 26 deletions(-) diff --git a/src/cluster/agglomerative.rs b/src/cluster/agglomerative.rs index 373f6f95..b9936b0e 100644 --- a/src/cluster/agglomerative.rs +++ b/src/cluster/agglomerative.rs @@ -76,6 +76,7 @@ impl Default for AgglomerativeClusteringParameters { pub struct AgglomerativeClustering, Y: Array1> { /// The cluster label assigned to each sample. pub labels: Vec, + parameters: Option, _phantom_tx: PhantomData, _phantom_ty: PhantomData, _phantom_x: PhantomData, @@ -176,12 +177,22 @@ impl, Y: Array1> AgglomerativeClusteri } Ok(AgglomerativeClustering { labels, + parameters: Some(parameters), _phantom_tx: PhantomData, _phantom_ty: PhantomData, _phantom_x: PhantomData, _phantom_y: PhantomData, }) } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &AgglomerativeClusteringParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } impl, Y: Array1> diff --git a/src/cluster/dbscan.rs b/src/cluster/dbscan.rs index 2e2aac10..6bf13005 100644 --- a/src/cluster/dbscan.rs +++ b/src/cluster/dbscan.rs @@ -64,6 +64,7 @@ pub struct DBSCAN, Y: Array1, D: Dista num_classes: usize, knn_algorithm: KNNAlgorithm, eps: f64, + parameters: Option>, _phantom_ty: PhantomData, _phantom_x: PhantomData, _phantom_y: PhantomData, @@ -295,7 +296,7 @@ impl, Y: Array1, D: Distance>> x.row_iter() .map(|row| row.iterator(0).cloned().collect()) .collect(), - parameters.distance, + parameters.distance.clone(), )?; let mut row = vec![TX::zero(); x.shape().1]; @@ -353,6 +354,7 @@ impl, Y: Array1, D: Distance>> num_classes: k as usize, knn_algorithm: algo, eps: parameters.eps, + parameters: Some(parameters), _phantom_ty: PhantomData, _phantom_x: PhantomData, _phantom_y: PhantomData, @@ -392,6 +394,15 @@ impl, Y: Array1, D: Distance>> Ok(result) } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &DBSCANParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/cluster/kmeans.rs b/src/cluster/kmeans.rs index b81ffd7e..f5f683f6 100644 --- a/src/cluster/kmeans.rs +++ b/src/cluster/kmeans.rs @@ -76,6 +76,7 @@ pub struct KMeans, Y: Array1> { size: Vec, _distortion: f64, centroids: Vec>, + parameters: Option, _phantom_tx: PhantomData, _phantom_ty: PhantomData, _phantom_x: PhantomData, @@ -315,6 +316,7 @@ impl, Y: Array1> KMeans size, _distortion: distortion, centroids, + parameters: Some(parameters), _phantom_tx: PhantomData, _phantom_ty: PhantomData, _phantom_x: PhantomData, @@ -411,6 +413,15 @@ impl, Y: Array1> KMeans y } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &KMeansParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/decomposition/pca.rs b/src/decomposition/pca.rs index 11853648..0dd2b62e 100644 --- a/src/decomposition/pca.rs +++ b/src/decomposition/pca.rs @@ -65,6 +65,7 @@ pub struct PCA + SVDDecomposable + EVDDe eigenvectors: X, eigenvalues: Vec, projection: X, + parameters: Option, mu: Vec, pmu: Vec, } @@ -329,6 +330,7 @@ impl + SVDDecomposable + EVDDecomposable eigenvectors, eigenvalues, projection: projection.transpose(), + parameters: Some(parameters), mu, pmu, }) @@ -360,6 +362,15 @@ impl + SVDDecomposable + EVDDecomposable pub fn components(&self) -> &X { &self.projection } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &PCAParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/decomposition/svd.rs b/src/decomposition/svd.rs index 259bfbc0..524b0f17 100644 --- a/src/decomposition/svd.rs +++ b/src/decomposition/svd.rs @@ -62,6 +62,7 @@ use crate::numbers::realnum::RealNumber; #[derive(Debug)] pub struct SVD + SVDDecomposable + EVDDecomposable> { components: X, + parameters: Option, phantom: PhantomData, } @@ -190,6 +191,7 @@ impl + SVDDecomposable + EVDDecomposable Ok(SVD { components, + parameters: Some(parameters), phantom: PhantomData, }) } @@ -212,6 +214,15 @@ impl + SVDDecomposable + EVDDecomposable pub fn components(&self) -> &X { &self.components } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &SVDParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/ensemble/extra_trees_regressor.rs b/src/ensemble/extra_trees_regressor.rs index 818ac6c7..bb5a9efa 100644 --- a/src/ensemble/extra_trees_regressor.rs +++ b/src/ensemble/extra_trees_regressor.rs @@ -104,6 +104,7 @@ pub struct ExtraTreesRegressor< Y: Array1, > { forest_regressor: Option>, + parameters: Option } impl ExtraTreesRegressorParameters { @@ -165,6 +166,7 @@ impl, Y: Array1 fn new() -> Self { Self { forest_regressor: Option::None, + parameters: Option::None } } @@ -207,6 +209,7 @@ impl, Y: Array1 Ok(ExtraTreesRegressor { forest_regressor: Some(forest_regressor), + parameters: Some(parameters) }) } @@ -222,6 +225,15 @@ impl, Y: Array1 let forest_regressor = self.forest_regressor.as_ref().unwrap(); forest_regressor.predict_oob(x) } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &ExtraTreesRegressorParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/ensemble/random_forest_classifier.rs b/src/ensemble/random_forest_classifier.rs index 0f86a4df..1a8478a7 100644 --- a/src/ensemble/random_forest_classifier.rs +++ b/src/ensemble/random_forest_classifier.rs @@ -107,6 +107,7 @@ pub struct RandomForestClassifier< trees: Option>>, classes: Option>, samples: Option>>, + parameters: Option } impl RandomForestClassifierParameters { @@ -200,6 +201,7 @@ impl, Y: trees: Option::None, classes: Option::None, samples: Option::None, + parameters: Option::None, } } fn fit(x: &X, y: &Y, parameters: RandomForestClassifierParameters) -> Result { @@ -506,6 +508,7 @@ impl, Y: Array1, Y: Array1 &RandomForestClassifierParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/ensemble/random_forest_regressor.rs b/src/ensemble/random_forest_regressor.rs index 0a8a888c..023e0757 100644 --- a/src/ensemble/random_forest_regressor.rs +++ b/src/ensemble/random_forest_regressor.rs @@ -95,6 +95,7 @@ pub struct RandomForestRegressor< Y: Array1, > { forest_regressor: Option>, + parameters: Option } impl RandomForestRegressorParameters { @@ -165,6 +166,7 @@ impl, Y: Array1 fn new() -> Self { Self { forest_regressor: Option::None, + parameters: Option::None, } } @@ -399,6 +401,7 @@ impl, Y: Array1 Ok(RandomForestRegressor { forest_regressor: Some(forest_regressor), + parameters: Some(parameters) }) } @@ -414,6 +417,15 @@ impl, Y: Array1 let forest_regressor = self.forest_regressor.as_ref().unwrap(); forest_regressor.predict_oob(x) } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &RandomForestRegressorParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/linear/elastic_net.rs b/src/linear/elastic_net.rs index d5b1d4d5..dae81843 100644 --- a/src/linear/elastic_net.rs +++ b/src/linear/elastic_net.rs @@ -98,6 +98,7 @@ pub struct ElasticNetParameters { pub struct ElasticNet, Y: Array1> { coefficients: Option, intercept: Option, + parameters: Option, _phantom_ty: PhantomData, _phantom_y: PhantomData, } @@ -288,6 +289,7 @@ impl, Y: Array1> Self { coefficients: Option::None, intercept: Option::None, + parameters: Option::None, _phantom_ty: PhantomData, _phantom_y: PhantomData, } @@ -385,6 +387,7 @@ impl, Y: Array1> Ok(ElasticNet { intercept: Some(b), coefficients: Some(w), + parameters: Some(parameters), _phantom_ty: PhantomData, _phantom_y: PhantomData, }) @@ -459,6 +462,15 @@ impl, Y: Array1> (x2, y2, gamma) } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &ElasticNetParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/linear/lasso.rs b/src/linear/lasso.rs index 59c60ddc..cbe922f7 100644 --- a/src/linear/lasso.rs +++ b/src/linear/lasso.rs @@ -64,6 +64,7 @@ pub struct LassoParameters { pub struct Lasso, Y: Array1> { coefficients: Option, intercept: Option, + parameters: Option, _phantom_ty: PhantomData, _phantom_y: PhantomData, } @@ -130,6 +131,7 @@ impl, Y: Array1> Self { coefficients: None, intercept: None, + parameters: None, _phantom_ty: PhantomData, _phantom_y: PhantomData, } @@ -352,6 +354,7 @@ impl, Y: Array1> Las Ok(Lasso { intercept: b, coefficients: Some(w), + parameters: Some(parameters), _phantom_ty: PhantomData, _phantom_y: PhantomData, }) @@ -402,6 +405,15 @@ impl, Y: Array1> Las scaled_x.scale_mut(&col_mean, &col_std, 0); Ok((scaled_x, col_mean, col_std)) } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &LassoParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/linear/linear_regression.rs b/src/linear/linear_regression.rs index 43410bbb..f65c9434 100644 --- a/src/linear/linear_regression.rs +++ b/src/linear/linear_regression.rs @@ -113,6 +113,7 @@ pub struct LinearRegression< > { coefficients: Option, intercept: Option, + parameters: Option, _phantom_ty: PhantomData, _phantom_y: PhantomData, } @@ -209,6 +210,7 @@ impl< Self { coefficients: Option::None, intercept: Option::None, + parameters: Option::None, _phantom_ty: PhantomData, _phantom_y: PhantomData, } @@ -274,6 +276,7 @@ impl< Ok(LinearRegression { intercept: Some(*w.get((num_attributes, 0))), coefficients: Some(weights), + parameters: Some(parameters), _phantom_ty: PhantomData, _phantom_y: PhantomData, }) @@ -301,6 +304,15 @@ impl< pub fn intercept(&self) -> &TX { self.intercept.as_ref().unwrap() } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &LinearRegressionParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/linear/logistic_regression.rs b/src/linear/logistic_regression.rs index c28dc347..1d4a7177 100644 --- a/src/linear/logistic_regression.rs +++ b/src/linear/logistic_regression.rs @@ -178,6 +178,7 @@ pub struct LogisticRegression< classes: Option>, num_attributes: usize, num_classes: usize, + parameters: Option>, _phantom_tx: PhantomData, _phantom_y: PhantomData, } @@ -389,6 +390,7 @@ impl, Y: classes: Option::None, num_attributes: 0, num_classes: 0, + parameters: Option::None, _phantom_tx: PhantomData, _phantom_y: PhantomData, } @@ -465,6 +467,7 @@ impl, Y: classes: Some(classes), num_attributes, num_classes: k, + parameters: Some(parameters), _phantom_tx: PhantomData, _phantom_y: PhantomData, }) @@ -491,6 +494,7 @@ impl, Y: classes: Some(classes), num_attributes, num_classes: k, + parameters: Some(parameters), _phantom_tx: PhantomData, _phantom_y: PhantomData, }) @@ -560,6 +564,15 @@ impl, Y: optimizer.optimize(&f, &df, &x0, &ls) } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &LogisticRegressionParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/linear/ridge_regression.rs b/src/linear/ridge_regression.rs index be2f3d41..e03f476a 100644 --- a/src/linear/ridge_regression.rs +++ b/src/linear/ridge_regression.rs @@ -192,6 +192,7 @@ pub struct RidgeRegression< > { coefficients: Option, intercept: Option, + parameters: Option>, _phantom_ty: PhantomData, _phantom_y: PhantomData, } @@ -253,6 +254,7 @@ impl< Self { coefficients: Option::None, intercept: Option::None, + parameters: Option::None, _phantom_ty: PhantomData, _phantom_y: PhantomData, } @@ -360,6 +362,7 @@ impl< Ok(RidgeRegression { intercept: Some(b), coefficients: Some(w), + parameters: Some(parameters), _phantom_ty: PhantomData, _phantom_y: PhantomData, }) @@ -409,6 +412,15 @@ impl< pub fn intercept(&self) -> &TX { self.intercept.as_ref().unwrap() } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &RidgeRegressionParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/naive_bayes/bernoulli.rs b/src/naive_bayes/bernoulli.rs index cdd5b83d..1e0bcd2c 100644 --- a/src/naive_bayes/bernoulli.rs +++ b/src/naive_bayes/bernoulli.rs @@ -127,7 +127,7 @@ impl NBDistribution /// `BernoulliNB` parameters. Use `Default::default()` for default values. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct BernoulliNBParameters { #[cfg_attr(feature = "serde", serde(default))] /// Additive (Laplace/Lidstone) smoothing parameter (0 for no smoothing). @@ -357,6 +357,7 @@ pub struct BernoulliNB< > { inner: Option>>, binarize: Option, + parameters: Option> } impl, Y: Array1> @@ -380,6 +381,7 @@ impl, Y: Arr Self { inner: Option::None, binarize: Option::None, + parameters: Option::None } } @@ -410,17 +412,18 @@ impl, Y: Arr BernoulliNBDistribution::fit( &Self::binarize(x, threshold), y, - parameters.alpha, - parameters.priors, + parameters.alpha.clone(), + parameters.priors.clone(), )? } else { - BernoulliNBDistribution::fit(x, y, parameters.alpha, parameters.priors)? + BernoulliNBDistribution::fit(x, y, parameters.alpha.clone(), parameters.priors.clone())? }; let inner = BaseNaiveBayes::fit(distribution)?; Ok(Self { inner: Some(inner), binarize: parameters.binarize, + parameters: Some(parameters) }) } @@ -485,6 +488,15 @@ impl, Y: Arr Self::binarize_mut(&mut new_x, threshold); new_x } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &BernoulliNBParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/naive_bayes/categorical.rs b/src/naive_bayes/categorical.rs index b60ee0d3..80c27fa7 100644 --- a/src/naive_bayes/categorical.rs +++ b/src/naive_bayes/categorical.rs @@ -257,7 +257,7 @@ impl CategoricalNBDistribution { /// `CategoricalNB` parameters. Use `Default::default()` for default values. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct CategoricalNBParameters { #[cfg_attr(feature = "serde", serde(default))] /// Additive (Laplace/Lidstone) smoothing parameter (0 for no smoothing). @@ -338,6 +338,7 @@ impl Default for CategoricalNBSearchParameters { #[derive(Debug, PartialEq)] pub struct CategoricalNB, Y: Array1> { inner: Option>>, + parameters: Option } impl, Y: Array1> @@ -346,6 +347,7 @@ impl, Y: Array1> fn new() -> Self { Self { inner: Option::None, + parameters: Option::None } } @@ -370,7 +372,7 @@ impl, Y: Array1> CategoricalNB { let alpha = parameters.alpha; let distribution = CategoricalNBDistribution::fit(x, y, alpha)?; let inner = BaseNaiveBayes::fit(distribution)?; - Ok(Self { inner: Some(inner) }) + Ok(Self { inner: Some(inner), parameters: Some(parameters) }) } /// Estimates the class labels for the provided data. @@ -415,6 +417,15 @@ impl, Y: Array1> CategoricalNB { pub fn feature_log_prob(&self) -> &Vec>> { &self.inner.as_ref().unwrap().distribution.coefficients } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &CategoricalNBParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/naive_bayes/gaussian.rs b/src/naive_bayes/gaussian.rs index dbf3fd81..3b93fa2a 100644 --- a/src/naive_bayes/gaussian.rs +++ b/src/naive_bayes/gaussian.rs @@ -92,7 +92,7 @@ impl NBDistribution /// `GaussianNB` parameters. Use `Default::default()` for default values. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[derive(Debug, Default, Clone)] +#[derive(Debug, Default, Clone, PartialEq)] pub struct GaussianNBParameters { #[cfg_attr(feature = "serde", serde(default))] /// Prior probabilities of the classes. If specified the priors are not adjusted according to the data @@ -266,6 +266,7 @@ pub struct GaussianNB< Y: Array1, > { inner: Option>>, + parameters: Option } impl< @@ -291,6 +292,7 @@ impl< fn new() -> Self { Self { inner: Option::None, + parameters: Option::None, } } @@ -320,9 +322,9 @@ impl, Y: Arr /// * `y` - vector with target values (classes) of length N. /// * `parameters` - additional parameters like class priors. pub fn fit(x: &X, y: &Y, parameters: GaussianNBParameters) -> Result { - let distribution = GaussianNBDistribution::fit(x, y, parameters.priors)?; + let distribution = GaussianNBDistribution::fit(x, y, parameters.priors.clone())?; let inner = BaseNaiveBayes::fit(distribution)?; - Ok(Self { inner: Some(inner) }) + Ok(Self { inner: Some(inner), parameters: Some(parameters) }) } /// Estimates the class labels for the provided data. @@ -362,6 +364,15 @@ impl, Y: Arr pub fn var(&self) -> &Vec> { &self.inner.as_ref().unwrap().distribution.var } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &GaussianNBParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/naive_bayes/multinomial.rs b/src/naive_bayes/multinomial.rs index ad873943..58d043e5 100644 --- a/src/naive_bayes/multinomial.rs +++ b/src/naive_bayes/multinomial.rs @@ -99,7 +99,7 @@ impl NBDistribution /// `MultinomialNB` parameters. Use `Default::default()` for default values. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq)] pub struct MultinomialNBParameters { #[cfg_attr(feature = "serde", serde(default))] /// Additive (Laplace/Lidstone) smoothing parameter (0 for no smoothing). @@ -302,6 +302,7 @@ pub struct MultinomialNB< Y: Array1, > { inner: Option>>, + parameters: Option } impl, Y: Array1> fmt::Display @@ -323,6 +324,7 @@ impl, Y: Array fn new() -> Self { Self { inner: Option::None, + parameters: Option::None } } @@ -350,9 +352,9 @@ impl, Y: Array /// binarizing threshold. pub fn fit(x: &X, y: &Y, parameters: MultinomialNBParameters) -> Result { let distribution = - MultinomialNBDistribution::fit(x, y, parameters.alpha, parameters.priors)?; + MultinomialNBDistribution::fit(x, y, parameters.alpha.clone(), parameters.priors.clone())?; let inner = BaseNaiveBayes::fit(distribution)?; - Ok(Self { inner: Some(inner) }) + Ok(Self { inner: Some(inner), parameters: Some(parameters) }) } /// Estimates the class labels for the provided data. @@ -391,6 +393,15 @@ impl, Y: Array pub fn feature_count(&self) -> &Vec> { &self.inner.as_ref().unwrap().distribution.feature_count } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &MultinomialNBParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/neighbors/knn_classifier.rs b/src/neighbors/knn_classifier.rs index 264ab0e2..2cfa781e 100644 --- a/src/neighbors/knn_classifier.rs +++ b/src/neighbors/knn_classifier.rs @@ -83,6 +83,7 @@ pub struct KNNClassifier< knn_algorithm: Option>, weight: Option, k: Option, + parameters: Option>, _phantom_tx: PhantomData, _phantom_x: PhantomData, _phantom_y: PhantomData, @@ -188,6 +189,7 @@ impl, Y: Array1, D: Distance, Y: Array1, D: Distance, Y: Array1, D: Distance &KNNClassifierParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/neighbors/knn_regressor.rs b/src/neighbors/knn_regressor.rs index b49743f8..a97c6684 100644 --- a/src/neighbors/knn_regressor.rs +++ b/src/neighbors/knn_regressor.rs @@ -80,6 +80,7 @@ pub struct KNNRegressor, Y: Array1, D: knn_algorithm: Option>, weight: Option, k: Option, + parameters: Option>, _phantom_tx: PhantomData, _phantom_ty: PhantomData, _phantom_x: PhantomData, @@ -179,6 +180,7 @@ impl, Y: Array1, D: Distance>> knn_algorithm: Option::None, weight: Option::None, k: Option::None, + parameters: Option::None, _phantom_tx: PhantomData, _phantom_ty: PhantomData, _phantom_x: PhantomData, @@ -231,13 +233,14 @@ impl, Y: Array1, D: Distance>> ))); } - let knn_algo = parameters.algorithm.fit(data, parameters.distance)?; + let knn_algo = parameters.algorithm.fit(data, parameters.distance.clone())?; Ok(KNNRegressor { y: Some(y.clone()), - k: Some(parameters.k), + k: Some(parameters.k.clone()), knn_algorithm: Some(knn_algo), - weight: Some(parameters.weight), + weight: Some(parameters.weight.clone()), + parameters: Some(parameters), _phantom_tx: PhantomData, _phantom_ty: PhantomData, _phantom_x: PhantomData, @@ -277,6 +280,15 @@ impl, Y: Array1, D: Distance>> Ok(result) } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &KNNRegressorParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/svm/svc.rs b/src/svm/svc.rs index d72ecdac..692d3ef7 100644 --- a/src/svm/svc.rs +++ b/src/svm/svc.rs @@ -292,7 +292,7 @@ pub struct SVCParameters, /// Controls the pseudo random number generation for shuffling the data for probability estimates - seed: Option, + pub seed: Option, } #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -608,6 +608,15 @@ impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2 + 'a, Y: Array f } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &SVCParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } impl, Y: Array1> PartialEq diff --git a/src/svm/svr.rs b/src/svm/svr.rs index e912743b..679a77a3 100644 --- a/src/svm/svr.rs +++ b/src/svm/svr.rs @@ -280,6 +280,15 @@ impl<'a, T: Number + FloatNumber + PartialOrd, X: Array2, Y: Array1> SVR<' T::from(f).unwrap() } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &SVRParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } impl, Y: Array1> PartialEq diff --git a/src/tree/base_tree_regressor.rs b/src/tree/base_tree_regressor.rs index f84ae7e9..2230e8a1 100644 --- a/src/tree/base_tree_regressor.rs +++ b/src/tree/base_tree_regressor.rs @@ -63,9 +63,13 @@ impl, Y: Array1> fn nodes(&self) -> &Vec { self.nodes.as_ref() } - /// Get parameters, return a shared reference + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model fn parameters(&self) -> &BaseTreeRegressorParameters { - self.parameters.as_ref().unwrap() + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() } /// Get estimate of intercept, return value fn depth(&self) -> u16 { diff --git a/src/tree/decision_tree_classifier.rs b/src/tree/decision_tree_classifier.rs index 96007677..2a2e7859 100644 --- a/src/tree/decision_tree_classifier.rs +++ b/src/tree/decision_tree_classifier.rs @@ -131,9 +131,13 @@ impl, Y: Array1> fn nodes(&self) -> &Vec { self.nodes.as_ref() } - /// Get parameters, return a shared reference - fn parameters(&self) -> &DecisionTreeClassifierParameters { - self.parameters.as_ref().unwrap() + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &DecisionTreeClassifierParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() } /// get classes vector, return a shared reference fn classes(&self) -> &Vec { diff --git a/src/tree/decision_tree_regressor.rs b/src/tree/decision_tree_regressor.rs index 86b99343..ebfc1d8f 100644 --- a/src/tree/decision_tree_regressor.rs +++ b/src/tree/decision_tree_regressor.rs @@ -94,6 +94,7 @@ pub struct DecisionTreeRegressorParameters { pub struct DecisionTreeRegressor, Y: Array1> { tree_regressor: Option>, + parameters: Option } impl DecisionTreeRegressorParameters { @@ -271,7 +272,8 @@ impl, Y: Array1> { fn new() -> Self { Self { - tree_regressor: None, + tree_regressor: Option::None, + parameters: Option::None } } @@ -309,6 +311,7 @@ impl, Y: Array1> let tree = BaseTreeRegressor::fit(x, y, tree_parameters)?; Ok(Self { tree_regressor: Some(tree), + parameters: Some(parameters) }) } @@ -317,6 +320,15 @@ impl, Y: Array1> pub fn predict(&self, x: &X) -> Result { self.tree_regressor.as_ref().unwrap().predict(x) } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &DecisionTreeRegressorParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } #[cfg(test)] diff --git a/src/xgboost/xgb_regressor.rs b/src/xgboost/xgb_regressor.rs index a3b9bf0a..92a3f4f0 100644 --- a/src/xgboost/xgb_regressor.rs +++ b/src/xgboost/xgb_regressor.rs @@ -609,6 +609,15 @@ impl, Y: Array1> XGRegres indices.truncate((population_size as f64 * subsample_ratio) as usize); indices } + + /// Getter for parameters used in the model + /// + /// # Returns + /// Parameters used to setup the model + pub fn parameters(&self) -> &XGRegressorParameters { + assert!(self.parameters.is_some()); + &self.parameters.as_ref().unwrap() + } } // Boilerplate implementation for the smartcore traits