Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: do not require an empty struct in cross_validate to define … #231

Open
wants to merge 2 commits into
base: development
Choose a base branch
from
Open
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
8 changes: 0 additions & 8 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ pub trait UnsupervisedEstimator<X, P> {

/// An estimator for supervised learning, that provides method `fit` to learn from data and training values
pub trait SupervisedEstimator<X, Y, P>: Predictor<X, Y> {
/// Empty constructor, instantiate an empty estimator. Object is dropped as soon as `fit()` is called.
/// used to pass around the correct `fit()` implementation.
/// by calling `::fit()`. mostly used to be used with `model_selection::cross_validate(...)`
fn new() -> Self;
/// Fit a model to a training dataset, estimate model's parameters.
/// * `x` - _NxM_ matrix with _N_ observations and _M_ features in each observation.
/// * `y` - target training values of size _N_.
Expand All @@ -36,10 +32,6 @@ pub trait SupervisedEstimator<X, Y, P>: Predictor<X, Y> {
/// In this one parameters are borrowed instead of moved, this is useful for parameters that carry
/// references. Also to be used when there is no predictor attached to the estimator.
pub trait SupervisedEstimatorBorrow<'a, X, Y, P> {
/// Empty constructor, instantiate an empty estimator. Object is dropped as soon as `fit()` is called.
/// used to pass around the correct `fit()` implementation.
/// by calling `::fit()`. mostly used to be used with `model_selection::cross_validate(...)`
fn new() -> Self;
/// Fit a model to a training dataset, estimate model's parameters.
/// * `x` - _NxM_ matrix with _N_ observations and _M_ features in each observation.
/// * `y` - target training values of size _N_.
Expand Down
8 changes: 0 additions & 8 deletions src/ensemble/random_forest_classifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,6 @@ impl<TX: Number + FloatNumber + PartialOrd, TY: Number + Ord, X: Array2<TX>, Y:
SupervisedEstimator<X, Y, RandomForestClassifierParameters>
for RandomForestClassifier<TX, TY, X, Y>
{
fn new() -> Self {
Self {
parameters: Option::None,
trees: Option::None,
classes: Option::None,
samples: Option::None,
}
}
fn fit(x: &X, y: &Y, parameters: RandomForestClassifierParameters) -> Result<Self, Failed> {
RandomForestClassifier::fit(x, y, parameters)
}
Expand Down
8 changes: 0 additions & 8 deletions src/ensemble/random_forest_regressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,6 @@ impl<TX: Number + FloatNumber + PartialOrd, TY: Number, X: Array2<TX>, Y: Array1
SupervisedEstimator<X, Y, RandomForestRegressorParameters>
for RandomForestRegressor<TX, TY, X, Y>
{
fn new() -> Self {
Self {
parameters: Option::None,
trees: Option::None,
samples: Option::None,
}
}

fn fit(x: &X, y: &Y, parameters: RandomForestRegressorParameters) -> Result<Self, Failed> {
RandomForestRegressor::fit(x, y, parameters)
}
Expand Down
9 changes: 0 additions & 9 deletions src/linear/elastic_net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,15 +284,6 @@ impl<TX: FloatNumber + RealNumber, TY: Number, X: Array2<TX>, Y: Array1<TY>> Par
impl<TX: FloatNumber + RealNumber, TY: Number, X: Array2<TX>, Y: Array1<TY>>
SupervisedEstimator<X, Y, ElasticNetParameters> for ElasticNet<TX, TY, X, Y>
{
fn new() -> Self {
Self {
coefficients: Option::None,
intercept: Option::None,
_phantom_ty: PhantomData,
_phantom_y: PhantomData,
}
}

fn fit(x: &X, y: &Y, parameters: ElasticNetParameters) -> Result<Self, Failed> {
ElasticNet::fit(x, y, parameters)
}
Expand Down
9 changes: 0 additions & 9 deletions src/linear/lasso.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,15 +116,6 @@ impl<TX: FloatNumber + RealNumber, TY: Number, X: Array2<TX>, Y: Array1<TY>> Par
impl<TX: FloatNumber + RealNumber, TY: Number, X: Array2<TX>, Y: Array1<TY>>
SupervisedEstimator<X, Y, LassoParameters> for Lasso<TX, TY, X, Y>
{
fn new() -> Self {
Self {
coefficients: Option::None,
intercept: Option::None,
_phantom_ty: PhantomData,
_phantom_y: PhantomData,
}
}

fn fit(x: &X, y: &Y, parameters: LassoParameters) -> Result<Self, Failed> {
Lasso::fit(x, y, parameters)
}
Expand Down
10 changes: 0 additions & 10 deletions src/linear/linear_regression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,16 +206,6 @@ impl<
Y: Array1<TY>,
> SupervisedEstimator<X, Y, LinearRegressionParameters> for LinearRegression<TX, TY, X, Y>
{
fn new() -> Self {
Self {
coefficients: Option::None,
intercept: Option::None,
solver: LinearRegressionParameters::default().solver,
_phantom_ty: PhantomData,
_phantom_y: PhantomData,
}
}

fn fit(x: &X, y: &Y, parameters: LinearRegressionParameters) -> Result<Self, Failed> {
LinearRegression::fit(x, y, parameters)
}
Expand Down
12 changes: 0 additions & 12 deletions src/linear/logistic_regression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,18 +390,6 @@ impl<TX: Number + FloatNumber + RealNumber, TY: Number + Ord, X: Array2<TX>, Y:
SupervisedEstimator<X, Y, LogisticRegressionParameters<TX>>
for LogisticRegression<TX, TY, X, Y>
{
fn new() -> Self {
Self {
coefficients: Option::None,
intercept: Option::None,
classes: Option::None,
num_attributes: 0,
num_classes: 0,
_phantom_tx: PhantomData,
_phantom_y: PhantomData,
}
}

fn fit(x: &X, y: &Y, parameters: LogisticRegressionParameters<TX>) -> Result<Self, Failed> {
LogisticRegression::fit(x, y, parameters)
}
Expand Down
10 changes: 0 additions & 10 deletions src/linear/ridge_regression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,16 +255,6 @@ impl<
Y: Array1<TY>,
> SupervisedEstimator<X, Y, RidgeRegressionParameters<TX>> for RidgeRegression<TX, TY, X, Y>
{
fn new() -> Self {
Self {
coefficients: Option::None,
intercept: Option::None,
solver: Option::None,
_phantom_ty: PhantomData,
_phantom_y: PhantomData,
}
}

fn fit(x: &X, y: &Y, parameters: RidgeRegressionParameters<TX>) -> Result<Self, Failed> {
RidgeRegression::fit(x, y, parameters)
}
Expand Down
21 changes: 6 additions & 15 deletions src/model_selection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@
//!
//! let cv = KFold::default().with_n_splits(3);
//!
//! let results = cross_validate(
//! LogisticRegression::new(), //estimator
//! // Need to pass generic type parameter to define the type of the estimator
//! let results = cross_validate::<_,_,_,_,_,LogisticRegression<_,_,_,_>,_,_>(
//! &x, &y, //data
//! Default::default(), //hyperparameters
//! &cv, //cross validation split
Expand Down Expand Up @@ -222,7 +222,6 @@ impl CrossValidationResult {
/// * `cv` - the cross-validation splitting strategy, should be an instance of [`BaseKFold`](./trait.BaseKFold.html)
/// * `score` - a metric to use for evaluation, see [metrics](../metrics/index.html)
pub fn cross_validate<TX, TY, X, Y, H, E, K, S>(
_estimator: E, // just an empty placeholder to allow passing `fit()`
x: &X,
y: &Y,
parameters: H,
Expand Down Expand Up @@ -271,7 +270,6 @@ where
/// * `parameters` - parameters of selected estimator. Use `Default::default()` for default parameters.
/// * `cv` - the cross-validation splitting strategy, should be an instance of [`BaseKFold`](./trait.BaseKFold.html)
pub fn cross_val_predict<TX, TY, X, Y, H, E, K>(
_estimator: E, // just an empty placeholder to allow passing `fit()`
x: &X,
y: &Y,
parameters: H,
Expand Down Expand Up @@ -360,9 +358,6 @@ mod tests {
impl<X: Array2<f32>, Y: Array1<u32>, P: NoParameters> SupervisedEstimator<X, Y, P>
for BiasedEstimator
{
fn new() -> Self {
Self {}
}
fn fit(_: &X, _: &Y, _: P) -> Result<BiasedEstimator, Failed> {
Ok(BiasedEstimator {})
}
Expand Down Expand Up @@ -404,8 +399,7 @@ mod tests {
..KFold::default()
};

let results = cross_validate(
BiasedEstimator {},
let results = cross_validate::<_, _, _, _, _, BiasedEstimator, _, _>(
&x,
&y,
BiasedParameters {},
Expand Down Expand Up @@ -452,8 +446,7 @@ mod tests {
..KFold::default()
};

let results = cross_validate(
KNNRegressor::new(),
let results = cross_validate::<_, _, _, _, _, KNNRegressor<_, _, _, _, _>, _, _>(
&x,
&y,
Default::default(),
Expand Down Expand Up @@ -500,8 +493,7 @@ mod tests {
..KFold::default()
};

let y_hat: Vec<f64> = cross_val_predict(
KNNRegressor::new(),
let y_hat: Vec<f64> = cross_val_predict::<_, _, _, _, _, KNNRegressor<_, _, _, _, _>, _>(
&x,
&y,
KNNRegressorParameters::default()
Expand Down Expand Up @@ -544,8 +536,7 @@ mod tests {

let cv = KFold::default().with_n_splits(3);

let results = cross_validate(
LogisticRegression::new(),
let results = cross_validate::<_, _, _, _, _, LogisticRegression<_, _, _, _>, _, _>(
&x,
&y,
Default::default(),
Expand Down
7 changes: 0 additions & 7 deletions src/naive_bayes/bernoulli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,13 +381,6 @@ impl<TX: Number + PartialOrd, TY: Number + Ord + Unsigned, X: Array2<TX>, Y: Arr
impl<TX: Number + PartialOrd, TY: Number + Ord + Unsigned, X: Array2<TX>, Y: Array1<TY>>
SupervisedEstimator<X, Y, BernoulliNBParameters<TX>> for BernoulliNB<TX, TY, X, Y>
{
fn new() -> Self {
Self {
inner: Option::None,
binarize: Option::None,
}
}

fn fit(x: &X, y: &Y, parameters: BernoulliNBParameters<TX>) -> Result<Self, Failed> {
BernoulliNB::fit(x, y, parameters)
}
Expand Down
6 changes: 0 additions & 6 deletions src/naive_bayes/categorical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,12 +347,6 @@ pub struct CategoricalNB<T: Number + Unsigned, X: Array2<T>, Y: Array1<T>> {
impl<T: Number + Unsigned, X: Array2<T>, Y: Array1<T>>
SupervisedEstimator<X, Y, CategoricalNBParameters> for CategoricalNB<T, X, Y>
{
fn new() -> Self {
Self {
inner: Option::None,
}
}

fn fit(x: &X, y: &Y, parameters: CategoricalNBParameters) -> Result<Self, Failed> {
CategoricalNB::fit(x, y, parameters)
}
Expand Down
6 changes: 0 additions & 6 deletions src/naive_bayes/gaussian.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,6 @@ impl<
Y: Array1<TY>,
> SupervisedEstimator<X, Y, GaussianNBParameters> for GaussianNB<TX, TY, X, Y>
{
fn new() -> Self {
Self {
inner: Option::None,
}
}

fn fit(x: &X, y: &Y, parameters: GaussianNBParameters) -> Result<Self, Failed> {
GaussianNB::fit(x, y, parameters)
}
Expand Down
6 changes: 0 additions & 6 deletions src/naive_bayes/multinomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,6 @@ impl<TX: Number + Unsigned, TY: Number + Ord + Unsigned, X: Array2<TX>, Y: Array
impl<TX: Number + Unsigned, TY: Number + Ord + Unsigned, X: Array2<TX>, Y: Array1<TY>>
SupervisedEstimator<X, Y, MultinomialNBParameters> for MultinomialNB<TX, TY, X, Y>
{
fn new() -> Self {
Self {
inner: Option::None,
}
}

fn fit(x: &X, y: &Y, parameters: MultinomialNBParameters) -> Result<Self, Failed> {
MultinomialNB::fit(x, y, parameters)
}
Expand Down
12 changes: 0 additions & 12 deletions src/neighbors/knn_classifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,18 +181,6 @@ impl<TX: Number, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>, D: Distance<Vec
impl<TX: Number, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>, D: Distance<Vec<TX>>>
SupervisedEstimator<X, Y, KNNClassifierParameters<TX, D>> for KNNClassifier<TX, TY, X, Y, D>
{
fn new() -> Self {
Self {
classes: Option::None,
y: Option::None,
knn_algorithm: Option::None,
weight: Option::None,
k: Option::None,
_phantom_tx: PhantomData,
_phantom_x: PhantomData,
_phantom_y: PhantomData,
}
}
fn fit(x: &X, y: &Y, parameters: KNNClassifierParameters<TX, D>) -> Result<Self, Failed> {
KNNClassifier::fit(x, y, parameters)
}
Expand Down
12 changes: 0 additions & 12 deletions src/neighbors/knn_regressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,18 +177,6 @@ impl<TX: Number, TY: Number, X: Array2<TX>, Y: Array1<TY>, D: Distance<Vec<TX>>>
impl<TX: Number, TY: Number, X: Array2<TX>, Y: Array1<TY>, D: Distance<Vec<TX>>>
SupervisedEstimator<X, Y, KNNRegressorParameters<TX, D>> for KNNRegressor<TX, TY, X, Y, D>
{
fn new() -> Self {
Self {
y: Option::None,
knn_algorithm: Option::None,
weight: Option::None,
k: Option::None,
_phantom_tx: PhantomData,
_phantom_ty: PhantomData,
_phantom_x: PhantomData,
}
}

fn fit(x: &X, y: &Y, parameters: KNNRegressorParameters<TX, D>) -> Result<Self, Failed> {
KNNRegressor::fit(x, y, parameters)
}
Expand Down
10 changes: 0 additions & 10 deletions src/svm/svc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,16 +208,6 @@ impl<TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>> De
impl<'a, TX: Number + RealNumber, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>>
SupervisedEstimatorBorrow<'a, X, Y, SVCParameters<TX, TY, X, Y>> for SVC<'a, TX, TY, X, Y>
{
fn new() -> Self {
Self {
classes: Option::None,
instances: Option::None,
parameters: Option::None,
w: Option::None,
b: Option::None,
phantomdata: PhantomData,
}
}
fn fit(
x: &'a X,
y: &'a Y,
Expand Down
9 changes: 0 additions & 9 deletions src/svm/svr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,6 @@ impl<T: Number + FloatNumber + PartialOrd> Default for SVRParameters<T> {
impl<'a, T: Number + FloatNumber + PartialOrd, X: Array2<T>, Y: Array1<T>>
SupervisedEstimatorBorrow<'a, X, Y, SVRParameters<T>> for SVR<'a, T, X, Y>
{
fn new() -> Self {
Self {
instances: Option::None,
parameters: Option::None,
w: Option::None,
b: T::zero(),
phantom: PhantomData,
}
}
fn fit(x: &'a X, y: &'a Y, parameters: &'a SVRParameters<T>) -> Result<Self, Failed> {
SVR::fit(x, y, parameters)
}
Expand Down
13 changes: 0 additions & 13 deletions src/tree/decision_tree_classifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,19 +507,6 @@ impl<TX: Number + PartialOrd, TY: Number + Ord, X: Array2<TX>, Y: Array1<TY>>
SupervisedEstimator<X, Y, DecisionTreeClassifierParameters>
for DecisionTreeClassifier<TX, TY, X, Y>
{
fn new() -> Self {
Self {
nodes: vec![],
parameters: Option::None,
num_classes: 0usize,
classes: vec![],
depth: 0u16,
_phantom_tx: PhantomData,
_phantom_x: PhantomData,
_phantom_y: PhantomData,
}
}

fn fit(x: &X, y: &Y, parameters: DecisionTreeClassifierParameters) -> Result<Self, Failed> {
DecisionTreeClassifier::fit(x, y, parameters)
}
Expand Down
12 changes: 0 additions & 12 deletions src/tree/decision_tree_regressor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,18 +387,6 @@ impl<TX: Number + PartialOrd, TY: Number, X: Array2<TX>, Y: Array1<TY>>
SupervisedEstimator<X, Y, DecisionTreeRegressorParameters>
for DecisionTreeRegressor<TX, TY, X, Y>
{
fn new() -> Self {
Self {
nodes: vec![],
parameters: Option::None,
depth: 0u16,
_phantom_tx: PhantomData,
_phantom_ty: PhantomData,
_phantom_x: PhantomData,
_phantom_y: PhantomData,
}
}

fn fit(x: &X, y: &Y, parameters: DecisionTreeRegressorParameters) -> Result<Self, Failed> {
DecisionTreeRegressor::fit(x, y, parameters)
}
Expand Down