Added the code for standardizing the dataset.
This commit is contained in:
@@ -86,29 +86,28 @@ class DatasetScaler {
|
||||
static void ScaleDataByMinMax(Matrix &qset, Matrix &rset,
|
||||
bool queries_equal_references) {
|
||||
|
||||
int num_dims = rset.n_rows();
|
||||
DHrectBound<2> qset_bound;
|
||||
DHrectBound<2> rset_bound;
|
||||
qset_bound.Init(qset.n_rows());
|
||||
rset_bound.Init(qset.n_rows());
|
||||
index_t num_dims = qset.n_rows();
|
||||
DHrectBound<2> total_bound;
|
||||
total_bound.Init(qset.n_rows());
|
||||
|
||||
// go through each query/reference point to find out the bounds
|
||||
for(index_t r = 0; r < rset.n_cols(); r++) {
|
||||
Vector ref_vector;
|
||||
rset.MakeColumnVector(r, &ref_vector);
|
||||
rset_bound |= ref_vector;
|
||||
total_bound |= ref_vector;
|
||||
}
|
||||
for(index_t q = 0; q < qset.n_cols(); q++) {
|
||||
Vector query_vector;
|
||||
qset.MakeColumnVector(q, &query_vector);
|
||||
qset_bound |= query_vector;
|
||||
if(!queries_equal_references) {
|
||||
for(index_t q = 0; q < qset.n_cols(); q++) {
|
||||
Vector query_vector;
|
||||
qset.MakeColumnVector(q, &query_vector);
|
||||
total_bound |= query_vector;
|
||||
}
|
||||
}
|
||||
|
||||
for(index_t i = 0; i < num_dims; i++) {
|
||||
DRange qset_range = qset_bound.get(i);
|
||||
DRange rset_range = rset_bound.get(i);
|
||||
double min_coord = min(qset_range.lo, rset_range.lo);
|
||||
double max_coord = max(qset_range.hi, rset_range.hi);
|
||||
DRange total_range = total_bound.get(i);
|
||||
double min_coord = total_range.lo;
|
||||
double max_coord = total_range.hi;
|
||||
double width = max_coord - min_coord;
|
||||
|
||||
printf("Dimension %d range: [%g, %g]\n", i, min_coord, max_coord);
|
||||
@@ -135,6 +134,86 @@ class DatasetScaler {
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Standardize the given query and the reference datasets in
|
||||
* each dimension to have zero mean and at most unit
|
||||
* variance.
|
||||
*
|
||||
* Assumes that the query and the reference together contain
|
||||
* more than one instance.
|
||||
*
|
||||
* @param qset The column-oriented query set.
|
||||
* @param rset The column-oriented reference set.
|
||||
* @param queries_equal_references The boolean flag that tells whether
|
||||
* the queries equal the references.
|
||||
*/
|
||||
static void StandardizeData(Matrix &qset, Matrix &rset,
|
||||
bool queries_equal_references) {
|
||||
|
||||
Vector mean_vector, standard_deviation_vector;
|
||||
|
||||
mean_vector.Init(qset.n_rows());
|
||||
mean_vector.SetZero();
|
||||
standard_deviation_vector.Init(qset.n_rows());
|
||||
standard_deviation_vector.SetZero();
|
||||
|
||||
// Go through each query/reference point to find out the mean
|
||||
// vectors.
|
||||
for(index_t r = 0; r < rset.n_cols(); r++) {
|
||||
la::AddTo(rset.n_rows(), rset.GetColumnPtr(r), mean_vector.ptr());
|
||||
}
|
||||
if(!queries_equal_references) {
|
||||
for(index_t q = 0; q < qset.n_cols(); q++) {
|
||||
la::AddTo(qset.n_rows(), qset.GetColumnPtr(q), mean_vector.ptr());
|
||||
}
|
||||
la::Scale(qset.n_rows(), 1.0 / ((double) qset.n_cols() + rset.n_cols()),
|
||||
mean_vector.ptr());
|
||||
}
|
||||
else {
|
||||
la::Scale(qset.n_rows(), 1.0 / ((double) qset.n_cols()),
|
||||
mean_vector.ptr());
|
||||
}
|
||||
|
||||
// Now find out the standard deviation along each dimension.
|
||||
for(index_t r = 0; r < rset.n_cols(); r++) {
|
||||
for(index_t i = 0; i < rset.n_rows(); i++) {
|
||||
standard_deviation_vector[i] +=
|
||||
math::Sqr(rset.get(i, r) - mean_vector[i]);
|
||||
}
|
||||
}
|
||||
if(!queries_equal_references) {
|
||||
for(index_t q = 0; q < qset.n_cols(); q++) {
|
||||
for(index_t i = 0; i < qset.n_rows(); i++) {
|
||||
standard_deviation_vector[i] +=
|
||||
math::Sqr(qset.get(i, q) - mean_vector[i]);
|
||||
}
|
||||
}
|
||||
la::Scale(qset.n_rows(),
|
||||
1.0 / ((double) qset.n_cols() + rset.n_cols() - 1),
|
||||
standard_deviation_vector.ptr());
|
||||
}
|
||||
else {
|
||||
la::Scale(rset.n_rows(), 1.0 / ((double) rset.n_cols()),
|
||||
standard_deviation_vector.ptr());
|
||||
}
|
||||
|
||||
// Now scale the datasets using the computed mean and the standard
|
||||
// deviation.
|
||||
for(index_t r = 0; r < rset.n_cols(); r++) {
|
||||
for(index_t d = 0; d < rset.n_rows(); d++) {
|
||||
rset.set(d, r, (rset.get(d, r) - mean_vector[d]) /
|
||||
standard_deviation_vector[d]);
|
||||
}
|
||||
}
|
||||
if(!queries_equal_references) {
|
||||
for(index_t q = 0; q < qset.n_cols(); q++) {
|
||||
for(index_t d = 0; d < qset.n_rows(); d++) {
|
||||
qset.set(d, q, (qset.get(d, q) - mean_vector[d]) /
|
||||
standard_deviation_vector[d]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -47,8 +47,11 @@
|
||||
* has to be positive.
|
||||
*
|
||||
* 5. kde/scaling (optional): whether to prescale the dataset
|
||||
* - range: scales both the query and the reference sets to be within the
|
||||
* unit hypercube [0, 1]^D where D is the dimensionality.
|
||||
*
|
||||
* - range: scales both the query and the reference sets to be within
|
||||
* the unit hypercube [0, 1]^D where D is the dimensionality.
|
||||
* - standardize: scales both the query and the reference set to have
|
||||
* zero mean and unit variance.
|
||||
* - none: default value; no scaling
|
||||
*
|
||||
* 6. kde/multiplicative_expansion (optional): If this flag is
|
||||
@@ -117,6 +120,11 @@ int main(int argc, char *argv[]) {
|
||||
DatasetScaler::ScaleDataByMinMax(queries, references,
|
||||
queries_equal_references);
|
||||
}
|
||||
else if(!strcmp(fx_param_str(kde_module, "scaling", "none"),
|
||||
"standardize")) {
|
||||
DatasetScaler::StandardizeData(queries, references,
|
||||
queries_equal_references);
|
||||
}
|
||||
|
||||
if(!strcmp(fx_param_str(kde_module, "kernel", "gaussian"), "gaussian")) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user