This forum has been archived. All content is frozen. Please use KDE Discuss instead.

feature normalize MatrixXd X?

Tags: None
(comma "," separated)
bravegag
Registered Member
Posts
52
Karma
0

feature normalize MatrixXd X?

Wed Oct 09, 2013 7:58 pm
hello,

What would be the best way to do a feature normalize for an input MatrixXd X with Eigen? i.e. subtract the mean and divide by the variance column-wise.
The pseudo code would be along the lines of e.g.
Code: Select all
MatrixXd X(3,3);
X << 1, 4, 7,
     2, 5, 8,
     3, 6, 9;

// >>>> this is a Matlab-like approach to illustrate the objective but in Eigen there is no colwise().variance()
// and I can't see how to repmat the mean and variance to apply it also column-wise to the MatrixXd
// in a vectorized form.
X = (X - X.colwise().mean().repmat(X.rows(), 1)) ./ X.colwise().variance().repmat(X.rows(), 1);

// expected result
MatrixXd expected_X(3,3);
expected_X << -1, -1, -1,
               0,  0,  0,
               1,  1,  1;
ASSERT_NEAR(expected_X, X, 1e-10);     

TIA,
Best regards,
Giovanni
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
For repmat you can use the replicate function, but here it is simpler to use rowwise. For coefficient-wise operations, you can either move to the array world or use the few cwise* functions. For instance:
Code: Select all
RowVectorXd mean = X.colwise().mean();
RowVectorXd var = (X.rowwise() - mean).array().square().colwise().mean();
X = (X.rowwise() - mean).array().rowwise() / var.array();
bravegag
Registered Member
Posts
52
Karma
0

Re: feature normalize MatrixXd X?

Thu Oct 10, 2013 8:24 am
hi ggael,

Thank you for the good and quick answer :) However, the results do not match Matlab, specifically computing the sample variance. In the example I proposed the variance should be [1 1 1] but with your proposed implementation results in [0.666667 0.666667 0.666667]. The issue is the unbiased sample variance formula. Using the unbiased sample variance then would be:
Code: Select all
   
Eigen::RowVectorXd mean = A.colwise().mean();
Eigen::RowVectorXd std = ((A.rowwise() - mean).array().square().colwise().sum() / (A.rows() - 1)).sqrt();
MatrixXd result = (A.rowwise() - mean).array().rowwise() / std.array();

UPDATE: the feature normalization divides by the standard deviation and not by the variance. This has been corrected above.
Best regards,
Giovanni


Bookmarks



Who is online

Registered users: Bing [Bot], Google [Bot], Yahoo [Bot]