Skip to content

Implementation of Standard scaler#143

Merged
Mec-iS merged 3 commits into
smartcorelib:developmentfrom
titoeb:standard-scaler
Aug 26, 2022
Merged

Implementation of Standard scaler#143
Mec-iS merged 3 commits into
smartcorelib:developmentfrom
titoeb:standard-scaler

Conversation

@titoeb

@titoeb titoeb commented Aug 24, 2022

Copy link
Copy Markdown
Contributor

In this branch I added an implementation for a StandardScaler as described in issue #54.

@titoeb
titoeb force-pushed the standard-scaler branch 2 times, most recently from c4153c4 to f866035 Compare August 24, 2022 05:58
@titoeb titoeb changed the title Standard scaler Implementation of Standard scaler Aug 24, 2022
@titoeb titoeb mentioned this pull request Aug 24, 2022
@Mec-iS
Mec-iS marked this pull request as ready for review August 24, 2022 09:33
@Mec-iS
Mec-iS requested review from Mec-iS and morenol August 24, 2022 09:39

@Mec-iS Mec-iS left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much for your contribution!

These are the first suggetions that came to my mind.

Comment thread src/preprocessing/numerical.rs Outdated
Comment thread src/preprocessing/numerical.rs
Comment thread src/preprocessing/numerical.rs Outdated
}

/// Extract a single column from a matrix and return it as a matrix.
fn take_column_from_matrix<T, M>(matrix: &M, column_index: usize) -> M

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two function look really useful, maybe you should consider adding them to linalg::BaseMatrix implementation as they are more general than the scaler implementation.
It would be nice to have something like DenseMatrix::take_column(...) (I thought we already have something like it?)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is already a take implementation for matrices.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes exactly, I also use the Matrix::take interface here, but I want to specialize it for taking columns (then you need to paramterize it via axis, e.g. Matrix::take(&[column_index], 1)). This is helpful because then I don't need to repeat this in my code and can test it in a central place (I always like to mess up the axis indices 😆 ). So if it is ok, I would still like to keep build_matrix_from_columns (or put it in the Matrix-implementation).

Apart from this I would also be happy to put any of the two methods (build_matrix_from_columns | take_column) into the Matrix imlementation. Should I do it? For which of the two methods?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If they have generic functionalities and they can be reused, not strictly tied to the implementation of the module, they can be moved to modules with a more generic functionalities so that other modules can make use of them. I think you can move take_columns_from_matrix into linalg::BaseMatrix implementation so it can be used like BaseMatrix::take_columns_from_matrix; same for build_matrix_from_columns.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed below, I think take_column_from_matrix , or rather Matrix:take_column (what you proposed earlier) I would put it into a more central place as it can be used in other places as well.


/// From a collection of matrices, that contain columns, construct
/// a matrix by stacking the columns horizontally.
fn build_matrix_from_columns<T, M>(columns: Vec<M>) -> Option<M>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this is a Vec<M> instead of a Vec<Vec<T>>>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build_matrix_from_columns function was build by me as a helper / utility function in this module. During fit of the StandardScaler I first take individual columns from the matrix that contains the raw data then apply the necessary scaling. In short I need Vec<M> instead of Vec<Vec<T>> because take_column_from_matrix returns a Matrix. Also this is helpful because I can use the neat methods sub_scalar as well as div_scaler to apply the scaling.

@Mec-iS Mec-iS Aug 25, 2022

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok but for it to be general it is better to use Vec<Vec<T>> as you won't need build da matrix from a matrix but a matrix from a 2-D vector. So if you plan to make build_matrix_from_columns generic it would be better for it to accept Vecs. If this is not possible, then probably the method is not fully reusable to other modules.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok that make sense. Then I would prefer not to put build_matrix_from_columns into Matrix because I would need to refactor it and it would not be optimal for this module anymore.

@Mec-iS

Mec-iS commented Aug 25, 2022

Copy link
Copy Markdown
Collaborator

There is an error with clippy, try to run cargo clippy --all-features -- -Drust-2018-idioms -Dwarnings

titoeb added 2 commits August 26, 2022 06:03
I created the method `Matrix::take_column` that uses the `Matrix::take`-interface to extract a single column from a matrix. I need that feature in the implementation of  `StandardScaler`.
@titoeb

titoeb commented Aug 26, 2022

Copy link
Copy Markdown
Contributor Author

There is an error with clippy, try to run cargo clippy --all-features -- -Drust-2018-idioms -Dwarnings

Should be fixed now!

@titoeb
titoeb requested review from Mec-iS and removed request for morenol August 26, 2022 06:07
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

Merging #143 (392191d) into development (a1c56a8) will increase coverage by 0.28%.
The diff coverage is 89.47%.

@@               Coverage Diff               @@
##           development     #143      +/-   ##
===============================================
+ Coverage        83.65%   83.94%   +0.28%     
===============================================
  Files               80       81       +1     
  Lines             8591     8724     +133     
===============================================
+ Hits              7187     7323     +136     
+ Misses            1404     1401       -3     
Impacted Files Coverage Δ
src/preprocessing/numerical.rs 88.88% <88.88%> (ø)
src/linalg/mod.rs 58.57% <100.00%> (+5.49%) ⬆️
src/algorithm/neighbour/fastpair.rs 95.67% <0.00%> (ø)
src/linalg/naive/dense_matrix.rs 80.11% <0.00%> (+0.89%) ⬆️
src/math/num.rs 84.09% <0.00%> (+2.27%) ⬆️
src/optimization/line_search.rs 90.00% <0.00%> (+8.00%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@Mec-iS

Mec-iS commented Aug 26, 2022

Copy link
Copy Markdown
Collaborator

Nice one @titoeb, hope we can collaborate in another PR soon.
If you are interested in how to serve smartcore, take a look to my repo https://github.com/Mec-iS/rust-grpc-smartcore
I am also looking for help to implement agglomerative clustering, see #11

@Mec-iS
Mec-iS merged commit d305406 into smartcorelib:development Aug 26, 2022
morenol pushed a commit that referenced this pull request Nov 8, 2022
* docs: Fix typo in doc for categorical transformer.
* feat: Add option to take a column from Matrix.
I created the method `Matrix::take_column` that uses the `Matrix::take`-interface to extract a single column from a matrix. I need that feature in the implementation of  `StandardScaler`.
* feat: Add `StandardScaler`.
Authored-by: titoeb <timtoebrock@googlemail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants